大端模式、小端模式、高字节序、低字节序、MSB、LSB

您所在的位置:网站首页 小端排序 大端模式、小端模式、高字节序、低字节序、MSB、LSB

大端模式、小端模式、高字节序、低字节序、MSB、LSB

2024-07-09 12:14| 来源: 网络整理| 查看: 265

摘要:你知道内存是怎么读取数据的吗?知道数据是怎么一个一个字节发送的吗?是低字节先发还是高字节先发?是bit0先发还是bit7先发?是从低地址开始读还是从高地址开始读?看完本篇比应该就明白了~

内存的读写永远从低地址开始读/写,从低到高!从低到高!从低到高!重要的话说三遍

大端模式和小端模式

大端模式和小端是实际的字节顺序和存储的地址顺序对应关系的两种模式。

百度百科

大端模式:高位字节存放在低地址中,低位字节存放在高地址中。最直观的字节序。

小端模式:高位字节存放在高地址中,低位字节存放在低地址中。最符合人的思维的字节序,x86、ARM都这么搞(KEIL C51中,变量都是大端模式的;KEIL MDK中,变量是小端模式的。)。

用图表示更加容易理解。以unsigned int value = 0x12345678为例,分别按照大端模式和小端模式存放在芯片中。

内存地址0x000000010x000000020x000000030x00000004大端模式0x120x340x560x78小端模式0x780x560x340x12

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

百度百科

不管是大端还是小端模式,我们在读取和存储数据的时候一定都是从内存的低地址依次向高地址读取或写入。另外注意,x86平台是小端的,ARM平台是小端的,而PowerPC平台是大端的。

字节高低位

一般左边为高位,右边为低位(这个高低来自于人类的阅读习惯,数字从左向右,表示由大到小)

一个16位(双字节)的数据,比如0xFF1A,那么高位字节就是0xFF,低位是0x1A。 如果是32位的数据,比如0x3F68415B。高位字(不是字节)是0x3F68,低位字是0x415B。

右边是低位位,左边是高位(人的阅读习惯)

LSB和MSB

最高有效位(most mignificant bit,msb)指的是一个n位二进制数字中的n-1位,具有最高的权值2^(n-1)。 有时也指Most Significant Byte(MSB),指多字节序列中具有最大权重的字节。

同理,最低有效位(least significant bit,lsb)和的是一个n位二进制数字中的0位,具有最低的权值2^0。有时也指Least Significant Byte(LSB),指多字节序列中具有最小权重的字节。

所以0x12345678的最高有效字节就是0x12,最低有效字节就是0x78,这样明白了吧!

举个栗子

当选择模数转换器(ADC)时,最低有效位(LSB)这一参数的含义是什么?

对于一个12位串行转换器,它会输出由1或0组成的12位数串。通常,转换器首先送出的是最高有效位(MSB)(即LSB + 11)。有些转换器也会先送出LSB。我们假设先送出的是MSB,然后依次送出MSB-1 (即 LSB + 10)和MSB -2(即LSB + 9)并依次类推。转换器最终送出MSB -11(即LSB)作为位串的末位。

LSB这一术语有着特定的含义,它表示的是数字流中的最后一位,也表示组成满量程输入范围的最小单位。对于12位转换器来说,LSB的值相当于模拟信号满量程输入范围除以2^12 或 4096的商。如果用真实的数字来表示的话,对于满量程输入范围为4.096V的情况,一个12位转换器对应的LSB大小为1mV。但是,将LSB定义为4096个可能编码中的一个编码对于我们的理解是有好处的。

截取自某12位ADC芯片数据手册

高位先行msb 、低位先行lsb

高位先行即在传输一个字节的时候先传输高位msb;低位先行即在传输一个字节的时候先传输低位lsb。高位先行和低位先行是针对串行数据传输方式来说的。常见的串行传输方式有串口(UAR)、I2C、SPI等。以串口传输方式为例,标准的串口传输方式是低位先行,芯片在通过TX引脚发送数据时,依次发送位0、位1……位7。

串口传输是低位先行

UART在数据传输时,协议规定了数据传输必须是低位先行,看下面的时序图你就知道了~

截图自STM32F407中文参考手册

IIC传输是高位先行

IIC的数据和地址均以8位字节传输,MSB 在前。从图中可以清楚地看到:

截图自STM32F407中文参考手册IIC部分

这一点也反映在代码中,我们随便找一个IIC的读字节和写字节的函数看看:

void i2c_SendByte(uint8_t _ucByte) { uint8_t i; /* 先发送字节的高位bit7 */ for (i = 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3