前言
本文记录下我学习STM32CubeMX时的流程,系统板是基于STM32F103C6T6,方便以后回忆。本章记录串口通信。这里居然有玄学问题,给我整了好久,头都大了。可能也是我能力有限才有的吧,泪目。
目录
- 串口通信
串口通信
-
STM32CubeMX中的串口配置,配置完后就可以生成了。
-
Keil5中打开生成的工程文件。写下发送函数,发送测试。
uint8_t send_str1[] = "hello world\r\n"; //这个在开头定义,所以说截图中没看到。 //&huart1 为串口1 , send_str1 为要发送的数据 , sizeof(send_str1) 为要发送的数据的长度 , 1000 为设置超时时间 HAL_UART_Transmit(&huart1,send_str1,sizeof(send_str1),1000); //堵塞模式发送,超时时间1000ms //关于&huart1这个名称,在串口端口初始化函数原型上已有它的名称结构在声明了,所以说要是换串口后,不知道名称,也可以跳转去看。
stm32f1xx_hal_uart.h文件中,串口操作相关函数。在725行位置处。
- 堵塞模式,传输函数将会阻塞,一直等待缓冲区可用时再传输数据,如果超过了超时时间,缓冲区在一定时间内无法发送数据时,传输函数将会超时退出。
- 非堵塞模式,则与上述相反,没有超时时间的概念,有数据就收发,不存在数据传输等待。
//堵塞模式发送 HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); //堵塞模式接收 HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); //非堵塞模式发送 HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); //非堵塞模式接收 HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
-
接收测试
接收测试的思路本来是想在接受完后,用发送函数发给串口调试助手。
- 测试方法一,在主函数中加入下述代码。现象,接收函数一直响应,不管有无数据。而且就算有数据它也会一直重复响应那一串数据,我想可能是中断标志或者数据缓冲区没清除干净,但是试了各种方法后到不行,挺奇怪的。
if(HAL_UART_Receive(&huart1,rece_str1,16,100)) { HAL_UART_Transmit(&huart1,rece_str1,sizeof(send_str1),1); //memset(send_str1, 0, sizeof(send_str1)); }
-
测试方法二,在主函数中加入下述代码。现象,莫名的卡顿感,怎么个卡顿呢,就是在必须要在规定的超时时间内收到规定长度的字节长度否正就丢弃(这是我后来才发现的,具体测试三说),把接收时间缩短或者换非堵塞模式又收不到。虽然说总感觉是接收函数出了问题,但是还是没头绪。
if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) //判断是否是空闲中断 { HAL_UART_Receive(&huart1,rece_str1,16,2000); HAL_UART_Transmit(&huart1,rece_str1,sizeof(send_str1),2000); memset(rece_str1,0,16); //清空缓冲区 __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断标志(否则会一直不断进入中断) }
-
测试方法三,在主函数中加入下述代码。这其实就是在测试方法二的基础上,将HAL_UART_Receive()函数的接收字节从16个变为1个。(多加了一个发送换行)
if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) //判断是否是空闲中断 { HAL_UART_Receive(&huart1,rece_str1,1,2000); HAL_UART_Transmit(&huart1,rece_str1,1,2000); HAL_UART_Transmit(&huart1,"\r\n",2,2000); memset(rece_str1,0,16); //清空缓冲区 __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断标志(否则会一直不断进入中断) }
总结:我现在,只有单字节正常接收的能力。串口收发以后可能都要基于测试方法三,单字节单字节的收,在整合成多字节了,多字节就像其它方法一样各种问题。当然,可能还有其它解决思路,有时间在探究。
扩展
在发送数据前,通常可以使用格式化函数将各种数据转换为字符形式后再发送。在C语言中,可以使用sprintf函数实现,例如:
sprintf(数组,"Data1:%d\r\n",整型数据);