OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 67313|回复: 105

(*(volatile unsigned long *)详解

  [复制链接]
头像被屏蔽

27

主题

61

帖子

2

精华

禁止发言

积分
518
金钱
518
注册时间
2011-1-10
在线时间
4 小时
发表于 2011-6-29 17:11:07 | 显示全部楼层 |阅读模式
(*(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只是个常量,不是指针更不是变量。


签名被屏蔽
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

19

主题

68

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2011-9-19
在线时间
8 小时
发表于 2011-12-6 08:52:47 | 显示全部楼层
回复【16楼】Tardis:
---------------------------------
回复【17楼】正点原子:
---------------------------------
15楼理解的好像有点问题呃,*(volatile unsigned char *)0x20,在这个式子中,首先把0x20强制转换成为指向一个unsigned char类型的指针,也就是说0x20现在它是一个地址了,然后再在其前面加一个*,这时就是取地址0x20中的数据,假如0x20里面放的是0x80,那么*(volatile unsigned char *)0x20=0x80,而不是指向0x80里面存放的值。
回复 支持 2 反对 1

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-6-29 19:59:31 | 显示全部楼层
学习...
回复 支持 反对

使用道具 举报

头像被屏蔽

27

主题

61

帖子

2

精华

禁止发言

积分
518
金钱
518
注册时间
2011-1-10
在线时间
4 小时
 楼主| 发表于 2011-6-30 14:40:22 | 显示全部楼层
。。。原子哥,你来学毛啊,忽悠人^_^
签名被屏蔽
回复 支持 反对

使用道具 举报

21

主题

47

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2011-6-30
在线时间
0 小时
发表于 2011-6-30 16:05:36 | 显示全部楼层
while((unsigned char *)0x20)这个相当于unsigned char *p; while(p)

这样当然死循环了,加了volatile也死循环啊,对吧
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-6-30 18:23:15 | 显示全部楼层
回复【3楼】yaocp86:
---------------------------------
volatile 这个我也很少用呢...
当然要学了.
回复【4楼】Crystal_oscillat:
---------------------------------
是的.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2011-7-22
在线时间
0 小时
发表于 2011-7-22 20:55:58 | 显示全部楼层
回复【楼主位】yaocp86:
---------------------------------
谢谢啦你的详解解决了我的疑惑,楼主对指针的理解好深刻哇
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2011-7-22
在线时间
0 小时
发表于 2011-7-22 20:56:51 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
谢原子大哥的提示,我弄清了这两个 *  的用法了。
回复 支持 反对

使用道具 举报

5

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2011-7-7
在线时间
23 小时
发表于 2011-7-24 15:12:45 | 显示全部楼层
学习了,mark
回复 支持 反对

使用道具 举报

9

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2011-8-11
在线时间
1 小时
发表于 2011-8-28 08:37:41 | 显示全部楼层
不顶不行
回复 支持 反对

使用道具 举报

46

主题

284

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
494
金钱
494
注册时间
2011-6-20
在线时间
0 小时
发表于 2011-8-28 15:18:08 | 显示全部楼层
以前一直不懂指针的。mark!
回复 支持 反对

使用道具 举报

16

主题

83

帖子

0

精华

初级会员

Rank: 2

积分
196
金钱
196
注册时间
2011-8-12
在线时间
6 小时
发表于 2011-8-28 23:07:26 | 显示全部楼层
学习了,谢谢!
回复 支持 反对

使用道具 举报

19

主题

156

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
291
金钱
291
注册时间
2011-3-23
在线时间
5 小时
发表于 2011-8-29 08:22:45 | 显示全部楼层
学习了·····
回复 支持 反对

使用道具 举报

64

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2011-7-23
在线时间
13 小时
发表于 2011-8-31 11:12:21 | 显示全部楼层
我学习不了,看不懂啊。
回复 支持 反对

使用道具 举报

19

主题

68

帖子

0

精华

初级会员

Rank: 2

积分
190
金钱
190
注册时间
2011-9-19
在线时间
8 小时
发表于 2011-10-20 11:25:41 | 显示全部楼层
回复【楼主位】yaocp86:
---------------------------------
请的比较深刻哈,呵呵,学习了,不知道能不能讲一下const这个修饰符呢?我好像理解的不是很清楚哦,平时也没用过,能不能也像上面一样,把const也讲一下,清楚、深刻一点,呵呵。。。。。。
回复 支持 反对

使用道具 举报

9

主题

39

帖子

0

精华

初级会员

Rank: 2

积分
89
金钱
89
注册时间
2011-10-21
在线时间
4 小时
发表于 2011-11-1 17:12:13 | 显示全部楼层
太猛了 本来我是这句话看不懂过来学习的 看完发现不懂的更多了
回复 支持 反对

使用道具 举报

46

主题

1579

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1970
金钱
1970
注册时间
2011-7-17
在线时间
4 小时
发表于 2011-11-1 23:37:48 | 显示全部楼层
回复【楼主位】yaocp86:
---------------------------------

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

回复【15楼】城南小卒:
---------------------------------
确实,太猛了。
约约的问一下:
*(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.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-11-2 00:29:23 | 显示全部楼层
是的.
回复 支持 反对

使用道具 举报

46

主题

1579

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1970
金钱
1970
注册时间
2011-7-17
在线时间
4 小时
发表于 2011-11-2 08:07:36 | 显示全部楼层
太猛了,忽然懂了如何使用指针。
Time?And?Relative?Dimension?In?Space.
回复 支持 反对

使用道具 举报

1

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
142
金钱
142
注册时间
2011-6-17
在线时间
15 小时
发表于 2011-11-2 12:56:47 | 显示全部楼层
剛剛想問, 謝樓主
回复 支持 反对

使用道具 举报

5

主题

43

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2011-12-2
在线时间
0 小时
发表于 2011-12-2 23:22:45 | 显示全部楼层
受教了.
回复 支持 反对

使用道具 举报

46

主题

284

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
494
金钱
494
注册时间
2011-6-20
在线时间
0 小时
发表于 2011-12-2 23:34:17 | 显示全部楼层
这个对学FSMC很有帮助
回复 支持 反对

使用道具 举报

39

主题

597

帖子

2

精华

金牌会员

Rank: 6Rank: 6

积分
2117
金钱
2117
注册时间
2011-9-3
在线时间
122 小时
发表于 2011-12-3 08:57:35 | 显示全部楼层
感謝樓主的分享,說的很通透。讓人讀了一目了然。
回复 支持 反对

使用道具 举报

13

主题

104

帖子

0

精华

初级会员

Rank: 2

积分
179
金钱
179
注册时间
2011-8-2
在线时间
0 小时
发表于 2011-12-3 11:16:06 | 显示全部楼层
回复【3楼】yaocp86:
---------------------------------
呵呵,顶起~~
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-12-6 11:06:06 | 显示全部楼层
回复【24楼】baiydcwy:
---------------------------------
恩,应该你的理解才是对的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

27

主题

274

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
472
金钱
472
注册时间
2011-11-2
在线时间
11 小时
发表于 2011-12-9 12:22:54 | 显示全部楼层
非常好,说明的如此通透 。
回复 支持 反对

使用道具 举报

2

主题

45

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2011-1-16
在线时间
4 小时
发表于 2011-12-11 08:31:45 | 显示全部楼层
拜读了,谢谢LZ
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2012-1-30
在线时间
1 小时
发表于 2012-1-30 12:42:19 | 显示全部楼层
不错,学习了
回复 支持 反对

使用道具 举报

2

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2011-4-6
在线时间
0 小时
发表于 2012-1-31 22:06:44 | 显示全部楼层
学习volatile的用法
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2012-2-12
在线时间
0 小时
发表于 2012-2-12 21:45:35 | 显示全部楼层
回复【楼主位】yaocp86:
---------------------------------
mark!!!
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2012-1-6
在线时间
0 小时
发表于 2012-2-13 10:01:53 | 显示全部楼层
学习
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2012-2-15
在线时间
0 小时
发表于 2012-2-15 17:12:38 | 显示全部楼层
学习了...
回复 支持 反对

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2012-2-13
在线时间
0 小时
发表于 2012-2-16 16:47:43 | 显示全部楼层
MARK
回复 支持 反对

使用道具 举报

9

主题

61

帖子

0

精华

初级会员

Rank: 2

积分
117
金钱
117
注册时间
2011-6-11
在线时间
0 小时
发表于 2012-2-23 09:14:50 | 显示全部楼层
回复【4楼】Crystal_oscillat:
---------------------------------
你理解错了,如果加了volatile,则每次都会去读原地址中的数据,而这个数据可能在你不知道的情况下自己发生变化(比如这是IO口的输入寄存器)
回复 支持 反对

使用道具 举报

10

主题

42

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2012-3-14
在线时间
0 小时
发表于 2012-3-24 17:24:39 | 显示全部楼层
这帖子,果断顶起,建议加精啊!
回复 支持 反对

使用道具 举报

1

主题

22

帖子

1

精华

初级会员

Rank: 2

积分
196
金钱
196
注册时间
2012-3-29
在线时间
0 小时
发表于 2012-4-13 22:29:15 | 显示全部楼层
好方法、、
回复 支持 反对

使用道具 举报

14

主题

164

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1860
金钱
1860
注册时间
2012-5-19
在线时间
286 小时
发表于 2012-8-30 09:16:21 | 显示全部楼层
很好值得学习
回复 支持 反对

使用道具 举报

58

主题

288

帖子

1

精华

高级会员

Rank: 4

积分
814
金钱
814
注册时间
2012-3-29
在线时间
81 小时
发表于 2012-9-1 18:06:22 | 显示全部楼层
楼主讲一下const 吧
回复 支持 反对

使用道具 举报

58

主题

288

帖子

1

精华

高级会员

Rank: 4

积分
814
金钱
814
注册时间
2012-3-29
在线时间
81 小时
发表于 2012-9-1 18:09:51 | 显示全部楼层
回复【25楼】正点原子:
---------------------------------
原子老大加酷吧
回复 支持 反对

使用道具 举报

27

主题

308

帖子

1

精华

高级会员

Rank: 4

积分
774
金钱
774
注册时间
2012-6-19
在线时间
19 小时
发表于 2012-9-2 00:59:27 | 显示全部楼层
写的不错
回复 支持 反对

使用道具 举报

10

主题

66

帖子

0

精华

初级会员

Rank: 2

积分
156
金钱
156
注册时间
2011-1-15
在线时间
5 小时
发表于 2012-10-9 15:54:05 | 显示全部楼层
mark~!
回复 支持 反对

使用道具 举报

8

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2012-10-31
在线时间
0 小时
发表于 2012-10-31 12:10:13 | 显示全部楼层
讲的很好
回复 支持 反对

使用道具 举报

8

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
92
金钱
92
注册时间
2012-10-31
在线时间
0 小时
发表于 2012-10-31 12:12:48 | 显示全部楼层
?????23??? baiydcwy:
---------------------------------
对的     嘿嘿  讨论的很好
回复 支持 反对

使用道具 举报

1

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2012-10-13
在线时间
50 小时
发表于 2012-11-24 16:05:51 | 显示全部楼层
回复【24楼】baiydcwy:
---------------------------------
你的理解是对的,我说原子哥怎么说是额。哈哈!
得之我幸,失只我命!
回复 支持 反对

使用道具 举报

22

主题

436

帖子

0

精华

高级会员

Rank: 4

积分
541
金钱
541
注册时间
2012-8-6
在线时间
2 小时
发表于 2012-11-24 16:42:54 | 显示全部楼层
xuexile 
往事随风!
回复 支持 反对

使用道具 举报

51

主题

214

帖子

0

精华

高级会员

Rank: 4

积分
561
金钱
561
注册时间
2011-4-11
在线时间
43 小时
发表于 2012-12-19 16:15:02 | 显示全部楼层
讲的真好
回复 支持 反对

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2012-9-21
在线时间
2 小时
发表于 2012-12-20 21:01:12 | 显示全部楼层
那么(volatile unsigned char *)0x20是一个固定的指针,是不可变的,不是变量。而char *u则是个指针变量。
再在前面加"*":*(volatile unsigned char *)0x20则变成了变量;


是不是可以这样理解,(volatileunsigned char*)0X20指向的是一个固定的地址,所以是不可变的,但是前面加了"*"后
*(volatile unsigned char *)0x20,指向了这个地址里面的内容,因为加了volatile,这地址的内容可以被硬件来修改,所以加了
"*"后,就成一个变量了。
回复 支持 反对

使用道具 举报

2

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2012-11-1
在线时间
0 小时
发表于 2012-12-23 11:44:22 | 显示全部楼层
看不懂啊看不懂
回复 支持 反对

使用道具 举报

65

主题

440

帖子

0

精华

高级会员

Rank: 4

积分
782
金钱
782
注册时间
2012-8-29
在线时间
17 小时
发表于 2012-12-24 07:46:46 | 显示全部楼层
指针的定义和赋值是不一样的 , unsigned char * a和*a是不一样的    前面是把a初始化成指针变量  其实他只是一个地址值 ,后面的是表示地址a中村的数据,一个是地址一个是数据。
人生永远追逐着幻光,但谁把幻光看作幻光,谁便沉入无边的苦海
回复 支持 反对

使用道具 举报

2

主题

18

帖子

0

精华

新手上路

积分
48
金钱
48
注册时间
2013-3-31
在线时间
0 小时
发表于 2013-3-31 21:33:51 | 显示全部楼层
MARK!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-20 20:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表