STM32F746G-DISCO 보드에서 USART(Universal synchronous asynchronous receiver transmitter)를 간단히 테스트해 보았습니다.
우선 USART 관련 레지스터를 데이터 시트에서 찾아보았습니다.
USART1/2/3/6 (총 4개로 동기/비동기로 사용됨), UART4/5/7/8 (총 4개로 비동기로만 사용됨)
총 8개가 있으며 0x40004400 ~ 0x400117 FF까지 할당되어져 있습니다.
STM32F746NG에서 사용되는 USART관련 레지스터 맵은 아래와 같습니다.
각 레지스터를 간단히 살펴보면 아래와 같으며 자세한 내용은 en.DM00124865.pdf를 참고하시면 됩니다.
USART_CR1/2/3
- USART control 레지스터로 USART 관련 인터럽트, 송/수신 활/비활성 등 제어 관련 설정을 할 수 있습니다.
USART_BRR
- Baudrate 관련 설정을 할 수 있습니다.
USART_GTPR
- Guard time and prescaler 레지스터로 irDA, Smartcard 모드 설정 시 사용됩니다.
USART_RTOR
- Receiver timeout 레지스터로 응답 시간 관련 timout 값을 설정할 수 있습니다.
USART_RQR
- Request 관련 레지스터로 송/수신 데이터 flush, Mute, Send break, Auto baud rate요청 등을 할 수 있습니다.
USART_ISQ
- Interrupt and status 레지스터로 값을 읽어 들임으로써 USART상태를 확인할 수 있습니다.
USART_ICR
- Interrupt flag clear 레지스터로 송/수신 완료나 에러 발생 유/무를 확인 할 수 있습니다.
USART_RDR
- Receive data 레지스터로 데이터 수신에 사용됩니다.
USART_TDR
- Transmit data 레지스터로 데이터 송신에 사용됩니다.
STM32F746G-DISCO 보드에서 USART를 회로도에서 살펴보았습니다.
현재 USART로 통신할 수 있는 VCP_TX/RX가 각 각 PA9와 PB7에 연결되어져 있습니다.
STM32CubeIDE에서 새 프로젝트인 USART 프로젝트를 생성합니다.
PA9와 PB7을 검색하여 USART1_TX, USART1_RX로 포트 세팅을 변경해 줍니다.
왼쪽 장치 리스트의 Categories 탭 -> Connectivity -> USART1을 선택합니다.
모드 탭에서 Asynchronous로 설정합니다.
Parameter 탭에서 115200bps/8bit/None/1로 설정합니다.
NVIC 탭에서 USART1 global interrupt의 Enable을 체크합니다.
아래 코드를 Private user code에 추가합니다.
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int count=0;
#define RBSIZE 20
uint8_t rxBuf[RBSIZE];
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART1){
printf("Received Data : %s\r\n", rxBuf);
HAL_UART_Receive_IT(&huart1, rxBuf, RBSIZE);
}
}
int __io_putchar(int ch) {
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
main 함수의 while 문에 간단히 메세지를 출력하는 printf 문을 넣었습니다.
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, rxBuf, RBSIZE);
printf("USART test on STM32F746G-DISCO\r\n");
HAL_Delay(1000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("I\'m alive (%d)\r\n", count++);
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
빌드 후 Run 버튼을 클릭하여 STM32F746G-DISCO 보드에 다운로드를 합니다.
Serial Terminal 창에서 ST-Link에서 생성된 COM 포트를 선택하여 연결시키면 1초 간격으로 I'm alive 메시지가 출력됩니다.
STM32CubeIDE에서 시리얼 창 설치하는 방법은 아래 게시글을 확인해 주시기 바랍니다.
STM32F746G-DISCO 보드에서 USART를 통해 출력되는 메시지를 PC에서 확인해 보았습니다.
다음은 반대로 PC에서 문자열을 작성 후 Enter 키 입력으로 문자열이 STM32F746G-DISCO 보드로 전송되고 STM 보드에서는 이렇게 수신된 내용을 PC로 재전송되도록 테스트해 보았습니다.
UART관련 HAL 라이브러리를 살펴보니 user level에서 수신할 버퍼와 사이즈를 지정하면 HAL단에서 이 버퍼가 다 채워져야 callback 함수를 호출하여 user level에서 확인 가능한 구조로 되어 있습니다.
가급적이면 HAL단을 수정하지 않고 사용하는게 좋지만 간단히 테스트를 위해 불가피하게 HAL단을 수정하여 Enter 키 처리를 하였습니다.
/* stm32f7xx_hal_uart.c 의 UART_RxISR_8BIT함수를 수정하였습니다. */
static void UART_RxISR_8BIT(UART_HandleTypeDef *huart)
{
uint16_t uhMask = huart->Mask;
uint16_t uhdata;
uint8_t user_cmd = 0;
/* Check that a Rx process is ongoing */
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
{
uhdata = (uint16_t) READ_REG(huart->Instance->RDR);
if(uhdata=='\r' || uhdata=='\n'){
user_cmd = 1;
*huart->pRxBuffPtr = '\0';
}else{
*huart->pRxBuffPtr = (uint8_t)(uhdata & (uint8_t)uhMask);
huart->pRxBuffPtr++;
huart->RxXferCount--;
}
if (user_cmd == 1 || huart->RxXferCount == 0U)
{
/****************** 이하생략 ******************/
수신된 문자가 CR/LF인 경우 강제로 callback을 호출하는 구조로 변경하였습니다.
빌드 후 실행 보면 아래와 같이 PC에서 입력된 문장을 STM32F746G-DISCO보드가 수신하여 잘 되돌려 주고 있습니다.
이상 STM32F746G-DISCO 보드에서 USART를 사용한 입/출력 테스트를 해 보았습니다.
'Hardware > STM32' 카테고리의 다른 글
[STM32F746G-DISCO] I2C 사용하기 (feat. OLED) (0) | 2024.07.06 |
---|---|
[STM32F746G-DISCO] I2C 사용하기 (feat. 터치스크린) (0) | 2024.07.05 |
STM32CubeIDE에서 시리얼 터미널 설치하기 (0) | 2024.07.05 |
[STM32F746G-DISCO] 하드웨어 살펴보기 (0) | 2024.07.03 |
[STM32F746G-DISCO] GPIO 사용하기 (0) | 2024.07.03 |
댓글