大小端定义与应用场景及C语言中大小端的实现

描述

大小端定义:

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

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

举个例子来说明,我们利用485进行通讯,采用的大端模式传输16进制数据为:01 23/ef 05,按照大端模式的数据为2301和05ef,转化为10进制为8961和1519。说白了就是直接将数据拼接进行转化。

应用场景:

网络上数据传输上往往采用大端模式进行数据传输;跨硬件平台进行数据传输,数据格式存在差异,存储字节的顺序可能不同;采用通讯协议每次传输数据的字节有一点限制等

例如char类型数据只占一个字节,传输可以直接传输,但是对于非char类型的数据,要在RS485,CAN通讯过程中就需要进行大小端数据的转化。

c语言中大小端的实现:

注意在转化过程中需要保持相同的大小端数据格式,不可以形成同一组数据中同时存在大端和小端数据,容易让使用者或者二次开发者产生误解。

z这里主要讲解大小端数据转化的原理与相关的代码:

首先常用的有16位数据和32位数据大小端转化,作为嵌入式代表的STM32单片机的unsingned int型:

/* 32位数据小端模式 */
#define uint32_data(x)    //定义32位数据,这里x为用户自己定义的需要转化的数据
(uint32_t)((((uint32_t)(x) & 0xff000000) >> 24) |\            //这里是ff000000不是ffff0000,按照每两个字节进行的转化
                    (((uint32_t)(x) & 0xff000000) >> 8) |\    //数据右移8位
                    (((uint32_t)(x) & 0x0000ffff) << 8) |\    //数据左移8位
                    (((uint32_t)(x) & 0x000000ff) << 24)\
             )  
/* 16位数据小端模式 */             
#define uint16_data(x)    //定义16位数据,这里x为用户自己定义的需要转化的数据
(uint16_t)((((uint16_t)(x) & 0x00ff) << 8) |\
          ((((uint16_t)(x) & 0xff00) >> 8) \
          )

 

按照上述代码测试一下,主函数调用一下,这里直接打印即可:

 

printf("%#x\n",uint32_data(0xef847321));
printf("%#x\n",uint16_data(0xef84));

输出结果:

217384ef

84ef

假如需要将一个int型can_data数据转化为小端模式,可以尝试如下代码:

can_data[0] = (u8)(num & 0xFF);           //取数据低8位
can_data[1] = (u8)((num >> 8) & 0xFF);    //数据右移8位,将低位移除保留高位数据

假如需要将一个int型can_data数据转化为大端模式,可以尝试如下代码:

can_data[2] = (u8)((num >> 8) & 0xFF);           //数据右移8位,将低位移除保留高位数据
can_data[3] = (u8)(num & 0xFF);                  //取数据为低8位

总结:

数据的大小端对不同平台数据传输具有重要意义,在具体使用时需要根据需要进行数据转化。

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分