본문 바로가기

MCU 제어/STM32Cube Mx

[STM32]UART 통신 입출력 실습

무언갈 배울 때 가장 중요한건 왜 배우는지 목적이 무엇인지 아는 것이라고 생각한다. 나는 디버깅할 때 pc로 값을 출력하도록하거나 센서의 값을 읽기 위해 uart 통신을 사용할 것이다.

 

 

uart를 사용하기 위해 usart1를 비동기 모드로 설정하였다. Basic Parameter를 보면 115200 Baud rate, 8bit, None parity, 1 Stop Bit로 설정하였다. 이전 포스팅을 통해 이 값들이 무엇을 이미하는지 알 수 있을 것이다.

 

Pin out view를 통해 tx, rx핀이 어느 핀으로 설정되있는지 알 수 있다. 자신이 가진 PCB와 사용하는 핀이 다르다면 옮길 수 있다. 나는 PCB회로를 확인한 결과 제대로 설정되있어서 옮기지 않았다.

project manager에서 프로젝트 이름과 경로를 설정할 수 있다. 경로에는 절대 한글로된 폴더가 없어야 한다. Toolchain은 자신이 사용하는 컴파일러에 맞게 설정해준다. 난 IAR 7을 사용하므로 EWARM V7을 선택하였다.

Code Generator에서 Generate peripheral ~~을 체크 해주는 것이 좋다. Stm32Cube Mx 프로그램은 내가 마우스로 까딱까딱 설정한 것들을 코드로 만들어주는 아주 편리한 기능을 제공하는데 이때 코드를 하나의 파일로 만들지 아니면 기능에 따라 .c/.h등 여러 파일로 나누어줄지 물어보는 것이다. 여러 파일로 나누어주는게 훨씬 편하다. 여기까지 했으면 code generate를 하면 된다.

 

UART로 Hello World! 출력하기

Application->user 안에 코드 파일들이 있다. 여기서 main.c에 uart를 통해 pc에 Hello world!를 보내는 코드를 작성해보자.  HAL드라이버를 사용하면 다른 mcu여도 레지스터를 하나하나 확인하여 건드리지 않고 같은 함수를 사용하여 제어할 수 있다. 하지만 HAL드라이버는 모든 mcu가 사용할 수 있도록 레지스터 값들로 변환하는 여러가지 작업들과 다른 mcu의 값들도 가지고?있기 때문에 상대적으로 무겁고 컴파일 시간이 걸린다.대충 Hal_Uart를 치고 ctrl+space를 누르면 자동완성 기능을 제공한다(다른 컴파일러도 되는지는 모르겠다).

딱봐도 HAL_UART_Transmit을 사용하면 될 것 같다. HAL_UART_Transmit(까지 치면 들어가는 인자값이 무엇인지 친절히 알려준다. HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); 이렇게 나온다.

uint8_t str[] = "Hello World!\n\r"; 
while(1){
    HAL_UART_Transmit(&huart1, (uint8_t*)str, 16, 1000); //uart번호, 출력할 문자열, 문자 개수, timeout
    HAL_Delay(1000); //1초 기다림
}

 

항상 코드는 주석 begin과 end사이에 작성해야한다. 안그러면 다시 code generator할 때 다 날아가버린다. 보드에 다운로드한 후 확인은 tera term, putty등 시리얼 통신 프로그램을 사용하면 된다. 그전에 보드와 PC를 usb to uart를 통해 연결해준다.

usb to uart adapter와 결과 모습

 UART로 입력받기 + 입력받은 문자 출력하기

uint8_t str[] = "Hello World!\n\r";
uint8_t received = '\0';
HAL_StatusTypeDef rcvStat;
while (1) {
    rcvStat = HAL_UART_Receive(&huart1, &received, 1, 10);
    if(rcvStat == HAL_OK)
    {
        HAL_UART_Transmit(&huart1, &received, 1, 1000); //읽어드린 값 터미널로 출력
    }
}

형식 - HAL_UART_Receive(uart번호, 데이터를 저장할 곳, 데이터 개수, 읽어드리는 시간)

HAL_UART_Receive를 우클릭에서 Go to definition을 해보면 UART값이 성공적으로 들어올 때 마다 HAL_OK를 반환한다는 것을 알 수 있다. 이것을 이용해 UART값이 들어올 때만 들어온 데이터를 UART로 전송하게 하였다.

실행하면 키보드로 치는 값이 Tera Term에 그대로 출력되는 모습을 볼 수 있다.

결과 화면

 

 

 

꿀팁

위의 경로로 들어가면 여러가지 예시 코드들을 볼 수 있다. 그중에서 UART_Printf라는 폴더를 열면 아래 코드가 나오는데 이 코드를 복사해서 main에 써주면 printf가 출력하는 곳이 원래는 콘솔창이지만 uart로 바꿔주는 역할은 한다. 긴 코드를 치지않고 printf만 치면 되므로 매우 편리하다. 몇번 uart를 사용하는지 &UartHandle을 지우고 써줘야한다. 이외에도 여러 예시 코드들이 있으므로 참고하면 좋을 것 같다.

 

#ifdef __GNUC__
/* With GCC, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

 

PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART3 and Loop until the end of transmission */
  HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);

  return ch;
}

 

 

오늘은 처음 올리는거라 여러가지 다른 설명도 많이 했는데 다음에는 주제와 관련된 내용만 올릴 것이다.

모르거나 헷갈리는 부분 댓글 남겨주세요. 아는 한에서 알려드리겠습니다.

'MCU 제어 > STM32Cube Mx' 카테고리의 다른 글

[STM32]PWM을 이용하여 BLDC 모터 구동하기  (0) 2020.03.21
[STM32] Basic Timer  (1) 2020.03.02
[STM32]UART 인터럽트 송수신 실습  (3) 2020.02.29
Cube MX란?  (0) 2020.02.21
[STM32]ST-Link 사용법 및 IAR 디버깅 방법  (0) 2020.02.02