| 
				打卡等级:以坛为家III打卡总天数:628最近打卡:2025-10-30 10:57:50 论坛元老 
 
 
	积分3545 
 | 
 
| 最近在研究使用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编译器的小端序;
 
 
 
 
 
 | 
 |