一 .
#define KEY0 (GPIOD->IDR&GPIO_Pin_0)
就是一个宏定义,即后面的 KEY0 将全部用后面的这一串代替:“(GPIOD->IDR&GPIO_Pin_0)”
所以使用宏定义后如果编译出错,你又看不出来的话,需要你仔细你的宏定义是否正确定义且被正确地使用。
其中的"->“是表示访问结构指针对应对象下的IDR成员,可以改写为“(*GPIOC).IDR”。
也就是说,如果GPIOD不是一个指针变量,或者不是指向拥有IDR成员的结构对象则编译就会出错;而如果对某个指针进行强制转换后编译成功了并不一定保证执行不会出错。如:
void *ptr=.../*某个结构对象的地址,但该结构没有IDR成员*/;
(struct stru_name_with_IDR*)ptr->IDR=...../*对ptr强制转换以便对其中的IDR成员进行操作*/;
上述两句编译时不会报错,因为使用强制转换,编译器认为你是了解你的目的的,但运行中可能出错,比如ptr指向的对象尺寸不够就会越界,其他的错误取决于IDR的类型等。
二 .
#define WARM_KEY_PIN (GPIOC->IDR&(1<<5))
#define Speak(tmp) GPIOA->ODR=tmp?(GPIOA->ODR|1<<12):(GPIOA->ODR&(~(1<<12)))
(1)IDR是查看引脚电平状态用的寄存器(只读),ODR是引脚电平输出的寄存器。
(2)1<<5表示:1左移5位(0000 0001---->0010 0000)
- ->在C语言中称为间接引用运算符,是二目运算符,优先级同成员运算符“.”。
- 用法:
p->a,其中p是指向一个结构体的指针,a是这个结构体类型的一个成员。表达式p->a引用了指针p指向的结构体的成员a。 - 例如:
struct T
{
int a;
char b;
}s;
struct T* p=&s;
那么,p->a相当于s.a。显然,有个等价写法:(*p).a,和p->a完全等效。