Internet of Things | Button experiment---Learn I/O input and interrupt programming | Read I/O input signal | Interrupt programming method | Polling to realize button capture experiment - study notes (13)

Purpose

Understand the working principle and electrical schematic diagram of the escape key

1 Key functions and uses, examples of common keys
2 Working principles of keys
Insert image description here
Insert image description here
3 Circuit representation of keys

Small homework after class:
Please give Baidu the relevant information about the popular touch buttons after class, and consider how to use the CPU of our development board to operate the touch buttons.

Understand the principle of IO input signal reading in STM32F407.
Understand the principle of external interrupt in STM32F407
. Learn to use CMSIS to realize the programming of I/O input signal reading
. Learn to use CMSIS to realize the programming of external interrupt.
Simple learning project transplantation

How to read the input signal of I/O in STM32F407

1 How does STM32F407 configure I/O as input
Insert image description here
Insert image description here
Insert image description here

2 How does STM32F407 read the input signal

8.3.9输入配置
当I/O端口被编程为输入时:
•输出缓冲区被禁用
•施密特触发输入被激活
•上拉和下拉电阻被激活取决于在GPIOx_PUPDR寄存器的配置
•I/O引脚上的数据在每个AHB1时钟周期的输入数据寄存器中采样
•对输入数据寄存器的读访问提供I/O状态
图28显示了I/O端口位的输入配置。

STM32F407 programming method for interrupts

12中断和事件
除非另有规定,本节适用于整个STM32F4xx系列。
12.1嵌套矢量中断控制器(NVIC)
12.1.1 NVIC特性
嵌套的矢量中断控制器NVIC包括以下特性:
•STM32F405xx/07xx和STM32F415xx/17xx的82个可屏蔽中断通道
STM32F42xxx和STM32F43xxx的最多91个可屏蔽中断通道
包括带FPU的Cortex™-M4的16条中断线)
•16个可编程优先级(使用4位中断优先级)
•低延迟异常和中断处理
•电源管理控制
•系统控制寄存器的实现
NVIC和处理器核心接口紧密耦合,从而实现低延迟
中断处理和延迟到达的中断的有效处理。
包括核心异常在内的所有中断都由NVIC管理。了解更多信息
关于异常和NVIC编程,请参见编程手册PM0214。
12.1.2 SysTick校准值寄存器
SysTick校准值固定为18750,它给出了1毫秒的参考时间基础
与SysTick时钟设置为18.75 MHz (HCLK/8,与HCLK设置为150 MHz)。
12.1.3中断和异常向量
STM32F405xx/07xx的矢量表见表62和表62
STM32F415xx/17xx和STM32F42xxx和STM32F43xxx设备。
12.2外部中断/事件控制器(EXTI)
外部中断/事件控制器由多达23个边缘检测器组成,用于生成
事件/中断请求。每条输入线都可以独立配置选择类型
(中断或事件)和相应的触发事件(上升或下降或两者)。每一行也可以独立遮罩。暂挂寄存器维护中断的状态行请求

12.2.1 EXTI的主要特性
EXTI控制器的主要特性如下:
•在每个中断/事件线上独立触发和掩码
•每个中断线的专用状态位
•生成多达23个软件事件/中断请求
•检测脉冲宽度低于APB2时钟周期的外部信号。请参考有关这方面的详细信息,请参阅STM32F4xx数据表的电气特性部分参数。
12.2.3唤醒事件管理
STM32F4xx能够处理外部或内部事件,以唤醒核心(WFE)。
唤醒事件可以通过以下方式生成:
在外设控制寄存器中使能中断,但不在NVIC中使能Cortex™-M4具有FPU系统控制寄存器的SEVONPEND位。当MCU从WFE、外设中断暂挂位和外设NVIC恢复
IRQ通道挂起位(在NVIC中断中清除挂起寄存器)必须是清除。
或在事件模式下配置外部或内部EXTI线路。CPU恢复时从WFE,不需要清除外设中断挂起位或NVIC IRQ通道挂起位作为挂起位对应的事件行未设置。
要使用外接线路作为唤醒事件,请参阅章节12.2.4:功能描述。
12.2.4功能介绍
为了生成中断,应该配置并启用中断线。完成了通过编程的两个触发寄存器与所需的边缘检测和使能
通过在中断掩码寄存器的相应位上写一个“1”来中断请求。
当选择的边缘出现在外部中断线上时,中断请求是生成的。与中断线对应的挂起位也被设置。这个请求是
通过在挂起寄存器中写入' 1 '来重置。
要生成事件,应该配置并启用事件行。这是由编程两个触发寄存器与所需的边缘检测和启用
通过向事件掩码寄存器中相应的位写入' 1 '来发送事件请求。当所选边缘发生在事件线上,则产生事件脉冲。挂起位
没有设置对应的事件行。
中断/事件请求也可以由软件通过在软件中写入' 1 '来生成中断/事件寄存器。
12.2.5外部中断/事件行映射
多达140个gpio (STM32F405xx/07xx和STM32F415xx/17xx), 168个gpio
(STM32F42xxx和STM32F43xxx)连接到16外部中断/事件线
以下方式:
图42 外部中断/事件GPIO映射(STM32F405xx/07xx)和STM32F415xx/17xx)

Insert image description here
Insert image description here

  • Initialize interrupt source
  • Enable interrupt source
  • The implementation of the interrupt handler routine is a Weak statement, which can be rewritten or implemented.

Realize key capture experiment by polling

How to create a new project using an existing project

Copy all the files under the LED project to the directory for detecting buttons through polling in Test 2.1.

Modify the project name to: key_pull_test, and open:
Insert image description here

Modify the root directory name on the project tree to: key_pull_test

Create a new F:\IOT\PRJ\key test 2.1 By polling the \code\drivers\key directory, copy led.c and led.h, and rename them key.c and key.h: View the definitions of defined constants to
Insert image description here
skip Transfer:
Insert image description here
Insert image description here
Add led.c and key.c to keil's drivers directory, which will be used later, and add the path to the header file in option:

Next modify the source code.

Implementation and analysis of key capture code through polling

1 Code process analysis

Write code framework:

//创建及修改说明
//V1.o创建第一个按键检测实验主程序代码﹑通过轮询的方式实现按键的检测


#include "systick.h"
#include "stm32f4xx.h"
#include "led.h"

#define SYS_MAX_CLK 12
#define DELAY_1S    1000

int main(void)
{
	uint16_t key0_press = KEY_UP;
	LED0_Init();//初始化LEDO
    delay_init(SYS_MAX_CLK);//初始化系统时钟
	Key_Init();

	while(1)
	{

		if(KEY_PRESS==Detect_key(KEY0_PIN))//查询按键key0(PE4)的状态
		{
			Led_Ctrl(LED0_PIN_ROW,LED0_PIN,LED_ON); //如果按键按下,点灯
			key0_press = KEY_PRESS;

		}
		delay_ms(200); 	//在延时(200ms)后,如果按键按下标志有效,关灯

		if(key0_press == KEY_PRESS)
		{
			Led_Ctrl(LED0_PIN_ROW,LED0_PIN,LED_OFF);
		}


	}
}

Insert image description here

2 Code implementation

Implement relevant definitions in key.h:

#ifndef __KEY_H
#define __KEY_H

#include "stm32f4xx.h"
#include "systick.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_gpio.h"

#define KEY0_PIN	 GPIO_PIN_4
#define KEY1_PIN	 GPIO_PIN_3
#define KEY2_PIN	 GPIO_PIN_2


#define KEY_PRESS  GPIO_PIN_RESET  //枚举变量,0,低电平
#define KEY_UP 		 GPIO_PIN_SET    //枚举变量,弹起时弱上拉,高电平

void 	   Key_Init(void);//初始化
uint16_t Detect_key(uint16_t key_pin);

#endif

The enumeration variables are defined in stm32f4xx_hal_gpio.h:

#define KEY_PRESS  GPIO_PIN_RESET  //枚举变量,0,低电平
#define KEY_UP 		 GPIO_PIN_SET    //枚举变量,弹起时弱上拉,高电平

Code for key.C:

#include <stdlib.h>
#include "key.h"


void Key_Init(void)
{

	GPIO_InitTypeDef  gpio_info;




	gpio_info.Pin = KEY0_PIN | KEY1_PIN; //KEY0_PIN,KEY1_PIN同时初始化
	gpio_info.Mode = GPIO_MODE_INPUT;    //由定义跳转,改成输入状态
	gpio_info.Speed = GPIO_SPEED_FREQ_MEDIUM; //其他参数采用复位值即可
	gpio_info.Pull =  GPIO_PULLUP;

	__GPIOE_CLK_ENABLE(); //stm32_hal_legacy.h中有:#define __GPIOE_CLK_ENABLE __HAL_RCC_GPIOE_CLK_ENABLE

	HAL_GPIO_Init(GPIOE, &gpio_info);


}

uint16_t Detect_key(uint16_t key_pin)
{
	uint16_t ret = KEY_UP;
	if(KEY_PRESS==HAL_GPIO_ReadPin(GPIOE,key_pin))  //GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
		{
			delay_ms(10);//延时10mS去抖动
			if(KEY_PRESS==HAL_GPIO_ReadPin(GPIOE,key_pin))
				{
					ret = KEY_PRESS;
				}
	  }

		return ret;

}

Code of test.C:

//创建及修改说明
//V1.o创建第一个按键检测实验主程序代码﹑通过轮询的方式实现按键的检测
#include "systick.h"
#include "stm32f4xx.h"
#include "key.h"
#include "led.h"

#define SYS_MAX_CLK 12
#define DELAY_1S    1000

int main(void)
{
	uint16_t key0_press = KEY_UP;
	LED0_Init();//初始化LEDO
  delay_init(SYS_MAX_CLK);//初始化系统时钟
	Key_Init();

	while(1)
	{

		if(KEY_PRESS==Detect_key(KEY0_PIN))//查询按键key0(PE4)的状态
		{
			Led_Ctrl(LED0_PIN_ROW,LED0_PIN,LED_ON); //如果按键按下,点灯
			key0_press = KEY_PRESS;

		}
		delay_ms(200); 	//在延时(200ms)后,如果按键按下标志有效,关灯

		if(key0_press == KEY_PRESS)
		{
			Led_Ctrl(LED0_PIN_ROW,LED0_PIN,LED_OFF);
		}


	}
}

Tips: Download error solution

When the default setting memory size is insufficient, the following error will appear:
Insert image description here
Solution: Adjust the configured memory size:
Insert image description here
Experimental phenomenon: press to turn on the light, let go to turn off the light.

Guess you like

Origin blog.csdn.net/Medlar_CN/article/details/132082791