在点灯的时候遇到一个问题:

	GPIO_ResetBits(GPIOF,GPIO_Pin_9);  //LED0对应引脚GPIOF.9拉低,亮  等同LED0=0;
	GPIO_SetBits(GPIOF,GPIO_Pin_9);    //LED0对应引脚GPIOF.0拉高,灭  等同LED0=1;

为啥通过GPIO_Pin_9  这个参数就可以设置GPIOF中引脚9的高低电平呢,我找到了GPIO相应的置位和复位函数:

//复位函数 设置IO引脚为低电平,点亮led
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->BSRRH = GPIO_Pin;
}
//置位函数  设置IO引脚为高电平,熄灭led
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
  /* Check the parameters */
  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
  assert_param(IS_GPIO_PIN(GPIO_Pin));

  GPIOx->BSRRL = GPIO_Pin;
}

这两段函数都是先检查传入参数的有效性,然后执行这个代码:

GPIOx->BSRRL = GPIO_Pin;

GPIO_Pin就是传入的参数,在这里其实就是调用函数时候填写的GPIO_Pin_9,那为啥填写这个就可以配置GPIOx->BSRRL寄存器呢,这也不是变量啊,怎么给寄存器GPIOx->BSRRH赋值的呢:

在如下代码位置右击,点击红框处:

就看到这个界面:

原来是通过宏定义啊:

#define GPIO_Pin_9                 ((uint16_t)0x0200)

其实换成16进制,也就是:

#define GPIO_Pin_9                0000 0010 0000 0000

再来看一下BSRR寄存器:

0000 0010 0000 0000正好就是对寄存器的第9位(BS9)写1置位,引脚9输出高电平,这个时候LED熄灭(低电平点亮); 同样,对寄存器的第25位(BR9)写1复位,引脚9输出低电平,这个时候LED点亮。

说明:置位 复位都是操作同一个寄存器,只不过分为低 16 位和高 16 位:

  • 低 16 位(0-15),我们往相应的位写 1,那么对应的 IO 口会输出高电平
  • 高 16 位(16-31)作用刚好相反,对相应的位写 1 会输出低电平
  •  总结:STM32对宏定义的使用较多,写成这样当然也是可以的:

    GPIOx->BSRRL = ((uint16_t)0x0200);

    或者这样:

    GPIOx->BSRRL = 0000 0010 0000 0000

    但是问题就是不那么清晰明了,采用宏定义的方式给这些变量起个名字,这样一眼就可以看出这个是设置哪个引脚的,要不然还得去看手册,查寄存器:

    GPIOx->BSRRL = GPIO_Pin;    //这里的GPIO_Pin 就是传入的参数GPIO_Pin_9

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32宏定义详解与应用

    发表评论