历史上的今天
今天是:2024年11月25日(星期一)
2020年11月25日 | 结构体在STM32串口接收中的妙用
2020-11-25 来源:eefocus
结构体C程序中在STM32单片机串口接收的妙用之一
结构体是一种数据的归类方式,相比数组或变量更具有整体全面性,例如一个数组只可以放一些按照元素顺序存放的单元变量,即tab ={x,x,x,x,x......},i 有多大,数组内元素就有多少.那么我们这时候如果我们用这个数组来接收串口接收信息,信息的格式是: 数据头>数据长度>数据区>数据校验>数据尾.
假设数据区为 <身高-体重-性别-年龄-学历>
那么我们用数组接收时,提取数据时就需要计算出数据格式中每个单元所对应的位置,即数组中第i个元素对应的内容.这样显然是很麻烦的,效率很低.这就相当于先织了一个大网,捕捉到一网鱼,还得过下称,才能按照重量分类开来一样.
那么如果我们能提前根据接收的数据的格式来做一个容器,直接把接收的数据复制到这个容器内,岂不是省了好大劲,来,有个好东西,这就是结构体.
我们按照接收数据的格式顺序定义一个结构体如下:
typedef struct
{
u8 head; //数据头
u16 dataLen; //数据长度值
u8 height; //身高
u8 weight; //体重
u8 sex; //性别
u8 age; //年龄
u8 education; //学历
u8 checksum; //校验和
u8 endmark; //结束字节
} RecData;
RecData userData;
结构体已经定义好了,接下来我们就将串口接收的数据复制到这个结构体 userData里面.
定义串口接收的缓冲数组为
U8 serRec[len];
U8 len=100; //按照实际接收范围定义
我这里使用的是stm32单片机,串口具有空闲中断功能,当检测到串口收到一帧数据后,会进入中断置位,此时我们将进行数据的复制,如下:
memcpy(&userData,&serRec,len ); //内存复制
这就将串口数据完整的复制到userData中了, 而且是对号入座的, 错,stm32单片机是32位单片机,结构体中的变量存储时不是按照一字节对齐存储的,即默认每个存储单元分配是4个字节,像u8类型只占一字节这种默认也占了四个字节,显然空了3个字节,那么整个结构体的容量就不是结构体内所有变量的实际类型所占的大小之和.
我们要做的就是让结构体内的变量可以以一字节为最小单位对齐,即各个变量紧密的连在一起在内存中,这就需要字节对齐的预处理指令:
另外需要注意的是STM32的数据存储方式是小端模式,即数据的高字节存储在内存地址的高字节,低字节存储在内存地址的低字节,如果串口接收到的数据是低字节在前,则拷贝来的数据就不用进行处理,如果接收的数据是高字节在前则需要对拷贝来的数据进行高低字节反转.
什么是大端和小端
Big-Endian和Little-Endian的定义如下:
1) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
2) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
举一个例子,比如数字0x12 34 56 78在内存中的表示形式为:
1)大端模式:
低地址 -----------------> 高地址
0x12 | 0x34 | 0x56 | 0x78
2)小端模式:
低地址 ------------------> 高地址
0x78 | 0x56 | 0x34 | 0x12
可见,大端模式和字符串的存储模式类似。
//keil 下1字节对齐
#pragma pack(push,1)
typedef struct
{
u8 head; //数据头
u16 dataLen; //数据长度值
u8 height; //身高
u8 weight; //体重
u8 sex; //性别
u8 age; //年龄
u8 education; //学历
u8 checksum; //校验和
u8 endmark; //结束字节
} RecData;
#pragma pack(pop)//恢复keil原来的数据对齐方式
用这条预处理指令将结构体声明在其中即可,代表结构体中变量会在内存中按照一字节对齐的方式存储.
至此,
userData.head
userData.dataLen
userData.height
.........
这些都已对号入座的数据就可以直接使用了.
史海拾趣
|
因为在做一个和光通信有关的东西,将二进制信号编码后由光调制发射,然后用探测器接受,所以想知道一些些好用的光电探测器或红外接收管器,最好是体积小(集接收,放大,滤波,解调于一体的),灵敏度高的!!有急用,谢谢了!!… 查看全部问答> |
|
郭谦来了,李峰走了;蔡速平来了,童志远走了……几乎每个月,我们都可以看到各个汽车企业的人事变动,由此汽车行业成为人事变动最为频繁的行业之一。 事实上,汽车人才的匮乏逐渐成为制约行业快速发展的最大瓶颈,一方面是市场的高度需求,另一方 ...… 查看全部问答> |
|
每次路过家里那个基站,总忍不住一探究竟,但是“有电危险”,被重重铁丝网包裹的东西,让人很难接近,于是和老公就猜想,里面是多么多么豪华的配置,宛如宫殿一般,重金早就的狭小空间,也忍不住想爬到最高处看看远处的风景。 今天闲逛,在C11 ...… 查看全部问答> |
|
我也来谈谈我在威客明星的这些日子 我做威客明星没有多久的时间,算算还不到一个月。我是我的一个同学叫我去做的,那时候我天天打游戏。没什么事干,过得挺颓废的。因为经常和同学聊天的原因(我这个同学是专搞电脑的,电脑技术没得说的),聊以前、 ...… 查看全部问答> |
|
看到一篇文章介绍使用泰克MSO2000、MSO3000和MSO4000系列混合信号示波器调试数字电路中的一些小技巧,觉得很有帮助,想跟大家共享! [ 本帖最后由 特利科技 于 2010-8-18 14:33 编辑 ]… 查看全部问答> |
|
问题描述:使用FSMC访问外部存储器时,如果CPU与DMA同时向外部存储器发出请求,将会产生存储器访问错误。 这个问题已经在新版本的芯片中得到解决,请联系就近的代理商了解详情。… 查看全部问答> |
|
我采用的USB转串口,MAX232接法完全按照使用手册里面接的,然后MAX232的7、8脚分别与串口相连,9、10脚作为TTL/COM电平输入输出,问题是:当把9和10脚接一起时,发什么就接收什么,这很正常,但是,当将两者断开时(正常情况下,此时应接受不到数据 ...… 查看全部问答> |




