大端模式:数据的高字节保存在内存的低地址中,数据的低字节保存在内存的高地址中;
小端模式:数据的高字节保存在内存的高地址中,数据的低字节保存在内存的低地址中;
举个例子来说明,我们利用485进行通讯,采用的大端模式传输16进制数据为:01 23/ef 05,按照大端模式的数据为2301和05ef,转化为10进制为8961和1519。说白了就是直接将数据拼接进行转化。
网络上数据传输上往往采用大端模式进行数据传输;跨硬件平台进行数据传输,数据格式存在差异,存储字节的顺序可能不同;采用通讯协议每次传输数据的字节有一点限制等
例如char类型数据只占一个字节,传输可以直接传输,但是对于非char类型的数据,要在RS485,CAN通讯过程中就需要进行大小端数据的转化。
注意在转化过程中需要保持相同的大小端数据格式,不可以形成同一组数据中同时存在大端和小端数据,容易让使用者或者二次开发者产生误解。
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位
数据的大小端对不同平台数据传输具有重要意义,在具体使用时需要根据需要进行数据转化。
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !