« 上一篇下一篇 »

STM32——带参数的宏定义

在编程的过程中,使用带参数的宏有时会使得程序看起来更加直观、操作也更加方便

如果我要点亮一个LED灯,我可以这样写

LED2_ON;

这样就可以点亮LED2,当然,LED2_ON是一个宏定义,那么它是一个怎样的宏呢?

#define LED2_ON  digitalLo(GPIOF,GPIO_Pin_7)

如上,它由 digitalLo(GPIOF,GPIO_Pin_7) 来替换,而 digitalLo() 为一个带有参数的宏,我们来看它的定义

#define digitalLo(p,i)    {p->BRR = i;}    // 输出低电平

因为预处理器不进行计算,而只进行字符串替换,所以我们调用LED2_ON的结果为

GPIOF->BRR = GPIO_Pin_7;

我们来看下GPIOF定义

#define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)

而GPIOF_BASE定义为

#define GPIOF_BASE            (APB2PERIPH_BASE + 0x1C00)

而APB2PERIPH_BASE定义为

#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)

而PERIPH_BASE定义为

#define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */

所以 APB2PERIPH_BASE = (PERIPH_BASE + 0x10000) = 0x40000000 + 0x10000 = 0x4001 0000

所以 GPIOF_BASE = (APB2PERIPH_BASE + 0x1C00) = 0x4001 0000 + 0x1C00 = 0x4001 1C00

所以 GPIOF = ((GPIO_TypeDef *)GPIOF_BASE) = (GPIO_TypeDef *)0x4001 1C00

 

如上图,由《STM32 Reference Manual》可知,0x4001 1C00为GPIO端口F的起始地址,所以GPIOF为一个结构体指针,并指向GPIO端口F的首地址,而GPIO_TypeDef 结构体的定义在上一篇文章中已经介绍过了,这里不再赘述。

现在我们回到 GPIOF->BRR = GPIO_Pin_7; 这一条代码,再来看下GPIO_Pin_7的定义

#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */

即 GPIOF->BRR = 0x0080

如上图,再参考手册可知,代码执行结果为配置GPIOF的引脚 7 为 0,而硬件原理图里面我们的LED2一端接VCC,一端接PF7脚,把GPIOF引脚7拉低,即使得LED2点亮。

使用带参宏点亮LED2(也可以是其他操作)使得代码很直观,易于操作,当然宏的参数要参照硬件原理图来设定。


原创作品