打印

这几个C语句什么意思呢?

[复制链接]
3086|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liulwn|  楼主 | 2008-2-28 21:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
看atmel了的例子程序的头文件看得不明白,请教下大侠:

#define AT91C_BASE_PIOA      (AT91_CAST(AT91PS_PIO)  0xFFFFF400)

#define AT91C_PIO_PA0        (1 <<  0)

#define PIO_PER         (AT91_CAST(AT91_REG *)  0x00000000)


它们是怎么个用法?

相关帖子

沙发
后学| | 2008-2-28 22:22 | 只看该作者

re

参照具体程序啊,

define你就当作替换得了,

使用特权

评论回复
板凳
HWM| | 2008-2-29 08:12 | 只看该作者

“#define”-定义,为了方便给后面的内容起个名。

就象LZ你自己也有一个名字一样,老师或老板点起名来方便。

使用特权

评论回复
地板
liulwn|  楼主 | 2008-2-29 09:50 | 只看该作者

看起来难懂

#define 语句在C51里定义都比较简单,如:sbit  P1_0 = P1^0;#define PLAY_1 P1_0 这样直接PLAY_1=0;就可以使用了。但在IAR ARM的C里用AT91C_PIO_PA0=0;这样的语句编译会报错,好象这样的定义还涉及到结构呀,指针呀什么的,实在看不明白。那位大侠能给指点下?    

使用特权

评论回复
5
ashowww| | 2008-2-29 10:38 | 只看该作者

其实你看不懂 的应该是后面的东西:

其实你看不懂 的应该是后面的东西:
(AT91_REG *)  0x00000000 强制类型转换,其实在这里AT91_REG应该也是u32的类型
(AT91PS_PIO)  0xFFFFF400 强制类型转把0xFFFFF400换成一个指向io的结构体指针
AT91_CAST这个没看之前在哪里定义,所以我也不知道.
(1 <<  0) 这种类型一般做位操作的多,<<这符号后面的数字多少就是操作第几位的.

使用特权

评论回复
6
liulwn|  楼主 | 2008-2-29 11:50 | 只看该作者

如ashowww说的确实是后面看不懂

如ashowww说的确实是后面看不懂,把头文件上传,大侠们给简单说下用法,让我等菜鸟学习下。
相关链接:https://bbs.21ic.com/upfiles/img/20082/2008229114943645.rar

使用特权

评论回复
7
wangharry| | 2008-2-29 14:52 | 只看该作者

你还是学好C语言先

使用特权

评论回复
8
Ice_River| | 2008-2-29 16:08 | 只看该作者

5楼说的很详细了

如果复杂不明白的话可以适当扩展成函数 就明白了!

使用特权

评论回复
9
liulwn|  楼主 | 2008-2-29 16:35 | 只看该作者

ARM的C好复杂

ARM的C好复杂,语句#define AT91C_PIO_PA0        (1 <<  0) 是否和#define AT91C_PIO_PA0        1  是样的?

使用特权

评论回复
10
dld2| | 2008-2-29 16:40 | 只看该作者

和ARM有啥关系

这是C语言中基本的位运算啊。
C语言在嵌入式应用中经常这么写。

使用特权

评论回复
11
huangbingg| | 2008-2-29 22:21 | 只看该作者

复习下C先!

楼主要复习下C先!  都是基本语句.

使用特权

评论回复
12
xhtxzxw| | 2008-3-1 20:50 | 只看该作者

嘿嘿

关于:“
#define AT91C_BASE_PIOA      (AT91_CAST(AT91PS_PIO)  0xFFFFF400)
#define AT91C_PIO_PA0        (1 <<  0)
#define PIO_PER         (AT91_CAST(AT91_REG *)  0x00000000)
”的说明,比较多的废话,幸运的是不费吐沫(费爪子,嘿嘿)

这些都是符号定义,目的是为了以后用“符号”而不是“具体的地址”来使用ARM的内部资源(这些内部资源当然都是有地址的寄存器啦!)

比如#define AT91C_BASE_PIOA      (AT91_CAST(AT91PS_PIO)  0xFFFFF400)这一句,以后当你要使用通用IO端口A的相关寄存器时,使用AT91C_BASE_PIOA这个符号就可以了,就不必使用从0xFFFFF400开始的一系列地址了。

注意使用通用IO端口时,涉及到的寄存器可不仅仅是端口本身的一个地址,而是好几个地址,比如:输出/输入设置寄存器,输出0寄存器,输出1寄存器,中断许可寄存器,中断禁止寄存器,中断屏蔽寄存器,.....,等等等等。所以要使用的不止0xFFFFF400这一个地址,而是一组连续的地址,于是,把这些连续的地址对应的、功能上相关的(都与端口A相关)寄存器组合到一个结构里,用指针AT91PS_PIO指向这个结构,你可以看看AT91PS_PIO是不是就是这么定义的。
以后要使用端口A,一般来说,你必须首先按手册的说明,设置这个结构里的某一个或某几个的寄存器的值(初始化),然后才可以使用它。

基本的使用形式是:AT91C_BASE_PIOA->XXXX = YYYY;

例如:
AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA0;//设置端口A的最低位为输出状态,PIO_OER是端口A的输出能寄存器。
AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA0;//端口A的最低位输出高电平,PIO_SODR是端口A的置1寄存器,如果要使最低位输出0,就必须使用寄存器PIO_CODR,即端口A的清0寄存器。

AT91C_PIO_PA0也是一个符号定义,说穿了就是1。“#define AT91C_PIO_PA0   (1 <<  0)”这个定义看起来似乎有点怪怪的感觉,但因为端口A可能是32位的,对每一位都有类似的定义:
AT91C_PIO_PA0     (1 <<  0)
AT91C_PIO_PA1     (1 <<  1)
AT91C_PIO_PA2     (1 <<  2)
AT91C_PIO_PA3     (1 <<  3)
....

AT91C_PIO_PA30    (1 << 30)
AT91C_PIO_PA31    (1 << 31)

假定你要使用端口A的B0~B3位以及B17~B19位为输出,并且让B0=1,B1=0,B2=0,B3=1,B17=0,B18=0,B19=1,就可以这样写代码:

AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA0 | AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA3 | AT91C_PIO_PA17 | AT91C_PIO_PA18 | AT91C_PIO_PA19;//初始化时设置端口A的B0,B1,B2,B3,B17,B18,B19位为输出状态。
.....
AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA0 | AT91C_PIO_PA3 | AT91C_PIO_PA19;//端口A的B0,B3,B19位输出高电平
AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA1 | AT91C_PIO_PA2 | AT91C_PIO_PA17 | AT91C_PIO_PA18;//端口A的B1,B2,B17,B18位输出低电平

由于有了前面的符号定义,就一个地址也看不见了,全用的符号。

端口做通用输入/输出,是端口的最简单应用,如果要使用端口的第二功能或者要启动端口的中断,需要的设置当然会更复杂一些,建议找对应的样例代码仔细看看,就没什么问题了。




使用特权

评论回复
13
tubie| | 2008-3-1 22:26 | 只看该作者

<<0就是增加程序的可读性吧。

使用特权

评论回复
14
xhtxzxw| | 2008-3-1 22:48 | 只看该作者

嘿嘿

代码看起来就整齐了!

使用特权

评论回复
15
huangbingg| | 2008-3-2 10:30 | 只看该作者

呵呵

12楼真是好人..

使用特权

评论回复
16
liulwn|  楼主 | 2008-3-2 20:53 | 只看该作者

谢谢xhtxzxw了!!!

你详细的解释明白多了!!!!

使用特权

评论回复
17
bxb_lhj| | 2008-3-3 17:26 | 只看该作者

luohuo

luoguo

使用特权

评论回复
18
mcizhy| | 2008-3-10 10:47 | 只看该作者

12楼收不收徒,报酬可议。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

156

帖子

3

粉丝