I encountered a problem when lighting the lamp:
GPIO_ResetBits(GPIOF,GPIO_Pin_9); //LED0对应引脚GPIOF.9拉低,亮 等同LED0=0;
GPIO_SetBits(GPIOF,GPIO_Pin_9); //LED0对应引脚GPIOF.0拉高,灭 等同LED0=1;
Why can the high and low levels of pin 9 in GPIOF be set through the parameter GPIO_Pin_9? I found the corresponding set and reset functions of 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;
}
Both of these functions first check the validity of the parameters passed in, and then execute this code:
GPIOx->BSRRL = GPIO_Pin;
GPIO_Pin is the parameter passed in. Here it is actually GPIO_Pin_9 filled in when calling the function. So why fill in this to configure the GPIOx->BSRRL register? This is not a variable. How to assign a value to the register GPIOx->BSRRH :
Right-click on the following code location and click on the red box:
You will see this interface:
It turns out that it is defined through macro:
#define GPIO_Pin_9 ((uint16_t)0x0200)
In fact, converted to hexadecimal, that is:
#define GPIO_Pin_9 0000 0010 0000 0000
Let’s take a look at the BSRR register :
0000 0010 0000 0000 is exactly to write 1 to the 9th bit of the register (BS9), and pin 9 outputs a high level. At this time, the LED goes out (the low level lights up); similarly, the 25th bit of the register (BR9 ) writes 1 to reset, pin 9 outputs low level, and the LED lights up at this time.
Note : Setting and resetting all operate on the same register, but it is divided into low 16 bits and high 16 bits:
- The lower 16 bits (0-15), we write 1 to the corresponding bit, then the corresponding IO port will output high level
- The upper 16 bits (16-31) have the opposite effect. Writing 1 to the corresponding bit will output a low level.
Summary: STM32 uses macro definitions a lot. It is of course possible to write it like this:
GPIOx->BSRRL = ((uint16_t)0x0200);
Or this:
GPIOx->BSRRL = 0000 0010 0000 0000
But the problem is that it is not so clear. Use macro definitions to name these variables, so that you can see at a glance which pin is set. Otherwise, you have to read the manual and check the register:
GPIOx->BSRRL = GPIO_Pin; // GPIO_Pin here is the incoming parameter GPIO_Pin_9