이번 과정은 UART 통신을 이용해 STM32 보드에 명령을 보내고 명령을 실행하는 기능을 구현하는 과정입니다.
아래 과정은 아래 환경과 보드를 이용했습니다.
- Windows 11 Home
- STM32CubeIDE-1.11.2
- STM32 NUCLEO-F103RB 보드
1. 프로젝트 생성하기
- STM32 프로젝트를 생성합니다.
- 다음과 같이 동작하는 프로그램을 작성하도록 하겠습니다.
◦ 사용자는 UART를 이용해 STM32에 명령을 보냅니다. (1 ~ 9 사이의 숫자)
◦ 이때 Interrupt가 발생합니다.
◦ Interrupt Cabllback에서 명령에 해당하는 기능을 수행합니다. (1: LED 끄기, 2: LED 켜기)
◦ STM32는 명령 수행 결과를 UART를 이용해 출력합니다.
2. 핀 설정 및 소스코드 생성하기
- UART 통신을 하기 위해서 'Connectivity' > 'USART2'에서 아래와 같이 설정합니다.
◦ Mode: Asynchronous
◦ 'Parameter Settings' > 'Basic Parameters' > 'Baud Rate': 9600
- 'Connectivity' > 'USART' > 'NVIC Settings'에서 'USART2 global interrupt'의 'Enabled'를 선택합니다.
- 'System Core' > 'GPIO' > 'PA5' 핀의 User Label을 'LED'로 변경합니다.
- 버튼에 해당하는 'PC13' 핀을 'GPIO_EXTI13'으로 설정합니다. (기본값)
- 'System Core' > 'GPIO' > 'PC13' 핀의 값을 아래와 같이 변경합니다.
◦ GPIO mode: 'External Interrupt Mode with Rising edge trigger detection'
◦ GPIO Pull-up/Pull-down: 'No pull-up and no pull-down'
◦ User Label: 'BTN'
- 'System Core' > 'GPIO' > 'NVIC'에서 'Exit line[15:10] interrupts'의 'Enabled'를 선택합니다.
- 'System Core' > 'NVIC' > 'NVIC'에서 아래 두 포트의 'Enabled'를 선택합니다.
◦ USART2 golbal interrupt
◦ Exit line[15:10] interrupts
- 'Ctrl + S' 또는 'Code Generation' 버튼을 눌러서 코드를 생성합니다.
- main.h 파일에 아래와 같이 설정한 핀들이 지정된 것을 확인할 수 있습니다.
- stm32f1xx_hal_gpio.c 파일에 GPIO Interrupt를 처리하기 위한 함수가 __weak로 정의되어 있는 것을 확인할 수 있습니다.
- stm32f1xx_hal_uart.c 파일에 UART Interrupt를 처리하기 위한 함수가 __weak로 정의되어 있는 것을 확인할 수 있습니다.
3. printf를 UART로 출력하기 위한 설정
- printf를 이용한 출력이 UART로 출력될 수 있도록 설정하는 과정입니다.
- 프로젝트를 선택한 후 마우스 메뉴버튼을 눌러서 뜨는 팝업메뉴에서 'Properties'를 선택합니다.
- 실행되는 Properties 창에서 'C/C++ Build' > 'Settings' > 'Tool Settings' > 'MCU Settings'를 선택한 후 'Use float with printf form newlib-nono (-u _printf_float)'를 선택합니다.
- main.c 파일의 /* USER CODE BEGIN Includes */ 아래와 같이 include를 추가합니다.
#include <stdio.h>
- main.c의 /* USER CODE BEGIN PFP */ 다음에 아래 코드를 추가합니다.
int __io_putchar(int ch)
{
(void) HAL_UART_Transmit(&huart2, (uint8_t*) &ch, 1, 100);
return ch;
}
4. 코드 작성 및 컴파일
- UART를 이용해 데이터를 수신할 1byte buffer를 선언합니다.
uint8_t rx_data;
- /* USER CODE BEGIN 2 */ 다음에 UART 입력이 발생하면 수신 Interrupt가 발생하도록 아래 코드를 추가합니다.
HAL_UART_Receive_IT(&huart2, &rx_data, 1);
- /* USER CODE BEGIN 3 */ 다음에 주기적으로 LED가 깜빡이도록 아래 코드를 추가합니다.
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); // LED On
HAL_Delay(500);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); // LED Off
HAL_Delay(500);
- /* USER CODE BEGIN 4 */ 다음에 Button이 눌리면 'Button Pressed' 메시지가 출력되도록 아래 코드를 입력합니다.
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == BTN_Pin)
{
printf("Button Pressed\r\n");
}
}
- 방금 전에 작성한 'HAL_GPIO_EXTI_Callback' 함수 다음에 UART 입력이 발생하면 'Key Pressed' 메시지를 출력하고 다음 UART 입력을 기다리도록 아래 코드를 입력합니다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2) {
printf("Key Pressed: %c\r\n", rx_data);
HAL_UART_Receive_IT(&huart2, &rx_data, 1);
}
}
- 툴바에서 'Build Debug' 버튼을 눌러서 컴파일 실행합니다.
5. 다운로드 및 디버깅
컴파일된 이미지를 다운로드하고 테스트합니다.
- Teraterm을 실행하고 아래와 같이 Serial을 선택합니다.
- 버튼을 누르면 'Button Pressed'를 키보드를 입력하면 'Key Pressed'가 출력되는 것을 확인할 수 있습니다.
6. '1'을 입력하면 LED가 켜지고 '2'를 입력하면 LED가 꺼지도록 수정
- /* USER CODE BEGIN 0 */ 아래쪽에 아래와 같이 수행할 수 있는 명령을 출력할 수 있도록 하는 함수를 생성합니다.
void print_cmd()
{
printf("----------\r\n%s\r\n%s\r\n----------\r\nEnter Command:\r\n",
"1: LED On",
"2: LED Off");
}
- /* USER CODE BEGIN 2 */ 아래쪽에 print_cmd() 함수를 실행하도록 해서 최초에 실행가능한 명령을 출력하도록 수정합니다.
print_cmd();
- /* USER CODE BEGIN 3 */ 아래쪽에 기존 코드를 삭제하고 아무런 일도 수행하지 않도록 아래와 같이 수정합니다.
HAL_Delay(1000);
- HAL_UART_RxCpltCallback 함수를 아래와 같이 수정합니다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2) {
if (rx_data == '1')
{
printf("LED On execute\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
}
else if (rx_data == '2')
{
printf("LED Off execute\r\n");
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}
HAL_UART_Receive_IT(&huart2, &rx_data, 1);
print_cmd();
}
}
- 코드 수정이 완료 됐으니 컴파일하고 실행합니다.
아래와 같이 메뉴가 출력되고 1을 입력하면 LED가 켜지고 2를 입력하면 LED가 꺼지는 것을 확인할 수 있습니다.
'로봇 > STM32' 카테고리의 다른 글
STM32 자동차 제어하기(2) - LED / BUZZER 제어하기 (0) | 2023.03.19 |
---|---|
STM32 자동차 제어하기(1) - 기본환경 설정 (0) | 2023.03.19 |
STM32 Button을 누르면 UART로 메시지 출력하기 (2) | 2023.02.28 |
STM32 Button Interrupt를 이용한 LED 제어 (0) | 2023.02.28 |
STM32 Button을 이용해서 LED 깜빡이기 (0) | 2023.02.22 |