0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机大小端转换的几点小技巧

jf_pJlTbmA9 来源:嵌入式专栏 作者:嵌入式专栏 2023-09-18 10:58 次阅读

大小端及字节序在嵌入式软件开发过程中经常会遇到,数据传输、存储、通信等这些地方都会牵涉到,下面就来给大家分享一下相关知识。

回顾字节序

字节序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。
---来自百度百科

拿数据 0x01020304为例:

在大端CPU中:数据将存储为0x01(address + 0),0x02(address + 1),0x03(address + 2),0x04(address + 3)。

在小端CPU中:数据将存储为0x04(address + 0),0x03(address + 1),0x02(address + 2),0x01(address + 3)。

wKgZomUD6pGAGoQNAACWk_PhUKU469.jpg

如果你的程序使用简单的数据结构(例如“ int”和“ short”),则没有什么麻烦。但是,如果数据结构类似于以下示例,则可能会遇到问题。

union {
 unsigned int dat;
 unsigned char c[4]; 
}X;

void foo( ) {
 int t0;
 X.dat = 0x01020304;
 t0 = X.c[0];
 ・・・
}

在大端 CPU 中编译并执行此代码时, t0”的值为0x01。在小端CPU中, t0”的值为0x04。

那么问题来了:要想使存储顺序从大端,变为小端,怎么办呢?

方法其实有很多种,这里讲讲针对IAR的两种方法:

使用__big_endian关键字。

使用__REV, __REV16, __REVSH, RBIT函数。

使用__big_endian关键字

IAR中__big_endian关键字提供了一种方便的方式来将应用程序从big-endian移植到little-endian。

__big_endian关键字用于访问以big-endian字节顺序存储的变量,而与应用程序其余部分使用的字节顺序无关。在ARMv6或更高版本进行编译时,可以使用__big_endian关键字。

只需添加__big_endian关键字即可,如:

____big_endian union {
 unsigned int dat;
 unsigned char c[4]; 
}X;

void foo( ) {
int t0;
X.dat = 0x01020304;
t0 = X.c[0];
・・・
}

修改后的代码在低位字节CPU中编译和执行,变量“ t0”为0x01。

注意:此关键字不能用于指针。同样,此属性不能在数组上使用。

同时,关键字__big_endian插入REV指令以交换字节数据,REV指令的插入会影响代码大小和执行时间。

wKgaomUD6pKAa1p_AALai85Y_1A869.png

关键字具有限制,不能应用于复杂的数据结构,比如以下代码会生成错误:

__big_endian
union {
 unsigned long dat;
 unsigned char c[4];
 struct {
 unsigned long a0: 1;
 unsigned long a1: 1;
 unsigned long a2: 2;
 unsigned long a3: 4;
 unsigned long a4: 8;
 unsigned long a5: 16;
 }s;
} f1_dat2;

使用__REV, __REV16, __REVSH, RBIT函数

大端和小端之间的字节顺序差异只是顺序,因此我们需要做的是更改字节顺序,我们再次以变量0x01020304为例:

wKgaomUD6pSAaFzgAADg91L_Fr0357.png

我们可以通过代码实现交换功能,比如:

typedef unsigned long uint32_t;
uint32_t bswap_32(uint32_t x) {
uint32_t t = x;
uint32_t s;
s = ( (((uint32_t)(t)   (uint32_t)0x000000ffUL) << 24) |
    (((uint32_t)(t)   (uint32_t)0x0000ff00UL) << 8) | 
     (((uint32_t)(t)   (uint32_t)0x00ff0000UL) >> 8) | 
 (((uint32_t)(t)   (uint32_t)0xff000000UL) >> 24) );
 return s; 
}

通过这种方式实现,将导致消耗更多时间和代码大小。

在C代码中,我们通常编写内联汇编代码实现交换。IAR有种内部函数可以实现该功能。

比如下面交换功能:

wKgZomUD6pWATH9DAAICgU2p4J8844.png

代码如下:

#include 
void x1( void ) {
s2 = __REV(s1);
s3 = __REV16(s1);
s4 = __REVSH(s1);
}

以上就是在IAR中实现大小端字节序的迁移方法,感兴趣的读者可以在IAR中编码测试一下。

来源:嵌入式专栏

审核编辑:汤梓红

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

    关注

    6030

    文章

    44486

    浏览量

    631853
  • 嵌入式
    +关注

    关注

    5057

    文章

    18964

    浏览量

    301839
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10802

    浏览量

    210769
收藏 人收藏

    评论

    相关推荐

    制作单片机几点心得体会

    制作单片机几点心得体会,在电源的输入端正向串联或反向并联一个二极管,当不小心接反电源的时候,二极管可以保护单片机不受反向电压的袭击
    发表于 06-05 11:23 4158次阅读
    制作<b class='flag-5'>单片机</b>的<b class='flag-5'>几点</b>心得体会

    单片机大小数据处理问题

    ,0x0022,0x0033,0x0044};char *ptr = buffer;发送数据的话直接操作ptr就可以了,现在考虑到单片机大小问题,如果我在这样发送是不是就会出现问题,没有合适的
    发表于 04-26 10:53

    单片机学习的意义有哪几点

    单片机学习的意义,我分为以下几点:1、能够加深对硬件底层的理解,对其内部结构的学习可以让你了解计算机的工作机理;2、应用单片机的产品已经渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机
    发表于 01-05 07:41

    单片机ad转换电路

    单片机ad转换电路:通过对双积分A/ D 转换过程及其原理的分析,结合8031 单片机定时计数器的特点,设计出一种新的A/ D 转换电路.
    发表于 05-11 22:50 265次下载
    <b class='flag-5'>单片机</b>ad<b class='flag-5'>转换</b>电路

    单片机EMC设计的几点建议

    单片机EMC设计的几点建议 1.单片机的工作频率   1.1单片机的设计应根据客户的需求来选择较低的工作频率首先介绍一下这样做的
    发表于 04-27 10:00 514次阅读
    <b class='flag-5'>单片机</b>EMC设计的<b class='flag-5'>几点</b>建议

    单片机EMC设计的几点建议

    单片机的工作频率单片机的设计应根据客户的需求来选择较低的工作频率首先介绍一下这样做的优点:采用低的晶振和总线频率使得我们可以选择较小的单片机满足时序的要求,这
    发表于 07-02 11:46 722次阅读
    <b class='flag-5'>单片机</b>EMC设计的<b class='flag-5'>几点</b>建议

    单片机实验-- AD转换实验

    单片机实验-- AD转换实验
    发表于 12-24 23:10 0次下载

    单片机C语言的几点基础知识说明

    本文档的主要内容详细介绍的是单片机C语言的几点基础知识说明。
    发表于 07-05 17:41 2次下载
    <b class='flag-5'>单片机</b>C语言的<b class='flag-5'>几点</b>基础知识说明

    stc单片机ad转换程序

    本文主要阐述了stc单片机ad转换程序及转换心得。
    的头像 发表于 11-04 09:58 1w次阅读

    51单片机的IO接口的地址和赋值大小的关系

    关于51单片机的IO接口的地址与赋值大小理解前提了解关于51单片机的IO接口的地址与赋值大小理解其他单片机定义前提了解提示:我们需要回顾C语
    发表于 11-17 10:51 14次下载
    51<b class='flag-5'>单片机</b>的IO接口的地址和赋值<b class='flag-5'>大小</b>的关系

    ARM大小模式

    以及外设的性质等, 一定要先在单片机的数据手册上查清楚可以使用的。在绝大多数情况下,基于 CM3 的单片机都使用小模式。为了避免不必要的麻烦,基本清一色地使用小
    的头像 发表于 09-29 18:37 5683次阅读
    ARM<b class='flag-5'>大小</b><b class='flag-5'>端</b>模式

    破解单片机固件的几点建议

    单片机(MCU)一般都有内部程序区和数据区(或者其一)供用户存放程序和工作数据(或者其一)。 为了防止未经授访问或拷贝单片机的机内程序,大部分单片机都带有加密锁定位或者加密字节,以 保护片内程序。
    发表于 03-06 09:42 1008次阅读

    单片机如何增大电流?电流大小与什么有关?

    单片机如何增大电流?电流大小与什么有关?  单片机是一种嵌入式系统,是一种微处理器,可以控制电子设备,如电子元器件、机械和电动设备等,来满足特定需要。作为电子设备的一种核心部件,单片机
    的头像 发表于 09-28 16:46 3498次阅读

    单片机中RAM少有哪几点原因?

    单片机中RAM少有哪几点原因? 正文: 单片机是指把整个计算机系统集成在一个芯片之内,具有微型化、低功耗、低成本等特点的集成电路。单片机系统中RAM少常有
    的头像 发表于 10-29 16:23 637次阅读

    单片机解密失败有哪几点原因呢?

    单片机解密失败有哪几点原因呢? 单片机解密失败的原因有很多,下面将详细列举可能的原因,并逐一进行解释,以期为您提供一个详尽、详实、细致的文章。 1. 芯片厂商实施的硬件保护机制 现代单片机
    的头像 发表于 11-07 10:17 811次阅读