MCU的大小端模式
- 大端模式
- 小端模式
- 大小端模式测试
- 联合体概念
- MCU大小端模式测试
- 大端模式测试
- 小端模式测试
- 大小端模式转换
在进行MCU开发的时候,我们需要注意MCU的数据存储模式,在嵌入式中有两种不同的存储模式,分别是 大端模式和小端模式。
大端模式
所谓的大端模式,意思就是高字节的数据存储在低位,低字节数据存储在高位。具体的表示方式如下图所示
小端模式
所谓的小模式,意思就是低字节的数据存储在低位,高字节数据存储在高位。具体的表示方式如下图所示
大小端模式测试
针对不同的MCU,我们都需要分清其数据的存储方式,如果存储方式不对,那么在不同的MCU之间进行通信时,就会因为数据格式的不对导致通信错误。那么当我们拿到一个MCU后,又该如何知道其存储模式呢,我们可以使用C语言中的联合体进行区分。
联合体概念
联合体是C语言中的一种数据结构,它的定义方式跟结构体类似,但是跟结构体不同的是,联合体中的所有成员变量都使用同一块存储空间,存储空间的大小由联合体中最大的成员变量的数据类型决定。
union test
{
unsigned char a;
unsigned short b;
unsigned int c;
};
在上面的程序中,定义了一个联合体,里面有3个成员变量,因为联合体中的成员变量是共用同一个存储空间的,所以上面的联合体中的存储空间就由最大的成员变量决定,也就是unsigned int类型。
MCU大小端模式测试
对于市面上的常用MCU,Crotex-M系列的MCU其存储格式是小端模式,而51内核的MCU其存储格式是大端模式,这两种MCU我们都可以使用Keil软件进行测试。
大端模式测试
要测试大端模式,我们需要先安装Keil的C51编译器,安装好之后我们打开软件。编写一段测试程序。
union test
{
unsigned char mychar[4];
unsigned long mylong;
};
void main()
{
union test test1;
test1.mychar[0] = 0x12;
test1.mychar[1] = 0x34;
test1.mychar[2] = 0x56;
test1.mychar[3] = 0x78;
}
测试程序编写好之后,我们打开Keil的软件仿真界面
我们打开Options for Target->Debug->Use Simulator
配置好之后,点击仿真按键进入仿真模式
从keil的变量地址中我们可以看到,mychar[0]的值为0x12,但是在mylong变量中,0x12被放到了高位,所以从上面测试可以看出,C51内核的MCU是大端模式
小端模式测试
小端模式的测试跟大端模式的测试差不多,但是要安装Keil的ARM编译器。安装好之后我们打开软件,编写一段测试程序。
union test
{
unsigned char mychar[4];
unsigned int myint;
};
void main()
{
union test test1;
test1.mychar[0] = 0x12;
test1.mychar[1] = 0x34;
test1.mychar[2] = 0x56;
test1.mychar[3] = 0x78;
}
测试程序编写好之后,我们打开Keil的软件仿真界面
我们打开Options for Target->Debug->Use Simulator
从keil的变量地址中我们可以看到,mychar[0]的值为0x12,在myint变量中,0x12被放到了低位,所以从上面测试可以看出,Crotex-M内核的MCU是小端模式。
大小端模式转换
对于需要在不同架构的MCU之间进行通信的场景来说,通常都需要进行大小端的转换,下面就给出常用的大小端转换的代码
static unsigned int little1,big1,little2,big2;
unsigned int swap_unsigned_int(unsigned int in_32)
{
unsigned int out_32;
out_32 = ((in_32 & 0xFF) << 24) | (((in_32 >> 8) & 0xFF) << 16) | (((in_32 >> 16) & 0xFF) << 8) | (((in_32 >> 24) & 0xFF));
return out_32;
}
void main()
{
// 大端转小端
big1 = 0x78563412;
little1 = swap_unsigned_int(big1);
// 小端转大端
little2 = 0x12345678;
big2 = swap_unsigned_int(little2);
}