c语言变量充当绝对地址,C语言访问绝对地址 - 单片机/MCU论坛 - 电子技术论坛 - 广受欢迎的专业电子论坛!...

本帖最后由 天道酬勤dw 于 2012-10-27 23:50 编辑

最近在学习凌阳单片机,但看到#define P_Watchdog_Clear (volatile unsigned int *) 0x7012这个宏定义不明白什么意思,因为之前STC单片机用KEIL编程时是用sfr P0 = 0x80;表示特殊功能寄存器的,第一次见这样总是感觉很奇怪。大量查阅相关资料,现整理如下,分享给需要的朋友,资料来源互联网。

对于#define P_Watchdog_Clear (volatile unsigned int *) 0x7012 我们分析一下:

(1)    (volatile unsigned int *) 0x7012 :0x7012 只是个值,前面加(unsigned int *)表示将0x7012强制转换为指针类型,我用的是凌阳SPCE061A是十六单片机,所以0x7012 强制转换为指向unsigned int类型的指针地址。意思是说读写这个地址时,要写进的值是unsigned int 型,读出的值也是unsigned int 型。那么(volatile unsigned int *) 0x7012 是一个固定的指针,是不可变的,不是变量。而如果写成unsigned int  *P则才是指针变量。

(2)    volatile:这个关键字说明这个变量是易变的,可能会被意想不到地改变,这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变。关键字volatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值,这样编译器就不会去假设这个变量的值了。例如用while((unsigned int *)0x7012)时,为了加快运行速度,编译器可能会把0x7012 地址的值读取到Register中,然后不停地判断Register相应位。而不会再读取0x7012 地址的值 ,这样当然是不行了,因为程序或其它事件(中断等)会改变0x7012 地址的值 ,结果很可能是一个死循环出不来了。用了volatile 则要求每次都去读0x7012 地址的实际值。

(3)    如果在前面加" * ":  *(volatile unsigned int *) 0x7012 ;对指针引用,就能操作指针所指向的0x7012地址的内容了。 如果写成#define P_Watchdog_Clear (*(volatile unsigned int *) 0x7012)那么与unsigned int P_Watchdog_Clear就差不多是一样的了,只不过前面的P_Watchdog_Clear 的地址是固定的。#define P_Watchdog_Clear (*(volatile unsigned int *) 0x7012);可看作是一 个普通变量P_Watchdog_Clear,这个变量有固定的地址,指向0x7012 。

关于#define XBYTE ((unsigned char volatile xdata *) 0)的理解:

XBYTE被定义成(unsigned char volatile xdata *) 0,0为一个基于寄存器的指针(可理解为:只不过这个指针用一个二进制常量标识,且其指向的内存单元在定义时就以固定为该二进制常量且不可更改.),其存储内型为2指向xdata,偏移量为0,这样XBYTE成为指向xdata零地址的指针,通过XBYTE[0]可以读写该地址处的数据;同样通过XBYTE[8000]也可以访问xdata空间绝对地址为8000处的数据。

关于#define BCFG0  (*((volatile unsigned int *) 0xFFE00000))的理解首先0xFFE00000为一个指针没错,且该指针为unsigned int型指向0xFFE00000内存单元,BCFG0被定义为对该指针做“*”指针运算,这样,BCFG0可理解为对内存单元0xFFE00000进行标识的一个unsigned int 型普通变量,同过BCFG0可是实现对该寄存器的读写访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值