본문 바로가기

STM32F469I-DISCO

UART RX : Polling, Interrupt 비교

A : Polling 방식.

     1) USART3 활성화, LED 연결 프로젝트 생성.

     2) 아래의 내용 추가

uint8_t rxData[100];

 

HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, LED2_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, LED3_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOK, LED4_Pin, GPIO_PIN_SET);

while (1)

{

     /* USER CODE END WHILE */

     if (HAL_UART_Receive(&huart3, rxData, 1, 1000) == HAL_OK)

     {

          HAL_UART_Transmit(&huart3, rxData, 1, HAL_MAX_DELAY); // putty console echo

          if (rxData[0] == '1') {

               HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_RESET); // LED ON

          }

          else if (rxData[0] == '0') {

               HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_SET); // LED OFF

          }

     }

     /* USER CODE BEGIN 3 */

}

 

콘솔 입력으로 인한 LED On/Off, 키보드 입력의 echo 확인

B-1 : Interrupt 방식.

     1) 기존의 프로젝트 .ioc에서 NVIC의 global interrupt을 enable한다.

 

                 참고 : 사용자 지정 콜백 함수명을 등록하는 방식은 HAL에서 지원하지 않으며, USART의 콜백함수는 HAL_UART_RxCpltCallback()으로 지정되어 있음.

     

     2) 아래의 내용 추가.

HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, LED2_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, LED3_Pin, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOK, LED4_Pin, GPIO_PIN_SET);

 

HAL_UART_Receive_IT(&huart3, rxData, 1);

/* USER CODE END 2 */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

while (1)

{

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

     if (huart->Instance == USART3)

     {

     // LED 제어

          if (rxData[0] == '1')

               HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_RESET); // ON

          else if (rxData[0] == '0')

                HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_SET); // OFF

 

     // 다시 수신 준비 (지속적 수신을 위해 반드시 필요)

          HAL_UART_Receive_IT(&huart3, rxData, 1);

     }

}

** 참고 :  HAL_UART_Receive_IT (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size) 에서 size를 2 입력하고 상태를 관찰하면, size의 의미를 명확하게 확인 할 수 있으며, 가변 입력되는 문자에 대한 검토가 필요하다.

B-2 : 가변 문자열 입력을 인식하는 Interrupt 방식.

프로그램 조건 : 

1) putty에서 입력하는 문자가 실시간으로 출력됨.

2) putty에서 줄바꿈이 발생하도록 설정.

3). LED1의 상태를 입력하는데 "LED1=on" 과 "LED1=off"로 사용자가 입력한다.

 

Putty 설정에서:
Terminal > Local Echo: Force Off 또는 Auto
Terminal > Line discipline options:
Implicit CR in every LF: 체크 (기본값)
Implicit LF in every CR: 체크 (필수!) ← \r이 들어올 때 줄바꿈 동작

 

코드 수정 사항.

#define CMD_BUFFER_SIZE 64

uint8_t rxChar;

char cmdBuffer[CMD_BUFFER_SIZE];

uint8_t cmdIndex = 0;

 

HAL_UART_Receive_IT(&huart3, &rxChar, 1);

// 콜백 함수 내용.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

     if (huart->Instance == USART3)

     {

            if (rxChar == '\r') // Enter 키 입력 시

            {

                // 개행 문자 출력 (\r\n)

                  const char newline[] = "\n";

                HAL_UART_Transmit(&huart3, (uint8_t*)newline, strlen(newline), HAL_MAX_DELAY);

                // 명령어 문자열 종료 처리

                cmdBuffer[cmdIndex] = '\0'; // 문자열 끝

                // 명령어 처리

                if (strcmp(cmdBuffer, "LED1=ON") == 0)

                {

                        HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_RESET); // ON

                        HAL_UART_Transmit(&huart3, (uint8_t*)"OK\r\n", 4, HAL_MAX_DELAY);

                  }

                else if (strcmp(cmdBuffer, "LED1=OFF") == 0)

                {

                      HAL_GPIO_WritePin(GPIOG, LED1_Pin, GPIO_PIN_SET); // OFF

                      HAL_UART_Transmit(&huart3, (uint8_t*)"OK\r\n", 4, HAL_MAX_DELAY);

                  }

                  else

                {

                        HAL_UART_Transmit(&huart3, (uint8_t*)"exceptional case\r\n", 18, HAL_MAX_DELAY);

                  }

                // 버퍼 초기화

                cmdIndex = 0;

                memset(cmdBuffer, 0, sizeof(cmdBuffer));

          }

           else

            {

                  // 에코 출력

                  HAL_UART_Transmit(&huart3, &rxChar, 1, HAL_MAX_DELAY);

 

                  // 명령어 버퍼에 저장

                  if (cmdIndex < CMD_BUFFER_SIZE - 1)

                        cmdBuffer[cmdIndex++] = rxChar;

                  else

                        cmdIndex = 0; // 버퍼 오버플로 방지 (선택 처리)

            }

            // 다음 수신 준비

            HAL_UART_Receive_IT(&huart3, &rxChar, 1);

      }

}

 

 

'STM32F469I-DISCO' 카테고리의 다른 글

STM32F469I DISCO - FMC - 128Mbit SDRAM  (1) 2025.06.27
UART RX : DMA 방식에서 Normal / Circular 모드 비교  (0) 2025.06.24
STM32에서 콘솔 텍스트 출력.  (1) 2025.06.21
Blink LED  (1) 2025.06.20
STM32F469 Discovery kit 관련.  (0) 2025.06.20