先说解决方案,细节和实现代码都放在正文
下位机:把结构体拆分成8位的整型数据,加上数据包头和包尾,然后按顺序单个单个地发出;
上位机:把串口里的数据读取出来,找到包头,按顺序装填到结构体中,然后使用结构体引用数据;
一、串口通信
串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式
相信浏览本文的朋友都已经使用过串口通信协议在各机器之间传递信息。这种通讯方式只需要四只引脚就能在短距离内实现全双工的通信,非常方便。目前许多通用芯片(如STM32)还提供了硬件支持,并给定了数据收发的接口函数。

以stm32为例,我们可以通过一些特定的函数使用芯片上的USART外设,不需要操心协议的电平规定就能够进行数据的收发,相关的函数在STM32的参考手册中列出:

在固件库中也可以找到:

大致看上去十分方便,但细看就会发现一个十分重要的问题,譬如发送数据的这个函数USART_SendData():
/**
* @brief Transmits single data through the USARTx peripheral.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param Data: the data to transmit.
* @retval None
*/
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
/* Transmit Data */
USARTx->DR = (Data & (uint16_t)0x01FF);
}
他只给你提供了单个数据的发送方式,而且数据类型限制位16位无符号整型(uint16_t),这就引出了我们在文章开头提到的拆分并封包发送的必要性。下面我们先介绍一下发送的结构体的样子,然后再说拆分封包的问题。
二、定义要发送的结构体
首先明确发送的结构体是什么样子的
/**
@part 通信数据结构
*/
/* 加速度信息结构体-XYZ三分量 */
typedef struct CSModuleInfo_ACC{
float _acc_X;
float _acc_Y;
float _acc_Z;
}CSInfo_Acc;
/* 经纬度信息结构体-经纬两分量 */
typedef struct CSmouduleInfo_LL{
float _latitude;
float _longitude;
}CSInfo_LL;
/* 测控站信息结构体 */
typedef struct CSInfoStrcutre CSInfoS;
typedef struct CSInfoStrcutre{
/* 核心温度 MCU温度 */
float _temp_O_MCU;
/* 气温 */
float _temp_env;
/* 气压 */
float _gp;
/* 加速度 */
CSInfo_Acc _acc;
/* 经纬度 */
CSInfo_LL _ll;
}* ptrCSInfo;
为了保证本文能符合大伙的需求,咱搞一个结构体嵌套,并且把数据类型都定义浮点数。意在说明我们这种传输结构体的方式不受结构体类型的限制,也不受浮点数的存储方式的限制,请放心学习使用。
注:代码中/* 测控站信息结构体 */部分的ptrCSInfo是这个大结构体的指针类型,CSInfoS是这个结构体的别名,这种写法是C语言的语法规则所允许的,不用感到奇怪。
三、下位机封包发送
封包发送的过程可以用下面的代码实现:
/**
* @brief 将数据打包并发送到上位机
* @param
ptrInfoStructure 指向一个装填好信息的infoStructure的指针
* @retval 无
*/
void CSInfo_PackAndSend(ptrCSInfo ptrInfoStructure)
{
uint8_t infoArray[32]={
0};
uint8_t infoPackage[38]={
0};
CSInfo_2Array_uint8(ptrInfoStructure,infoArray

介绍如何通过串口发送和接收结构体数据,包括下位机拆分封包及上位机解析过程。
最低0.47元/天 解锁文章
3506





