STM32串口通讯协议
预先设置好一个发送缓冲区,先将帧头帧尾存到发送缓冲区对应位置。
要发送一帧数据前,先将待发数据填入缓冲区的数据区中,校验结果也填入缓冲区的对应区域,然后再调用串口发送程序依次将缓冲区内容发送出去。
接收也是类似的,先定义一个接收缓冲区,收到一个就顺序填入接收缓冲区,达到一帧的字节数后,就开始搜索帧头,检查帧尾、校验和,完全正确后,从接收缓冲区对应位置取出数据,进行相应处理。
你好,不错的代码,期待后续大家分享,,,,,,,,,,,,,,,,,,,,,
大神,我们有些都是初学者,没见过高山,入门的时候难免会迷茫,给大家分享一个感觉比较好用的串口代码吧,感激不尽!
先写个发送的例子吧,以TI Cortex-M3为例:
// 定义一个10字节的发送缓冲区(如果内存充足,最好定义成全局变量,用起来比较方便)
// 这里假设你的通讯协议定义的一帧数据包中有10个字节:
// 第1字节为帧头,第2字节为设备识别码,后面有7字节的数据,最后一字节为校验和
unsigned char UART0SendBuf[10];
// 通过串口0发送若干个字节数据的函数
void Uart0SendOut(const unsigned char* pData, unsigned int len)
{
unsigned char i;
for(i = 0;i < len; i++)
UARTCharPut(UART0_BASE, pData[i]);
}
// 在需要通过串口0发送数据的地方使用如下代码
unsigned char i, j;
unsigned char CheckSum;
UART0SendBuf[0] = FRAME_HEAD;// FRAME_HEAD为帧头的宏定义
UART0SendBuf[1] = DEVICE_ID;// DEVICE_ID为设备识别码(取决于通讯协议中是否有此项)
CheckSum = 0;
// 这里就是你将自己想要发送的数据填充到缓冲区的代码了,请根据实际需求来修改
// 假设你要发送的7字节数据就在UserData[]数组中
for(i=0;i<7;i++)
{
UART0SendBuf[i+2] = UserData[i];
CheckSum += UserData[i];
}
UART0SendBuf[9] = CheckSum;// 计算校验和
Uart0SendOut(UART0SendBuf,10);// 这里就是将一帧数据发送出去的语句了,采用的是函数调用的方式。
不好意思,上面有一行注释放错位置了,订正如下:
CheckSum += UserData[i];// 计算校验和
UART0SendBuf[9] = CheckSum;// 校验和添加到帧尾
非常感谢,真是帮了我大忙了,我一定会好好体会学习的。
当发送一个9位数据呢?如何用9位数据来区别地址与数据帧
如果是用的直接支持9bit数据UART的MCU,在发送前直接设置数据或地址标识就可以了;
如果是需要手动设置9bit数据的MCU,则在每帧数据发送时单独设置控制位。
不用客气!
你的问题还没解决吗?
高手
行家一出手,便知有没有?
学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了
接收还是发送,这是个问题
串口通信,具体协议原理可以不用懂,直接调用初始化和收发送函数即可
学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了学习了
学习学习!
受教了!
真赞,好好试试。
51单片机 时可以通过TB8和RB8来决定 发送/接收 地址帧或数据帧的,一般时手动设置
但是STM32好像没有这个功能,我要做一个STM32(主机)跟8个51单片机(从机) 多机通信。请问STM32 作为主机 ,怎样决定发送的是地址或数据?
代码里 这样区分行不行?
//·发送地址,唤醒从机
void USART_Send_addr_9b(UART_HandleTypeDef *huart, uint8_t Data)
{
huart->Instance->DR= ((uint16_t)Data |(uint16_t)0x100);
}
//·对从机发送数据
void USART_Send_data_9b(UART_HandleTypeDef *huart, uint8_t Data)
{
huart->Instance->DR= ((uint16_t)Data &(uint16_t)0x0FF);
}