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 |