STM32F103RCT6学习笔记
问题解决
时钟资源无法使用外部时钟HSE、LSE
在RCC设置中打开
High Speed Clock(HSE)高速时钟
Low Speed Clock (LSE)低速时钟
CrystakCeramic Resonator 外部晶振时钟源
BYPASS Clock Source 旁路时钟源
printf重定向
按照教程重写fputc函数发现能在串口输出东西,但是是乱码
后来发现,那是使用keil编译器时才需要重写的函数,如果是GCC的话,需要重写 __io_putchar() 和 _write()
int __io_putchar(int ch){
uint8_t temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xff);
return (ch);
}
int _write(int fd, char *ptr, int len)
{
HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, 0xFFFF);
return len;
}
使用clion自带的串口moniter时发现,不加printf内容最后要加\n
,否则无法打印,原因未知
每次MX重新生成代码都需要重写CMakeList
在CMakelist_template中添加代码,CLion中选择update CMakelist with STM32CubeMX
使用uart中断回调函数实现串口收发时只能生效一次
查阅资料了解到HAL库对于USART的接收中断的处理,划分了好几层。
首先,串口接收中断触发后的入口程序在启动文件startup_stm32f401xc.s中定义为USART1_IRQHandler()和USART2_IRQHandler();
然后,USARTx_IRQHandler()的内容就一句:调用HAL_UART_IRQHandler();
接着,HAL_UART_IRQHandler()对一系列的异常场景进行处理后,再调用UART_Receive_IT();
最后,而在UART_Receive_IT()中,会判断RxXfeiCount值是否为0,当为0时就关断了串口接收中断!RxXfeiCount是UART结构体中“剩余待接收的数据计数值”。——也就是说,每当接收完HAL_UART_Receive_IT()函数中规定的RXBUFFERSIZE个数据就关闭接收中断。这也解释了为什么会出现只收到第1批数据后,再也无法接收数据的现象了。
HAL库对于串口接收中断处理的几层调用关系如下:
USARTx_IRQHandler()
┗━ HAL_UART_IRQHandler()
┗━ UART_Receive_IT()
{
if (--huart->RxXferCount == 0U)
{
/* Disable the UART Data Register not empty Interrupt */
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
.......
.......
HAL_UART_RxCpltCallback();
.......
}
显然,在Main()中每次调用HAL_UART_Receive_IT()后,都能收到一批数据,那么采用循环的方式也可以持续接收到串口数据。但是这样做和“查询接收”没啥区别了吧。另一种更好的思路是:每完成一批数据接收后,自动使能接收中断。
而在UART_Receive_IT()函数中调用了接收回调函数HAL_UART_RxCpltCallback()。只要在这个回调函数中末尾再添加HAL_UART_Receive_IT(),重新打开串口接收中断、并设定接收的数据量就解决了。
提示:这里填写该问题的具体解决方案:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
.............
.............
HAL_UART_Receive_IT(UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
}
Q.E.D.