学习STM32有很多关于地址直接操作函数和指针这里分析一下,在程序中看到这样一句话:
if((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)
其中:
*(vu32*)(0X20001000+4))== (*(__IO uint32_t*)(0X20001000+4))==(*(volatile unsigned int*)(0X20001000+4))
(*(vu32*)(0X20001000+4)) 通过内存寻址访问地址为(0x20001000 + 4)中的值
(0X20001000+4)只是一个常量;
(volatile unsigned int*)(0X20001000+4) 将0x20001000 + 4这个常量强制转化成volatile unsigned int类型的指针;
(*(volatile unsigned int*)(0X20001000+4)) 相对于取0x20001000 + 4地址处的值。
为什么要将0x20001000 + 4这个常量强制转化成volatile unsigned int类型的指针呢?
假设定义*P 取地址符 &P 得到P地址,这个地址是随机的系统分配空闲地址,我们不能直接给P赋地址值,因为那样是不合法的,我们只能给指针赋值为NULL。
但是现在必须让指针指向一个已知地址(0X20001000+4),必须转换类型,在地址前面加上指针转换的类型我们这里用的volatile unsigned int*,如果不转换,不成功。
在具体研究一下指向指针的指针看程序和输出:
现在我们来一行一行的看:
第一个printf语句 a,这个大家都知道啦,输出肯定是63啊,因为十进制99,十六进制就是63啊!
第二个printf语句 pa, pa是不是就代表0x0012ff40啊呵呵!一个变量的本质就是避免程序员和地址打交到啦!04的话就是0012ff44啦!对吧!
第三个printf语句 *pa, *pa就是第二句中的0012ff44取内容啊,当然就是63啦!
第四个printf语句 ppa, ppa呢!通过前面的笔记一看就知道它显示出的值是0012ff40啦!
第五个printf语句,*ppa, *ppa呢!唉!现在看来真是太简单了,显示出0012ff44
第六个printf语句,**ppa, **ppa呢就是0012ff44再取内容嘛!63啦!
通过这么一分析,有木有更清晰一点、绝对不会头晕吧!
假如使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义:
这里使用 volatile关键字的好处就是:
1.volatile是一个类型修饰符(typespecifier);
2.volatile关键字声明的变量,编译器对访问该变量的代码就不再进行优化;
3.volatile 关键字声明的变量,对变量的存取不能缓存到寄存器,每次使用时需要在内存中重新存取。