结构体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
.........
这些都已对号入座的数据就可以直接使用了.
上一篇:ST-LINK 的SWD接线图
下一篇:STM32程序的烧录方式 与 ISP一键下载
推荐阅读
史海拾趣
2001年对BURGESS来说是具有重要意义的一年。在这一年,BURGESS荣获了女皇赏,这是对其卓越业绩和贡献的极高认可。同时,BURGESS还售出了由Lurssen船厂制造的当时世界上最大的私人超级游艇,这一成就再次证明了其在游艇经纪行业的卓越地位。
Datatronic公司自创立之初,就致力于电子技术的创新。在早期,公司开发了一款具有革命性的数据处理器,该处理器以其高效的运算能力和稳定性迅速在市场上获得了认可。通过不断的技术迭代和优化,Datatronic公司逐渐在数据处理领域树立了技术领先的地位,吸引了大量客户。
E-Switch公司始终坚持以客户为中心的经营理念,致力于为客户提供优质的服务和产品。公司建立了完善的客户服务体系,及时解决客户在使用过程中遇到的问题。同时,E-Switch还积极与客户保持沟通交流,了解市场需求变化,以便及时调整产品策略和生产计划。正是这种以客户至上的经营理念和持续发展的战略眼光,让E-Switch在电子行业中不断发展壮大。
Essentra Components公司一直将客户服务放在首位,通过提供优质的售前咨询、售中支持和售后服务,赢得了客户的广泛赞誉。公司不仅为客户提供了丰富的产品选择,还根据客户的具体需求提供定制化的解决方案。此外,公司还建立了完善的物流配送体系,确保产品能够及时、准确地送达客户手中。这些努力使得Essentra Components在客户中树立了良好的口碑,为公司的发展奠定了坚实的基础。
微软前中国总裁唐骏曾经说过:“人的职业生涯是需要经营的,它和经营一个企业并无二致。”。这话用在天津英诺华微电子技术有限公司总经理褚以人身上再贴切不过。从一名核物理专业的大学生,到如今投身半导体产业的IC设计师,他在不断地经营中把自己 ...… 查看全部问答∨ |
我现在需要做个电话机!可以显示大头贴的!需要用块彩色的LCD,不知道市场上卖的带驱动的那种LCD是不是可以直接接到ARM处理器的IO口上?一般黑白的LCD也是可以的吧!主要的部分是在软件的编程吧!… 查看全部问答∨ |
本帖最后由 paulhyde 于 2014-9-15 04:15 编辑 2009年全国大学生电子设计竞赛G题是一个设计功率放大器的题,主要考核学生模拟电子技术的基础技能,要求是一定要用场效应晶体管做末级放大,且电路增益要求很大,如5mV的输入要达到5W(8欧负载)的输 ...… 查看全部问答∨ |
WINCE 能实现每秒5000次中断吗?有没有高手做过,请赐教。 Wince5.0 硬件每秒钟5000个脉冲触发X86CUP的7号中断,Wince能完全捕获到每一个中断吗,保证不丢,请做过的兄弟姐妹帮帮忙,提提思路,或者给 一段代码,不胜感激… 查看全部问答∨ |
跟踪代码发现usrRoot已经执行完,却始终没有跳转到boot的蓝屏界面,谁能指点一下为什么?谢谢! 我是在workbench下,VxWorks6.6… 查看全部问答∨ |
|
TI的2407A的调试一定要加一块RAM吗? 这块ram的作用是什么呀?能告诉我TI的哪个文档中描述这个问题了? ccs中的load 是把程序load到哪里了? 小弟刚刚学习,那位大虾帮帮我哦,谢谢!!! 还有,谁能提供一些汇编的例子,为什么TI只提供一 ...… 查看全部问答∨ |