良许Linux教程网 干货合集 你真的懂CPU大小端模式吗?

你真的懂CPU大小端模式吗?

大多数人可能已经十分熟知了像RS232、RS485、CAN这样在工业界广泛运用的总线系统,它们都是数字信号的传输手段。但是,对于模拟信号,我们通常用什么方法进行传输呢?

在工业应用中,经常会有需要检测各种非电类的物理参数,比如温度、压力、速度和角度等,这就要求把这些参数转化为可以进行远距离传输的模拟信号,以便将数据送达几百米之外的监控室或是显示装置。在这些应用中,最为普遍的技术选择是利用4至20毫安(mA)的电流范围来传递模拟信息。

电流型信号之所以受到青睐,是因为它的抗干扰能力非常强。在工业现场,可能会遇到几伏大小的噪声电压,而这些噪声的功率通常很低,导致产生的噪声电流一般小于纳安级别,这将对4至20mA信号传输造成极其微小的干扰;此外,因为电流源具有很高的内阻,所以线路电阻即便串联在回路中也不会影响传输的准确性,允许信号通过普通的双绞线在数百米范围内稳定传输;而且由于电流源的大内阻性质和稳定的电流输出,接收端仅需安装一个250欧的地面电阻,便可以得到一个0至5伏电压的信号,这样低输入阻抗的接收器能够确保纳安级别的输入电流干扰仅产生极弱的电压噪声。

二、什么是大端和小端?

大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。

小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

假如32位宽(uint32_t)的数据0x12345678,从地址0x08004000开始存放:

地址 小端存放内容 大端存放内容
0x08004003 0x12 0x78
0x08004002 0x34 0x56
0x08004001 0x56 0x34
0x08004000 0x78 0x12

再结合一张图进行理解:

image-20231226200123916
image-20231226200123916

从上面表格、图可以看得出来,大小端的差异在于存放顺序不同

在维基百科中还有有一段关于“端的起源”:

image-20231226200127094
image-20231226200127094

三、数组在大端小端情况下的存储

以unsigned int value = 0x12345678为例,分别看看在两种字节序下其存储情况,我们可以用unsigned char buf[4]来表示value。

1.大端模式下

地址 数组 位置
高地址 buf[3] 0x78 低位
buf[2] 0x56
buf[1] 0x34
低地址 buf[0] 0x12 高位

2.小端模式下

地址 数组 位置
高地址 buf[3] 0x12 低位
buf[2] 0x34
buf[1] 0x56
低地址 buf[0] 0x78 高位

不知道大家对数组进行强制转换成整型数据没有?

如果你要进行强制转换,肯定要考虑大小端问题。

四、大小端谁更好?

小端模式:强制转换数据不需要调整字节内容,1、2、4字节的存储方式一样。

大端模式:符号位的判定固定为第一个字节,容易判断正负。

总结:大端小端没有谁优谁劣,各自优势便是对方劣势。

五、常见字节序

常见的操作系统是小端,通讯协议是大端。

1.常见CPU的字节序

大端模式:PowerPC、IBM、Sun

小端模式:x86、DEC

ARM既可以工作在大端模式,也可以工作在小端模式。

(内容来自网络)

2.STM32属于小端模式

测试一款MCU属于大端,还是小端方法很多种,通过打印数据,通过在线调试查看数据:

image-20231226200132998
image-20231226200132998

当然,在MCU的手册中也有相关说明。

六、大小端转换

开篇说了,实际应用中,大小端应用的地方很多通信协议、数据存储等。如果字节序不一致,就需要转换。

只要你理解其中原理(高低顺序),转换的方法很多,下面简单列列两个。

1.对于16位字数据

#define BigtoLittle16(A)   (( ((uint16)(A) & 0xff00) >> 8)    | \
                                       (( (uint16)(A) & 0x00ff) 

2.对于32位字数据

#define BigtoLittle32(A)   ((( (uint32)(A) & 0xff000000) >> 24) | \
                                       (( (uint32)(A) & 0x00ff0000) >> 8)   | \
                                       (( (uint32)(A) & 0x0000ff00) 

方法很多种,感兴趣的朋友可自行研究。本文就写到这里,希望对你有帮助。

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部