社区
单片机/工控
帖子详情
*(volatile unsigned short *)0x20000000背后的意义是啥?
dahuatttt
2008-06-06 04:08:23
加精
从8*8LED点阵灯程序中看到的。
...全文
4115
30
打赏
收藏
*(volatile unsigned short *)0x20000000背后的意义是啥?
从8*8LED点阵灯程序中看到的。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
30 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
jdygrdzh
2012-02-04
打赏
举报
回复
再补充一点,volatile只是告诉编译器不要优化对这个地址的读写,以便能够直接访问这个地址所对应的硬件寄存器.但是实际上,编译器并不知道这个地址是内存中的还是在内存映射的寄存器里的,硬件对他的操作还是可能经过缓存cache,这样就不能达到直接访问硬件的目的.
解决方法是,处理器会有一个判断逻辑,看目的地址是不是可被缓存的.如果是内存地址当然可以,如果是硬件内存映射那不使用缓冲.这个对软件是透明的.
Robert_NORM
2011-10-28
打赏
举报
回复
前阵子,这个问题困扰我很久,隐隐约约的理解!看了文章之后受益匪浅、、、
谢谢~~~~~~
guangbiao_w
2011-06-03
打赏
举报
回复
已阅。
JimsdogV1
2011-04-26
打赏
举报
回复
volatile表示异变不固定的 每次用的时候都会重新加载值
csong220800227
2011-04-15
打赏
举报
回复
收益良多啊
dong20072
2010-05-10
打赏
举报
回复
楼上太cool了
zhihui525
2009-09-27
打赏
举报
回复
第一条编译的话应该会出错,你可以去试试看,楼上的 shuiyan 同志已经讲的很清楚了,楼主慢慢理解
一定要加*的,就像你定义变量
unsigned int *aa; //定义一个指针变量
aa=0x54; //表示这个指针变量的值为0x54
*aa=0x55; //表示对以aa的值为地址的值进行赋值,也就是内存中0x00000054里的值置为0x55;
*(unsigned int *)0x54=0x55 也是一样的道理
但是 (unsigned int *)0x54=0x55 是不行的,编译器会认为是类似 0x54=0x55的赋值,那当然会出错的
[/Quote]
这个说得好……说到点子上了
gooogleman
2009-07-24
打赏
举报
回复
[Quote=引用 22 楼 jchqxl 的回复:]
地址强制转换成指针
[/Quote]
指针就是地址啊,不用什么强制转换,只是强制转换某类型而已!
jchqxl
2009-07-09
打赏
举报
回复
地址强制转换成指针
dahuatttt
2008-06-16
打赏
举报
回复
0x20000000是真实的绝对地址么?不是mmu转换以后的地址?
用户 昵称
2008-06-16
打赏
举报
回复
你涉及的都是逻辑地址,有的设备只有几K的地址也能映射到2M以上。
ly_liuyang
2008-06-12
打赏
举报
回复
直接向IO Map操作
yangchao_cy
2008-06-12
打赏
举报
回复
绝对地址
fycom200
2008-06-11
打赏
举报
回复
volatile 是多余的,删掉它,然后应该就明白了吧
sherlock_lai
2008-06-11
打赏
举报
回复
[Quote=引用 6 楼 dahuatttt 的回复:]
"控制该显示模块的I/O地址为0x20000000"
既然如此,那就应该是(volatile unsigned short *)0x20000000=XXX 啊。
可为什么写成*(volatile unsigned short *)0x20000000=XXX 才行呢?
ARM9-2410的板子
[/Quote]
0x20000000=XXX 怎么行?
0x1=0x2 这行么? 这些都是确切的值,当然不能划等号
又不是汇编里的 mov 0x01,0x02
sherlock_lai
2008-06-11
打赏
举报
回复
[Quote=引用 10 楼 dahuatttt 的回复:]
1 (volatile unsigned short *)0x20000000=XXX
2 *(volatile unsigned short *)0x20000000=XXX
可是2在语义上应该是XXX存放在0x20000000内值所指向的地址里啊。和1是不同的地址啊!
还是不明白。。。
[/Quote]
第一条编译的话应该会出错,你可以去试试看,楼上的 shuiyan 同志已经讲的很清楚了,楼主慢慢理解
一定要加*的,就像你定义变量
unsigned int *aa; //定义一个指针变量
aa=0x54; //表示这个指针变量的值为0x54
*aa=0x55; //表示对以aa的值为地址的值进行赋值,也就是内存中0x00000054里的值置为0x55;
*(unsigned int *)0x54=0x55 也是一样的道理
但是 (unsigned int *)0x54=0x55 是不行的,编译器会认为是类似 0x54=0x55的赋值,那当然会出错的
dahuatttt
2008-06-11
打赏
举报
回复
谢谢各位的回答,终于搞清楚了!也谢谢wjlsmail,可惜揭帖早了,没给加上分。
wjlsmail
2008-06-11
打赏
举报
回复
(volatile unsigned short *)0x20000000=XXX
*(volatile unsigned short *)0x20000000=XXX
类似:
unsigned short * pus = 0x20000000;
pus = xxx; // 改变 pus 的指向,即pus这个地址变量的值改变为xxx
*pus = yyy; // pus所指向的地址空间,保存 yyy 值。
shuiyan
2008-06-11
打赏
举报
回复
[Quote=引用 10 楼 dahuatttt 的回复:]
1 (volatile unsigned short *)0x20000000=XXX
2 *(volatile unsigned short *)0x20000000=XXX
可是2在语义上应该是XXX存放在0x20000000内值所指向的地址里啊。和1是不同的地址啊!
还是不明白。。。
[/Quote]
2在语义上是:有一个指针指向地址0x20000000,这个地址(0x20000000)中存放的值是xxx。
注意,在这里0x20000000已经是一个确定的地址值了,而不是变量。
如果在C语言里这么写:
unsigned int value = 100;
unsigned int* pt = &value;
那么你肯定能理解pt是一个指针,指向value这个变量的地址。
那么如果这么写呢:
unsigned int* pt;
pt = 0x20000000;
*pt = xxx;
能理解吗? pt是一直指针,指向一个地址,这个地址是固定的0x20000000,而这个地址上存放的值是一个int型数xxx。
shuiyan
2008-06-10
打赏
举报
回复
[Quote=引用 6 楼 dahuatttt 的回复:]
"控制该显示模块的I/O地址为0x20000000"
既然如此,那就应该是(volatile unsigned short *)0x20000000=XXX 啊。
可为什么写成*(volatile unsigned short *)0x20000000=XXX 才行呢?
ARM9-2410的板子
[/Quote]
向一个地址赋值,当然是要在前面加*的,这是C的基本。
如果不加*,那就是在0x20000000这个地址存放了一个xxx,这个xxx也是一个地址,而不是一个你希望的变量值。
加载更多回复(9)
(*(
volatile
unsigned
long *)详解
(*(
volatile
unsigned
long *)详解
(*((
volatile
unsigned
short
*) 0x83200000))
#define S6D0129_IR (*((
volatile
unsigned
short
*) 0x83200000))
volatile
表示 禁止编译器优化
unsigned
short
* 的意思是定义一个2个字节的地址指针 连起来就是在0x82300000地址位置上输出一个2个字节长的数据。在0x82300000地址TFT的IR信号。 *(
volatile
unsigned
*(
volatile
unsigned
short
int *)(0x60020000)=val; 的解析
*(
volatile
unsigned
short
int *)(0x60020000)=val; 0x60020000 地址值,你想象成内存地址好了,这是一串数字 (
volatile
unsigned
short
int )(0x60020000) 将数字强制转换为地址指针类型,也就是经过这样一转换, 0x60020000 就指向某一块内存位置了,第二个就简单了,就是把val 赋值存储到0x60...
一个表达式 *(
volatile
unsigned
short
int *)(0x60020000)=val; 的解析
*(
volatile
unsigned
short
int *)(0x60020000)=val; 0x60020000 地址值,你想象成内存地址好了,这是一串数字 (
volatile
unsigned
short
int *)(0x60020000) 将数字强制转换为地址指针类型,也就是经过这样一转换, 0x60020000 就指向某一块内存位置了,第二个*就简单了,就是把val 赋值存
C 指针
代码中直接访问寄存器: *(
volatile
unsigned
short
*)的含义 *(
volatile
unsigned
short
*)
0x20000000
的
意义
volatile
表示 禁止编译器优化.
unsigned
short
* 的意思是定义一个2个字节的地址指针, 连起来就是在
0x20000000
地址位置上输出一个2个字节长的数据。 ( unsig
单片机/工控
27,374
社区成员
28,770
社区内容
发帖
与我相关
我的任务
单片机/工控
硬件/嵌入开发 单片机/工控
复制链接
扫一扫
分享
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章