www.openedv.com
您好,欢迎您!    会员注册 | 登入 
公告:欢迎访问www.openedv.com开源电子网,开源共享共同进步,祝您新年快乐,万事如意!
设为首页 | 加入收藏
论坛首页 » STM32/STM8专区 前往: 
(*(volatile unsigned long *)详解
发表人 内容
[Down] [Up]
[楼主位] yaocp86

等级:NO
注册时间:
2011/01/10 20:44
文章: 67
来自: 南京
离线

(*(volatile unsigned long *)
对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的端口的概念。如果是内存映射,那就方便的多了。

以 #define IOPIN (*((volatile unsigned long *) 0xE0028000)) 为例:作为一个宏定义语句,define是定义一个变量或常量的伪指令。首先( volatile unsigned long * )的意思是将后面的那个地址强制转换成 volatile unsigned long * ,unsigned long * 是无符号长整形,volatile 是一个类型限定符,如const一样,当使用volatile限定时,表示这个变量是依赖系统实现的,以为着这个变量会被其他程序或者计算机硬件修改,由于地址依赖于硬件,volatile就表示他的值会依赖于硬件。

volatile 类型是这样的,其数据确实可能在未知的情况下发生变化。比如,硬件设备的终端更改了它,现在硬件设备往往也有自己的私有内存地址,比如显存,他们一般是通过映象的方式,反映到一段特定的内存地址当中,这样,在某些条件下,程序就可以直接访问这些私有内存了。另外,比如共享的内存地址,多个程序都对它操作的时候。你的程序并不知道,这个内存何时被改变了。如果不加这个voliatile修饰,程序是利用catch当中的数据,那个可能是过时的了,加了 voliatile,就在需要用的时候,程序重新去那个地址去提取,保证是最新的。归纳起来如下:

1. volatile变量可变允许除了程序之外的比如硬件来修改他的内容
2. 访问该数据任何时候都会直接访问该地址处内容,即通过cache提高访问速度的优化被取消

对于((volatile unsigned long *) 0xE0028000)为随硬件需要定义的一种地址,前面加上“*”指针,为直接指向该地址,整个定义约定符号IOPIN代替,调用的时候直接对指向的地址寄存器写内容既可。这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。上述表达式拆开来分析,首先(volatile unsigned long *) 0xE0028000的意思是把0xE0028000强制转换成volatile unsigned long类型的指针,暂记为p,那么就是#define A *p,即AP指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作。

对于(volatile unsigned char *)0x20我们再分析一下,它是由两部分组成:
1)(unsigned char *)0x20,0x20只是个值,前面加(unsigned char *)表示0x20是个地址,而且这个地址类型是unsigned char ,意思是说读写这个地址时,要写进unsigned char 的值,读出也是unsigned char 。
2)volatile,关键字volatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值。例如用while((unsigned char *)0x20)时,有时系统可能不真正去读0x20的值,而是用第一次读出的值,如果这样,那这个循环可能是个死循环。用了volatile 则要求每次都去读0x20的实际值。

那么(volatile unsigned char *)0x20是一个固定的指针,是不可变的,不是变量。而char *u则是个指针变量。
再在前面加"*":*(volatile unsigned char *)0x20则变成了变量(普通的unsigned char变量,不是指针变量),如果#define i (*(volatile unsigned char *)0x20),那么与unsigned char i是一样了,只不过前面的i的地址是固定的。

那么你的问题就可解答了,(*(volatile unsigned char *)0x20)可看作是一个普通变量,这个变量有固定的地址,指向0x20。而0x20只是个常量,不是指针更不是变量。




这篇文章被编辑了 1 次. 最近一次更新是在 2011/06/29 17:12


希望在哪里呀,希望在哪里!
[加为好友] 回复 引用回复
[Down] [Up]
[1楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

学习...



我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
[Down] [Up]
[2楼] yaocp86

等级:NO
注册时间:
2011/01/10 20:44
文章: 67
来自: 南京
离线

。。。原子哥,你来学毛啊,忽悠人^_^


这篇文章被编辑了 1 次. 最近一次更新是在 2011/06/30 14:42


希望在哪里呀,希望在哪里!
[加为好友] 回复 引用回复
[Down] [Up]
[3楼] Crystal_oscillat


等级:NO
注册时间:
2011/06/30 15:20
文章: 47
来自: 湖南
离线

while((unsigned char *)0x20)这个相当于unsigned char *p; while(p)

这样当然死循环了,加了volatile也死循环啊,对吧


[加为好友] 回复 引用回复
[Down] [Up]
[4楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

回复【2楼】 yaocp86 :
---------------------------------
volatile 这个我也很少用呢...
当然要学了.
回复【3楼】 Crystal_oscillat :
---------------------------------
是的.



我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
[Down] [Up]
[5楼] 京剧娃娃


等级:NO
注册时间:
2011/07/22 14:48
文章: 6
来自: 哈尔滨
离线

回复【楼主位】 yaocp86 :
---------------------------------
谢谢啦你的详解解决了我的疑惑,楼主对指针的理解好深刻哇


[加为好友] 回复 引用回复
[Down] [Up]
[6楼] 京剧娃娃


等级:NO
注册时间:
2011/07/22 14:48
文章: 6
来自: 哈尔滨
离线

回复【4楼】 正点原子 :
---------------------------------
谢原子大哥的提示,我弄清了这两个 *  的用法了。


[加为好友] 回复 引用回复
[Down] [Up]
[7楼] zhy980

等级:NO
注册时间:
2011/07/07 13:47
文章: 2
离线

学习了,mark


[加为好友] 回复 引用回复
[Down] [Up]
[8楼] chao8828276

等级:NO
注册时间:
2011/08/11 08:48
文章: 32
离线

不顶不行


[加为好友] 回复 引用回复
[Down] [Up]
[9楼] muc520

等级:NO
注册时间:
2011/06/20 21:01
文章: 210
离线

以前一直不懂指针的。mark!


[加为好友] 回复 引用回复
[Down] [Up]
[10楼] SEASON3

等级:NO
注册时间:
2011/08/12 01:59
文章: 61
离线

学习了,谢谢!


[加为好友] 回复 引用回复
[Down] [Up]
[11楼] 苹果

等级:NO
注册时间:
2011/03/23 09:42
文章: 72
离线

学习了·····


[加为好友] 回复 引用回复
[Down] [Up]
[12楼] esteem

等级:NO
注册时间:
2011/07/23 10:12
文章: 48
来自: 河南
离线

我学习不了,看不懂啊。


[加为好友] 回复 引用回复
[Down] [Up]
[13楼] baiydcwy

等级:NO
注册时间:
2011/09/19 15:08
文章: 68
来自: 武汉
离线

回复【楼主位】 yaocp86 :
---------------------------------
请的比较深刻哈,呵呵,学习了,不知道能不能讲一下const这个修饰符呢?我好像理解的不是很清楚哦,平时也没用过,能不能也像上面一样,把const也讲一下,清楚、深刻一点,呵呵。。。。。。


[加为好友] 回复 引用回复
[Down] [Up]
[14楼] 城南小卒

等级:NO
注册时间:
2011/10/21 17:13
文章: 18
离线

太猛了 本来我是这句话看不懂过来学习的 看完发现不懂的更多了


[加为好友] 回复 引用回复
[Down] [Up]
[15楼] Tardis


等级:NO
注册时间:
2011/07/17 14:35
文章: 621
离线

回复【楼主位】 yaocp86 :
---------------------------------

回复【4楼】 正点原子 :
---------------------------------

回复【14楼】 城南小卒 :
---------------------------------
确实,太猛了。
约约的问一下:
*(volatile unsigned char *)0x20这个可不可以理解成这样?
0x20是一个数,那么(volatile unsigned char *)0x20就表示0x20这个地址上所存的一个unsigned char型的数,那么再在前面加*,就代表了0x20这个地址中的数所代表的地址对应的数?也就是,假如0x20中存的是0x80,那么*(volatile unsigned char *)0x20这个是不是就指向0x80这个地址中所存的数了?



Time And Relative Dimension In Space.
[加为好友] 回复 引用回复
[Down] [Up]
[16楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

是的.



我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
[Down] [Up]
[17楼] Tardis


等级:NO
注册时间:
2011/07/17 14:35
文章: 621
离线

太猛了,忽然懂了如何使用指针。



Time And Relative Dimension In Space.
[加为好友] 回复 引用回复
[Down] [Up]
[18楼] Cho

等级:NO
注册时间:
2011/06/17 12:17
文章: 22
离线

剛剛想問, 謝樓主


[加为好友] 回复 引用回复
[Down] [Up]
[19楼] Bigben

等级:NO
注册时间:
2011/12/02 22:33
文章: 5
来自: 湖南
离线

受教了.


[加为好友] 回复 引用回复
[Down] [Up]
[20楼] muc520

等级:NO
注册时间:
2011/06/20 21:01
文章: 210
离线

这个对学FSMC很有帮助


[加为好友] 回复 引用回复
[Down] [Up]
[21楼] 螃蟹爱虫


等级:NO
注册时间:
2011/09/03 00:18
文章: 372
来自: 广东
离线

感謝樓主的分享,說的很通透。讓人讀了一目了然。


[加为好友] 回复 引用回复
[Down] [Up]
[22楼] 提刀上马

等级:NO
注册时间:
2011/08/02 16:15
文章: 91
离线

回复【2楼】 yaocp86 :
---------------------------------
呵呵,顶起~~


[加为好友] 回复 引用回复
[Down] [Up]
[23楼] baiydcwy

等级:NO
注册时间:
2011/09/19 15:08
文章: 68
来自: 武汉
离线

回复【15楼】 Tardis :
---------------------------------
回复【16楼】 正点原子 :
---------------------------------
15楼理解的好像有点问题呃,*(volatile unsigned char *)0x20,在这个式子中,首先把0x20强制转换成为指向一个unsigned char类型的指针,也就是说0x20现在它是一个地址了,然后再在其前面加一个*,这时就是取地址0x20中的数据,假如0x20里面放的是0x80,那么*(volatile unsigned char *)0x20=0x80,而不是指向0x80里面存放的值。


[加为好友] 回复 引用回复
[Down] [Up]
[24楼] 正点原子


等级:NO
注册时间:
2010/12/02 10:41
文章: 8097
来自: 湖南
离线

回复【23楼】 baiydcwy :
---------------------------------
恩,应该你的理解才是对的。



我的淘宝小店:http://shop62103354.taobao.com
[加为好友] 回复 引用回复
[Down] [Up]
[25楼] zenghi


等级:NO
注册时间:
2011/11/02 10:35
文章: 131
离线

非常好,说明的如此通透 。


[加为好友] 回复 引用回复
[Down] [Up]
[26楼] wlkdy

等级:NO
注册时间:
2011/01/16 08:41
文章: 45
离线

拜读了,谢谢LZ


[加为好友] 回复 引用回复
[Down] [Up]
[27楼] zhjr1220

等级:NO
注册时间:
2012/01/30 12:40
文章: 2
离线

不错,学习了


[加为好友] 回复 引用回复
[Down] [Up]
[28楼] victor

等级:NO
注册时间:
2011/04/06 19:37
文章: 17
离线

学习volatile的用法


[加为好友] 回复 引用回复
[Down] [Up]
[29楼] liyucheng987

等级:NO
注册时间:
2012/02/12 21:44
文章: 1
离线

回复【楼主位】 yaocp86 :
---------------------------------
mark!!!


[加为好友] 回复 引用回复
[Down] [Up]
[30楼] Littlebee

等级:NO
注册时间:
2012/01/06 15:04
文章: 3
来自: 江苏 
离线

学习


[加为好友] 回复 引用回复
[Down] [Up]
[31楼] jonathan

等级:NO
注册时间:
2012/02/15 16:13
文章: 6
来自: 北京
离线

学习了...


[加为好友] 回复 引用回复
[Down] [Up]
[32楼] 冰天雪地_兰


等级:NO
注册时间:
2012/02/13 12:11
文章: 19
来自: 北京
离线

MARK


[加为好友] 回复 引用回复
[Down] [Up]
[33楼] trusture


等级:NO
注册时间:
2011/06/11 19:47
文章: 44
来自: 重庆
离线

回复【3楼】 Crystal_oscillat :
---------------------------------
你理解错了,如果加了volatile,则每次都会去读原地址中的数据,而这个数据可能在你不知道的情况下自己发生变化(比如这是IO口的输入寄存器)


[加为好友] 回复 引用回复
[Down] [Up]
[34楼] 10086rainer

等级:NO
注册时间:
2012/03/14 20:22
文章: 37
离线

这帖子,果断顶起,建议加精啊!


[加为好友] 回复 引用回复
[Down] [Up]
[35楼] zhanggenftf

等级:NO
注册时间:
2012/03/29 10:33
文章: 8
离线

好方法、、


[加为好友] 回复 引用回复
 
前往: 

Powered by ALIENTEK工作室 © 粤ICP备12000418号-1