首先在外部中断里有这样一个中断服函数,而且是可以正常工作的。
void EXTI0_IRQHandler(void)
{
delay_ms(10); //消抖
if(WK_UP==1)
{
LED0=!LED0;
LED1=!LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0线路挂起位
}
和这个LED0相关的定义如下,是一个宏定义
#define LED0 PAout(8) // PA8
其它相关宏定义如下:
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
那我的问题来了,LED0是一个宏定义,也不是变量。怎么对一个宏定义取反。最后我们类函数宏展开,那也应该是得到GPIOA_ODR第8个位ODR8 的值为0或者为1,我们可以!0或者!1,也可以#define LED0 0然后!LED0,但是LED0=!LED0就说语法上不通了。小弟不明白,就算#define LED0 PAout(8),最后得到的#define LED0 1难道就可LED0=!LED0了,这个从C语法上来说是说不通的。还是我理解有误???请各位大神指点一下小弟。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#define A 1+1
int a = A * 2;
楼主认为 a 的值是多少?
如果你觉得a是4,那就错了。代码在编译前,会复制 1 + 1 这段文字到 A处,所以真正的代码是
int a = 1 + 1 * 2;
这句代码才是被编译的代码,a的值是3.
还有#include语句包含头文件,在编译前也是把头文件的内容复制出来,粘贴到include语句这个地方。
所以楼主的问题,第一次复制粘贴后是
PAout(8) = !PAout(8)
然后PAout(8)也是宏,再次复制粘贴
BIT_ADDR(GPIOA_ODR_Addr,8) = !BIT_ADDR(GPIOA_ODR_Addr,8)
这个也是宏,继续复制粘贴
MEM_ADDR(BITBAND(GPIOA_ODR_Addr, 8)) = !MEM_ADDR(BITBAND(GPIOA_ODR_Addr, 8))
还是宏,继续复制粘贴
*((volatile unsigned long *)(BITBAND(GPIOA_ODR_Addr, 8))) = ! *((volatile unsigned long *)(BITBAND(GPIOA_ODR_Addr, 8)))
还是宏,继续
*((volatile unsigned long *)(((GPIOA_ODR_Addr& 0xF0000000)+0x2000000+((GPIOA_ODR_Addr&0xFFFFF)<<5)+(8<<2)) )) = ! *((volatile unsigned long *)(((GPIOA_ODR_Addr& 0xF0000000)+0x2000000+((GPIOA_ODR_Addr&0xFFFFF)<<5)+(8<<2)) ))
GPIOA_ODR_Addr应该还是宏,你没贴相关代码,我就不粘贴了。
最后那句长长的句子才是真正的代码,你可以复制那句话放到原来的地方,帮编译器省点力气。
现在明白了吗?
一周热门 更多>