找回密码
 立即注册
查看: 1094|回复: 1

关于大端序和小端序的问题

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:511
  • 最近打卡:2025-06-17 10:39:32

46

主题

232

回帖

3093

积分

论坛元老

积分
3093
发表于 2023-7-18 20:11:35 | 显示全部楼层 |阅读模式
最近在研究使用sdcc编译8051C程序,
遇到两个跟大端序和小端序相关的问题,这里分析记录一下:


case1: 移植keil pwm实现呼吸灯的程序;


keil中定义了一个16位的特殊功能寄存器,用来同时设置PWM占空比的高位和低位;
#define     PWM05T2    (*(unsigned int volatile xdata *)0xFF3A)
直接给PWM05T2付值int类型的变量能够得到想要的效果;
使用类似的定义方式用sdcc编译发现没有呼吸灯的效果;

后来经过大佬提示是大端序和小端序的问题;
STC8G的相关寄存器设置是:
低位地址是:0xFF3A用来存放PWM05T2H高位数据;
高位地址是:0xFF3B用来存放PWM05T2L低位数据;

keil是大端序编译器,低位地址存放数据的高位;
所以当 PWM05T2 = 0X1234 时:
0xFF3A 存的就是 0x12;
0xFF3B 存的就是 0x34;

而sdcc是小端序编译器,高位地址存放高位数据:
所以当 PWM05T2 = 0X1234 时:
0xFF3A 存的就是 0x34;
0xFF3B 存的就是 0x12;

case2: 读取rom中存放的1.19v基准电压;
以STC8G2K64S4为例,假设基准电压是:1.19v. 也就是 1190mv
按照官方文档基准电压的
数据高位 0x04 存放在地址低位: 0XFDF7
数据低位 0xa6 存放在地址高位: 0XFDF8
keil中通过指针指向低位地址,能够读取到正确的数值;
sdcc就读不到正确的数值,编译器认为地址低位的数据就是数据低位,因此读取的数据是 0xa604 ,
考虑大端小端问题按照字节采用分别读取的方式:
读取到地址低位的数据是数据高位:4(十进制)
读取到地址高位的数据是数据低位:161(十进制)
换算成16进制就是 0x04a1,再转换成10进制就是:1185 准确的;
定义一个int类型的指针指向低位地址;

思考:
大端序和小端序是编译器决定的,
在大多数情况下我们进行int类型操作时不需要关注大端小端的问题,编译器会按照自己的端序进行读写;
但是当遇到类似寄存器设置的时候还是需要清晰的知道mcu的厂商时如何规划寄存器地址的,跟所使用的编译器是否兼容。
这里的两个case SCT的设置恰好满足keil 51编译器的小端序;




不争是争
回复

使用道具 举报 送花

11

主题

340

回帖

939

积分

荣誉版主

积分
939
发表于 2023-7-23 13:52:13 来自手机 | 显示全部楼层
改成8位操作就对了,读两次。
其实int翻译成汇编也是读两次的。
sdcc小端模式
C51大端模式
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-17 16:32 , Processed in 0.150702 second(s), 53 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表