GPIO input - key detection

 

How does the system detect when a key is pressed?

We indirectly complete the key detection through the on-off state of the LED light. When the button is pressed, the LED light is on, and when the button is pressed again, the LED light is off.

To complete this experiment, we will use the basic input functionality of the GPIO peripheral.

Check the key schematic diagram of the development board, as shown in Figure 3-1.

Figure 3-1

K1 and K2 in the figure are buttons. Taking K1 as an example, when the button is not pressed, its PA0 pin is in the ground state, that is, the low level. When the button is pressed, the pin is connected to the power supply, and the input state is high. So as long as we detect the input level state of the pin corresponding to the button (here is PA0), we can judge whether the button is pressed. This is the principle of key detection.

It is necessary to know that due to the elastic effect of the mechanical button, the button will not be turned on or off stably immediately when the button is pressed, that is, there is button jitter. Under normal circumstances, we need to debounce by software or hardware to get the ideal experimental effect. Software de-jitter, such as through timer delay, ignores the jitter before and after; and hardware de-jitter, such as the charge and discharge delay of capacitors, can be used. This article has been debounced by default.

Directly start the analysis of the programming link.

First, enable the clock of the GPIO port, then initialize the pins of the buttons and LED lights, and finally control the state switching of the LED lights by reading the different level states of the pins. This is the general procedure of this experiment.

 

Enable GPIO port clock

All GPIO peripherals are mounted on the APB2 bus, so the enable register is RCC_APB2ENR, and the firmware function is RCC_APB2PeriphClockCmd (the function of the firmware function is the encapsulation of the RCC_APB2ENR register operation). What we need to enable is the GPIOA clock, so the following API can be called to enable the clock:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 

 

Initialize buttons and LED lights

After enabling the GPIOA clock, the buttons and LED lights are initialized. We need to use the GPIO_Init firmware function (this function implements the encapsulation of the configuration pin mode) to configure the pin as floating input mode. In this step, we can write a function to encapsulate it. The following code:

/**
  * @brief  初始化按键
  * @param  无
  * @retval 无
 */ void Key_GPIO_Config(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选择按键引脚PA0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置引脚模式为浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化按键 } 

Note: When the IO port is in input mode, there is no need to set the output rate.

Similarly, since we need to indirectly complete the key detection through the LED light (here we use the RGB light and use the G-color pin PB0), the above steps also need to be repeated for the PB0 pin of the LED light. The process is the same as The key initialization process is similar, and will not be repeated here. Readers can refer to the key process to complete.

 

Detect key state

Next, it is necessary to determine whether the button is pressed by detecting the level state of the button pin. So how do we get the level state of the pin? Looking at the reference manual, we can see that we can get it by reading the value of the IDR register. And this operation is also encapsulated by the STM32 firmware library, and its function name is GPIO_ReadInputDataBit. Looking at the source code, it is the encapsulation of the IDR register operation, as shown in Figure 3-2 below.

 

Figure 3-2

It will eventually return the level state of the pin, that is, return 1 (high level) and return 0 (low level). In the code, "Bit_RESET" and "Bit_SET" have been defined by enumeration, Bit_RESET=0 (low level), Bit_SET=1 (high level). Finally, we complete the key detection by judging the return value of the function. If the button is pressed, the pin outputs a high level. We also encapsulate the detection process as a function Key_DETECTOR, as follows:

/**
  * @brief  检测按键状态
  * @param  GPIOx:x可以是A, B, C, D, E
  *         GPIO_Pin:对应引脚序号
 * @retval 1(高电平,即按下按键)、0(低电平,即没有按下按键)  */ uint8_t Key_DETECTOR(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){ uint16_t keyState = GPIO_ReadInputDataBit(GPIOx, GPIO_Pin); /* 检测是否按下按键 */ if(keyState){ return 1; }else{ return 0; } } 

Everything is ready, we only owe the east wind, we can finally start writing the main function. In the main function, you need to gradually call the above-mentioned API to complete the experimental function. Go directly to the code:

// 定义控制LED的引脚
#define LED_TOGGLE		          LED_Control(GPIOB, GPIO_Pin_0)
// 使用带参宏输出LED灯的另一种状态
#define LED_Control(GPIOx, GPIO_Pin)      {GPIOx->ODR ^= GPIO_Pin;}

int main(void){ uint8_t SaveStatus = 0; uint8_t State; LED_GPIO_Config(); Key_GPIO_Config(); while(1) { State = Key_DETECTOR(GPIOA, GPIO_Pin_0); if(SaveStatus != State) { if(State == 1) { LED_TOGGLE; } SaveStatus = State; } } } 

So far, our key detection experiment has also been analyzed.

 

 

Transfer from Zhihu.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324517387&siteId=291194637