Uart Polling으로 LED를 On/Off 할 수 있게 되었다.
https://pilimage.tistory.com/19
Polling방식에서는 데이터가 들어올 때까지 대기하는 시간 동안은 버튼을 눌러도 동작하지 않는 경우가 있었다. (HAL_UART_Receive의 timeout 시간을 길게 하면 확실히 볼 수 있다.)
Uart Interrupt를 이용하여 이를 해결해보자
먼저 Uart Interrput 기능을 설정하기 위해 PinOut & Configuration에서 사용하는 Uart를 선택하고 NVIC Settings 메뉴에서 Interrupt를 Enable 시킨 후, Code Generation을 한다.
이제 Uart Interrupt 기능을 사용할 수 있게 되었다.
먼저 메인 함수의 MX_USART1_UART_Init()을 한 후, HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)를 호출한다.(*pData 는 수신받을 변수, size는 수신받을 데이터 크기)HAL_UART_Receive_IT는 수신 인터럽트를 Enable 하고 수신 대기 상태로 만든다.인터럽트가 발생하면 HAL_UART_IRQHandler 가 호출된다. HAL_UART_IRQHandler에서 자동으로 인터럽트를 처리한 후 Callback 함수를 호출한다.
여러 Callback 함수들이 있지만 수신과 관련된 RxCpltCallback을 사용한다.
HAL_UART_RxCpltCallback은 수신을 완료했을때 Callback이 되며 __weak함수이므로 해당 weak 함수를 수정하지 말고 직접 따로 구현을 해주면 된다.
먼저 구현한 HAL_UART_RxCpltCallback은 다음과 같다.
uart1로 인터럽트가 수신이 되면 데이터를 저장하는 data_arr에 수신받은 데이터를 넣는다.
수신받은 데이터를 HAL_UART_Transmit_IT로 송신하여 콘솔 창에 출력한다.
그 후, HAL_UART_Receive_IT를 호출하여 다시 수신 대기상태로 만든다.
(HAL_UART_Receive_IT의 경우 1회용이라고 생각하고 한번 수신을 한 후, 계속 수신을 하려면 반복하여 호출해야 한다. )
이제 메인 함수의 루프에서 data_arr을 체크하여 LED를 동작시키면 된다.
기존의 on/off 에서 LED1이면 LED on / LED0 이면 LED off가 되도록하였다.
1. RxCpltCallback에서 수신을 받은 후 idx++을 하기에 메인 루프에서는 idx-1을 하여 '\r' 또는 '\n'을 찾는다.
2. 해당 조건에 들어가면 '\0'을 넣어 문자열의 끝을 알린다.
3. 문자열을 비교하여 LED를 On/Off 한다.
해당 코드로 기능들은 잘 동작한다.
하지만 뭔가 찝찝하다.
일단 메인 루프에 버튼 조작까지 주르륵 늘어있어서 가독성이 별로인 것 같다.
버튼 조작 부분을 함수로 만들어 버리자
push_btn과 push_tick은 저장된 값을 알고 있어야 하므로 포인터 매개변수로 넘겨주자
콘솔을 입력하는 부분도 함수로 만들자
data_arr 배열의 경우 RxCallback에도 호출되기 때문에 전역 변수로 사용하였다.
메인의 소스가 훨씬 깔끔해진것 같다.
하지만 그래도 찝찝하다.
지금의 RxCpltCallback에서 데이터를 처리하는 방식으로는 문제가 발생할 것 같은 느낌적인 느낌이 난다.
만약 메인 루프의 use_console을 처리하는 중에 인터럽트가 발생하여 데이터를 수신한다면 idx가 변경되면서 문제가 생길 수 있지 않을까?
예를 들어 LED0을 수신받고 use_console의 루틴으로 들어갔는데 바로 LED1을 수신 받으면 data_arr[idx]='\0'을 처리할 때 idx가 바뀌어 다음 LED1이 동작이 안되지 않을까?
수신 데이터를 처리하는데 있어서 싸늘하다....불안한다...
이를 좀 더 보완하고자 링 버퍼(Ring Buffer)를 이용한 인터럽트를 사용해보자
언제?
다음글에서 ....
끝
'지식저장소 > STM32F746' 카테고리의 다른 글
[C/STM32] 7 . LED 제어 - PWM 생성 (0) | 2022.04.14 |
---|---|
[C/STM32] 6. LED ON/OFF - Uart Interrupt + Ring buffer 제어 (0) | 2022.03.29 |
[C/STM32] 4. LED ON/OFF - Uart Polling 제어 (1) | 2022.03.17 |
[C/STM32] 3. LED ON/Off - 버튼 채터링 추가 (2) | 2022.02.25 |
[C/STM32] 2. LED ON/OFF - 버튼 제어 추가 (2) | 2022.02.24 |