关于串口调试助手,还应知道:
这里可以看出下列代码中的 0D回车,0A换行 是用来判断结束位的
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D))
- /* Private includes ----------------------------------------------------------*/
- /* USER CODE BEGIN Includes */
- #include <string.h>//meset()函数调用
- /* USER CODE END Includes */
- /* USER CODE BEGIN PV */
- #define RXBUFFERSIZE 256 //最大接收字节数
- char RxBuffer[RXBUFFERSIZE]; //接收数据
- uint8_t aRxBuffer; //接收中断缓冲
- uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数
- /* USER CODE END PV */
- /* USER CODE BEGIN 2 */
- HAL_UART_Receive_IT(&huart1,&aRxBuffer,1); //中断接收一个字符
- /* USER CODE END 2 */
- /*
- 串口接收中断回调函数
- */
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- {
- if (Uart1_Rx_Cnt >= 255)
- {
- memset(RxBuffer,0x00,sizeof(RxBuffer));//对数组进行清零操作
- HAL_UART_Transmit(&huart1,(uint8_t *)"数据溢出",4,0xffff);//
- }
- else
- {
- RxBuffer[Uart1_Rx_Cnt++]=aRxBuffer; //接收数据转存
- if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位 0D回车,0A换行
- {
- HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer, Uart1_Rx_Cnt,0xFFFF); //将收到的信息发送出去
-
- while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);//检测UART发送结束
-
- Uart1_Rx_Cnt = 0;
- memset(RxBuffer,0x00,sizeof(RxBuffer)); //清空数组
- }
-
-
- }
- HAL_UART_Receive_IT(&huart1,&aRxBuffer,1); //使得程序可以重新触发接收中断 +
-
- }
上述代码实现的是 发送数据被返回
实验二:
1、串口发送/接收函数
2、串口中断函数
3串口查询函数
HAL_UART_GetState(); 判断UART的接收是否结束,或者发送数据是否忙碌
UART几个标志位
TXE、TC、RXNE、ORE。
TXE:发送数据寄存器为空 (Transmit data register empty)
TC:发送完成 (Transmission complete)
RXNE:读取数据寄存器不为空 (Read data register not empty)
ORE:上溢错误 (Overrun error)
UART接收丢失数据
UART接收丢失数据与软件和硬件都有可能有关系,下面说几个常见丢失数据的原因及解决办法。
1.接收溢出丢失数据
指未及时取走数据导致溢出错误而丢失数据,通常是发生在大量数据、以查询方式接收数据的情况下。在MCU启动过程中、接收数据过多处理不及时、复杂系统响应不及时等情况都会出现数据丢失的情况。
解决办法:
2.接收中断丢失数据
使用UART中断接收数据相比查询接收数据的方式更常见,中断方式比查询方式响应更及时,但不合理处理同样也会存在数据丢失的情况。
在数据量大时,UART接收中断函数耗时、优先级低等情况下容易丢失数据。
解决办法:
3.时钟误差导致丢失数据
在通信波特率较高的情况下,如果时钟误差加大,很可能导致数据丢失。
解决办法:
UART发送丢失数据
UART发送丢失数据很多工程师都遇到过,通常情况下是传输未完成的原因。
HAL库已经有几年了,但还是有很多工程师都使用标准外设库,这时如果自己封装接口不当,就会存在发送最后一字节数据丢失的问题。
1.UART传输未完成导致数据丢失
如下代码,只考虑非空,但实际传输并未完成。
- //往USART1,发送 length长度的数据data
- void SendData(u8 *data,u8 length)
- {
- u8 i;
- for(i=0;i<length;i++)
- {
- USART_SendData(USART2, data[i]);
- while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)//等得发送完成
- {
- }
- }
- }
但发送非空不代表发送完成,虽然在某些场合更高效,但某些场合就会导致数据丢失。
比如:使用此函数发送之后进入休眠、关闭接收端设备电源等情况下。
解决办法:使用HAL封装的接口,代码包含判断传输完成
- /*******************************************************************************
- * @函数名称 SendData1
- * @函数说明 向串口1发送数组信息
- * @输入参数
- data:要发送的信息的首地址
- len: 发送的长度
- * @输出参数 无
- * @返回参数 无
- *******************************************************************************/
- void SendData1(u8 *data,u8 length)
- {
- u8 i;
- for(i=0;i<length;i++)
- {
- HAL_UART_Transmit(&huart1,&data[i],length,0xFFFF); //将收到的信息发送出去,HAL封装的接口,代码包含判断传输完成
- }
- }