最近因为项目需要,需要做一个STM32和Windows的串口通讯协议来交换数据,本着追求极致的心态,来讨论一下简明的数据帧的设计方法。
##数据的传输方式
对于很多单片机初学者而言,可能他们接触到串口 首先想到的就是通过串口打印字符串,然后就会很理所当然的想到了用“打印”的方式来传输数据。
比如我们需要传输一个float型的数据value,可能小白们首先会想到的方式就是串口重定向printf然后像下面这样把数据传输过去
printf("%f",&value);
但是实际上,对于程序之间的交流,使用字符串打印这样的方式是非常浪费传输数据的,因为假设这个浮点数据为1234.567占了8个字符(小数点也占一位) 所以用字符串传输的方式就需要通过串口传输8个字节,但是实际上float类型在内存里面永远都是占用4个字节,所以使用字符串的传输效率是非常低的,并且这样传输 上位机收到的也是字符串,还得把字符串的数据读出来重新放到一个float类型的数据里面,才可以进行运算。
因此,通过串口传输的数据基本上都是通过直接传输内存数据来实现的。
它的原理大概是这样 同样以float类型作例子
当你在程序里面声明了一个float类型的变量的时候,程序会为这个变量开辟一个4字节的内存空间,然后这4个字节的内存数据唯一决定了这个float类型的数据(具体实现方式可以百度float类型的存储方式)。因此,我们的串口只要把这4个字节的数据通过串口传输到上位机,然后上位机根据传输协议直接把这4个字节写入到一个float类型的内存空间中,然后这个float类型的数据也就随之完成了。
为了方便这个过程的实现 我们可以定义一个联合体
typedef union{
float value;
unsigned char sendbuf[4];
}send_type;
这样定义的好处就是:联合体内的所有成员共用一片内存空间
然后我们需要传输数据float型数据的时候,我们只需要声明一个send_type类型,然后对send_type的value直接赋值,然后与此同时sendbuf的数据也会因此改变,我们就可以直接发送sendbuf[4]这四个字节了。建议在上位机的程序里面也使用同样的联合体,然后当上位机的snedbuf[4]放入接收的4个字节之后,value就可以直接读出所需要的数据了。然后对于其他各种数据类型,如double,long int之类的类型同样也可以使用这种方式来传输,只需要注意好各种数据类型需要占用的内存空间就可以了
##组合数据的传输方式的注意事项
通过上面的方式,我们通过传输内存数据的方式来传输单个数据了,那么当我们需要传输多个数据呢?
或者说,传输的并不是直接的数据,而是带有一定的开头,结尾的数据,假如协议规定数据起始要先发一个字节的标志0x0d,然后传输两个float型数据,再以结束标识符0x0d结尾
(此处0x0d是人为规定,协议可以要求为其他值)
这时候只考虑联合体的话并不能解决我们的问题
这时候结构体就派上用场了
typedef struct{
unsigned char head;
float send1;
float sned2;
unsigned char end;
}sned_frame;
像这样我们就可以按照顺序把协议整合成一个结构体的形式,编译器会根据结构体内成员顺序在内存里按顺序分配内存空间,上位机和单片机共用同一种结构体形式,然后只需要设定好帧内各成员内容之后,把结构体直接发过去,好像就可以了??
其实问题并没有想的这么简单。结构体虽然会占用一片连续的内存空间,但是实际上结构体内的成员并不一定是连续分配内存空间的。可以实践,刚刚声明的结构体,它并不是只占用1+4+4+1=10个字节的内存空间。为什么会这样呢?因为编译器在分配内存时会按照内存对齐的方式来分配内存,因此前面的unsigned char变量为了和float对齐,编译器为其分配了4个字节的空间。这会导致我们协议的帧长度增加一些没有意义的空的数据,并且判断帧长度将变得复杂。
(当然,其实如果上位机和stm32的内存对齐的方式恰好是一样的话,只要保证把整个结构体传输过去,整个通信应该还是可以完成的)
那么如何取消编译器的内存自动对齐呢?
我们可以在结构体定义后紧跟一句attribute ((packed))
这一句的意义是将该定义的内存分配强行按最小位对齐(也就是按字节对齐)。
那么我们修改后的结构体定义是这样的:
typedef struct{
unsigned char head;
float send1;
float sned2;
unsigned char end;
}_attribute__ ((__packed__)) sned_frame;
可以实践,对现在的结构体使用sizeof关键字,得到的的长度为10。这样就可以压缩帧的长度,避免数据浪费了。在需要改动协议的时候,也只需要简单的增加结构体的成员即可。
/-----------------------------------------------------------------------------------------------------------
2018年6月4日11:26:30后记:
在STM32的开发中,如果使用了硬件浮点数解算的话,同时又存在串口发送浮点型数据的话,此时最好不要压缩数据帧,按照编译器的自动补充空字节来发送,上位机也保持一样的数据包.因为硬件浮点解算涉及到了内部的专用电路,而此时如果浮点数没有内存对齐的话是无法使用硬件解算从而出现错误的.这时候会带来不必要的麻烦. 当然 如果需要和性能受限制的设备进行通信,不舍得填充空数据的话,在涉及内存不对齐的浮点数据可以先开一个临时变量进行操作,在进行发送的前一刻使用memcpy函数将浮点数放进数据帧内也是可以的
上一篇:STM32添加路径报错
下一篇:OpenMV数据打包发送以及STM32对数据的解析(串口方式)
推荐阅读
史海拾趣
Excel-Display Corporation(以下简称EDC)成立于XX世纪初,由一群富有远见的电子工程师和企业家共同创立。他们看到了当时显示技术领域的巨大潜力,决定成立一家专注于研发和生产高质量显示器的公司。
EDC在创立初期就注重技术研发和产品质量,投入大量资金引进先进的生产设备和技术人才。经过几年的努力,EDC成功推出了一系列性能稳定、画质优良的显示器产品,逐渐在市场上崭露头角。
与此同时,EDC也积极开拓国际市场,与多家国际知名企业建立了合作关系。这些合作不仅为EDC带来了技术上的支持,也为其产品的国际化推广奠定了坚实的基础。
为了进一步扩大市场份额,Dean Technology公司开始积极拓展国际市场。他们通过设立海外办事处、与当地企业建立合作关系等方式,将产品推向全球。在这个过程中,公司不断优化产品设计,提高生产效率,以满足不同国家和地区客户的需求。随着国际市场的不断拓展,Dean Technology的高压二极管产品逐渐在全球范围内获得了良好的口碑。
进入21世纪,随着LED技术的快速发展,ERG看到了固态照明市场的巨大潜力。2008年,公司决定成立一个新的部门——ERG Lighting,专注于为固态照明市场设计、制造和分销LED驱动器和其他照明配件。这一举措极大地拓展了公司的业务范围,并使其在市场上占据了有利地位。ERG Lighting的成立,不仅为公司带来了新的增长点,还进一步巩固了其在电源转换产品领域的领先地位。
随着国内市场的日益饱和,博林公司开始积极拓展海外市场。公司制定了详细的国际化战略,通过参加国际展览、建立海外销售渠道等方式,不断提升品牌知名度和影响力。同时,博林公司还积极寻求与国际知名企业的合作机会,通过技术合作和市场共享等方式,实现互利共赢。这些举措使得博林公司的市场份额不断扩大,国际竞争力日益增强。
近年来,随着智能电网技术的快速发展,CINTERION凭借其领先的M2M通信技术,在该领域取得了显著突破。其EU3 M2M模块因其卓越的性能和稳定性,荣获了SmartGrid.TMCnet.com颁发的2011年智能电网杰出奖。这一奖项的获得,不仅证明了CINTERION在智能电网技术创新方面的实力,也为公司在该领域的进一步发展奠定了坚实基础。
随着技术的成熟,APMI开始着手市场拓展。公司积极与各大电子制造商合作,为其提供定制的电源管理解决方案。同时,APMI还加大了品牌宣传力度,通过参加行业展会、发布技术白皮书等方式,提高品牌知名度和影响力。凭借卓越的产品性能和完善的售后服务,APMI在市场上赢得了良好的口碑,客户群体不断扩大。
摘要:本文从国内外安防工程的比较入手,就徐谈林教授提出的安防工程要做到“四个结合”进行了分析,指出只有综合考虑四个结合,才能建成一个经济实用安防工程。关键词:安防工程商安防工程 安防系统 安防设备一、序言在安防行业中安防工程商占有重 ...… 查看全部问答∨ |
|
用最新库玩转智林STM32开发板(之三)------用自动重装载的PWM点亮真彩背光板 用最新库玩转智林STM32开发板(之三)------用自动重装载的PWM点亮真彩背光板用最新库玩转智林STM32开发板(之三)------用自动重装载的PWM点亮真彩背光板 用最新库玩转智林STM32开发板------用自动重装载的PWM点亮真彩背光板 上次用的是TOGGLE,又用 ...… 查看全部问答∨ |
(一)背景介绍 随着安全防范体制和技术的进一步完善和提高,使得医疗行业完全有条件、有能力应用最新的高新科技成果,带领全行业步入一个新的台阶,提供最先进最及时的医疗服务,树立自己的行业形象,并能够高效的为用户服务。 为促 ...… 查看全部问答∨ |
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY not1 IS PORT(a : IN STD_LOGIC; b : OUT STD_LOGIC); END not1; ARCHITECTURE no_t OF not1 IS BEGIN &nb ...… 查看全部问答∨ |
|
USB HOST,NAS,CDMA,EDGA无线上网卡,PCIE转换芯片,WIFI模块,Catalyst Semiconouctorinc 代理Oxford 相应的接口芯片,VIA WIFI 芯片,Yitran PLC芯片,及CATALYST 如: PCMCIA CDMA/GPRS无线上网卡解决方案---OXCF950B, OXCFU950B 该方案方案是采用高通通讯芯片与OXCF950芯片一起实现,是目前市面上应用最为广泛的无线上网卡实现方案。 ...… 查看全部问答∨ |
我的是IAR MSP430 最新板,并成功破解,破解之后,发现我的debug菜单总是灰的,无论你怎么选择,怎么编译就是灰色,请路过大侠,高手们支招我怎么才能让C-Spy好用… 查看全部问答∨ |
【颁奖礼】ADI有奖下载活动之3 两线环路供电变送器解决方案 活动详情:>>ADI有奖下载活动之3两线环路供电变送器解决方案! 又到了颁奖时刻,这也是我们最喜欢发帖的时候,此活动是年前结束的,因为春节特殊时间段的顾忌,所以现在才公布,收到迟到的礼物,需要大家的理解!马上揭晓30名获奖者名单!! ...… 查看全部问答∨ |