- 打卡等级:以坛为家II
- 打卡总天数:511
- 最近打卡:2025-06-17 10:39:32
论坛元老
- 积分
- 3093
|
最近在研究使用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编译器的小端序;
|
|