STM32 HAL库 UART发送与接收数据的学习笔记
转义字符:
\r |
回车(CR) ,将当前位置移到本行开头 |
013 |
\n |
换行(LF) ,将当前位置移到下一行开头 |
010 |
数据发送:
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
阻塞式发送,最好不要两个该函数连续使用(会出问题,我踩过坑),就是发送字节大小使用sizeof()计算的话,会导致后面一个内容不能正常发送;
while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX) ;使用标志位等待前一个发送结束后也不能解决后面一个发送失败的问题(验证过)
因此在连续使用阻塞式发送数据的时候,发送字节的大小自行计算不要使用sizeof()
数据接收:
普通接收函数HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);又叫阻塞式接收
size接收的数据长度 数据只能接收到设置的长度,发送了超过size字节的数据,则只接收size字节的数据
试了几次该函数每次都只能接收一个字节 未找到原因 不推荐该方式接收;
中断接收函数HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
达到size字节数才触发中断 试了一下没有达到指定字节也能触发中断接收
想接收不定长的数据时可以采取以下方法:
在主函数中设置接收中断,每次接收一个字节:
#include <string.h>
#define RXBUFFERSIZE 256 //最大接收字节数
char RxBuffer[RXBUFFERSIZE]; //接收数据
uint8_t aRxBuffer; //接收中断缓冲
uint8_t Uart1_Rx_Cnt = 0; //接收缓冲计数
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //开启串口接收中断,这一句要放到main()函数中
原理:在中断回调函数中将每次接收到的该字节 转存到另一个数组中拼接起来
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
if(Uart1_Rx_Cnt >= 255) //溢出判断
{
Uart1_Rx_Cnt = 0;
memset(RxBuffer,0x00,sizeof(RxBuffer));
HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10,0xFFFF);
}
else
{
RxBuffer[Uart1_Rx_Cnt++] = aRxBuffer; //接收数据转存
if((RxBuffer[Uart1_Rx_Cnt-1] == 0x0A)&&(RxBuffer[Uart1_Rx_Cnt-2] == 0x0D))
/*判断结束位结束位的意思是换行
0A LF/NL(Line Feed/New Line) 换行键
0D CR (Carriage Return) 回车键*/
{
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)); //清空数组 将数组清空为0
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中断
}