STM32 UART 통신

HAL 라이브러리를 이용하여 UART 통신 해보기

Recent Post


WOL Magic 패킷을 만들어 원격으로 컴퓨터 키기

WOL 패킷 구조 + C언어 코드

Recommended Post


1석 트랜지스터 증폭기

최대한 적은 부품으로 증폭회로 만들기


NE555 발진회로 구성

라디오 만들기 - 2 (발진회로 만들기)

CubeMX를 이용하여 STM32L476RG MCU 기준으로 UART 통신을 해보려고 합니다.

UART 통신은 SoC 칩에서 가장 쉽고 간단하게 주변 장치와 통신할 수 있는 비동기 통신 방식이여서 여러 모듈, 장비와 연동하는데 많이 사용됩니다.

이 포스팅에서는 USB to UART 모듈을 사용하여 컴퓨터랑 연동 해보려고 합니다.

CubeMX 세팅

CubeMX View

CubeMX 에서 설정한 핀맵

STM 기반의 SoC 에는 다양한 통신 포트를 설정 할 수 있습니다.

그 중 UART4 로 통신 할 수 있도록 설정해 줍니다.

CubeMX UART config

UART4을 Asynchronous 모드로 설정하고 band rate를 9600으로 설정 해주었습니다.

CubeMX UART 글로벌 인터럽트

다음 NVIC 설정에서 글로벌 인터럽트를 활성화 해줍니다.

CubeMX UART pin

GPIO 핀은 건들이지 않고 기본값으로 설정합니다.

코드

다음 코드는 메인함수에서 UART 수신을 확인하여 특정 값을 입력받았을때 LED를 켜고 끄는 간단한 예제입니다.

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_UART4_Init(void);

unsigned char RxBuffer[1]; // Rx Buffer

int main(void)
{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();
  MX_UART4_Init();
	
  while (1)
  {
        HAL_UART_Receive(&huart4, RxBuffer, 1, 10); // data read
        
        if(RxBuffer[0] == 'A'){
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
        }
        else if(RxBuffer[0] == 'B'){
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);	
        }
  }
}

테스트 회로

실제 회로

회로도

회로 구성은 단순히 LED 점멸회로와 UART 모듈과 연결만 해놓았습니다.

첨부한 회로도는 간단하게 어떤 구조로 연결했는지만 참고해주세요 ㅎㅎ

팁) 제대로 통신이 되지않으면 UART 선을 제대로 연결 했는지 확인 해보세요. 은근 실수 많이하는 부분입니다.

UART 수신 인터럽트 활용

위 코드를 사용하여 실제보드에 올리고 main 함수에서 다른 작업을 하고 있을 때 순간적으로 데이터를 놓치는 상황이 발생할 수 있습니다.

이러한 경우를 대비하기 위해 UART 통신으로 데이터가 들어오면 인터럽트가 실행되어 데이터를 읽고 동작 할 수 있도록 HAL 라이브러리에서 지원합니다.

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_UART4_Init(void);

unsigned char RxBuffer[1];

int main(void)
{
    HAL_Init();

    SystemClock_Config();

    MX_GPIO_Init();
    MX_UART4_Init();
	
    HAL_UART_Receive_IT(&huart4, RxBuffer, 1);

    while (1)
    {
        // 아무것도 안하는 무한루프
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	 if(huart -> Instance == huart4.Instance)
	 {
        if(RxBuffer[0] == 'A'){
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
        }
        else if(RxBuffer[0] == 'B'){
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);	
        }
    
        HAL_UART_Receive_IT(&huart4, RxBuffer, 1);
	 }
}

주요 함수 정리

UART 전송 함수

HAL_StatusTypeDef  HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

UART_HandleTypeDef *huart : 사용할 uart 핸들러

uint8_t *pData : 전송할 데이터

uint16_t Size : 전송할 데이터 수

uint32_t Timeout : TimeOut 설정

예제 :

HAL_UART_Transmit(&huart1, Tx_Buffer, 1, 2);

UART 수신 함수

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

UART_HandleTypeDef *huart : 사용할 uart 핸들러

uint8_t *pData : 입력 받은 데이터를 저장할 버퍼

uint16_t Size : 수신 버퍼에서 읽을 데이터 수

uint32_t Timeout : TimeOut 설정

예제 :

HAL_UART_Receive(&huart1,aRxBuffer,1,20);