STM32MP157实验(三)——按键扫描和中断

2023-05-16

文章目录

  • 按键扫描
    • 设计需求
    • 基础知识
    • 硬件设计
    • STM32CubeIDE设计
      • MX设置
      • 代码设计
    • 实验结果
  • 按键中断
    • 设计需求
    • 基础知识
    • 硬件设计
    • STM32CubeIDE设计
      • MX设置
      • 代码设计
  • 总结


按键扫描

设计需求

通过按键扫描的方式实现,按下KEY_USER1(KEY1)按键,点亮LED_GREEN,再次按下熄灭LED_GREEN;按下KEY_USER2(KEY2)按键,点亮LED_YELLOW,再次按下熄灭LED_YELLOW.

基础知识

前面LED灯是控制GPIO输出,而按键则是读取GPIO电平,从而获知按键是否按下。

按键检测一般有两种:按键扫描(类似于轮询)和按键中断(中断检测)。

按键扫描:是间隔很短时间反复查询GPIO状态,从而的值是否有按键动作,这种方式简单,但是比较耗费资源。按键中断则是通过按键产生中断信号,从而实现按键的检测,这种方式需要使用到中断机制,需要对MCU有一定的了解。后面的按键中断实验将会详细介绍
按键一般占用一个GPIO口,通过检测该GPIO的电平变化得知按键操作,我们查看按键原理图如下
在这里插入图片描述通过原理图我们可以分析出,当按键没有按下的时候,3.3V的VDD通过电阻直接连在我们的GPIO口上(PG2),那么我们的MCU读取到的PG2GPIO口的电平就是高电平。当我们的按键按下,左边电路导通,那么我们的GPIO口的电平就是低电平,MCU读取到的电平就是低电平。

我们常用的按键都是机械触点式按键,机械式按键在按下或释放过程中,由于机械弹性作用的影响,会伴随着机械抖动,如下所示:
在这里插入图片描述
抖动的时长与机械开关特性相关,一般为5ms-10ms。在这个抖动过程中,会产生多次高低电平,所以为了确定电平的稳定性,我们需要截取稳定的电平断,所以我们需要进行按键的消抖。按键消抖可以硬件上处理,即在硬件旁并联电容,吸收抖动的电平。也可以软件处理,即通过延时,避开抖动。

硬件设计

在这里插入图片描述

开发板上有4个按键,其中两个是复位按键和唤醒按键,这次实验不会介绍,后面介绍。另外两个按键就是我们的上面的KEY1和KEY2.KEY1接在了MCU的PG3脚,并且并联了一个C34电容用于硬件的消抖,还并联了一个TVS二极管防静电。同理,KEY2接在了PG2上。

STM32CubeIDE设计

MX设置

在这里插入图片描述注意这里的红绿两个灯也需要配置,就像第一个实验那样

代码设计

driver_led.h

#ifndef DRIVER_LED_H_
#define DRIVER_LED_H_

#include "main.h"
#include "stm32mp1xx_hal.h"

#define  LED_GREEN_ON()      HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET)
#define  LED_GREEN_OFF()	 HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET)

#define  LED_YELLOW_ON()     HAL_GPIO_WritePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin, GPIO_PIN_RESET)
#define  LED_YELLOW_OFF()    HAL_GPIO_WritePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin, GPIO_PIN_SET)

extern void DemoLedInit(void);
extern void LedBlinking(void);
#endif /* DRIVER_LED_H_ */

driver_key.h

#ifndef DRIVER_KEY_H_
#define DRIVER_KEY_H_
#include "driver_led.h"
#include "main.h"
#include "stm32mp1xx_hal.h"
#define PUSH_DOWN  GPIO_PIN_RESET
#define PUSH_UP    GPIO_PIN_SET

#define KEY1_READ   HAL_GPIO_ReadPin(KEY_USER1_GPIO_Port,KEY_USER1_Pin)
#define KEY2_READ	HAL_GPIO_ReadPin(KEY_USER2_GPIO_Port,KEY_USER2_Pin)

extern void Scan_key1(void);
extern void Scan_key2(void);
#endif /* DRIVER_KEY_H_ */

driver_key.c

#include "driver_key.h"
#include <stdbool.h>
static bool key1_flag=false;
static bool key2_flag=false;
void Scan_key1(void){
	if(KEY1_READ==PUSH_DOWN){//如果按键按下
		HAL_Delay(5);//延迟5秒,消抖
		if(KEY1_READ==PUSH_DOWN){
			key1_flag=!key1_flag;
			if(key1_flag){
				LED_GREEN_ON();//改变绿灯的状态
			}else{
				LED_GREEN_OFF();
			}
		}
	}
}

void Scan_key2(void){
	if(KEY2_READ==PUSH_DOWN){
		HAL_Delay(5);
		if(KEY2_READ==PUSH_DOWN){
			key2_flag=!key2_flag;
			if(key2_flag){
				LED_YELLOW_ON();
			}else{
				LED_YELLOW_OFF();
			}
		}
	}
}

main.c

int main(void)
{
  /* USER CODE BEGIN 1 */
	static uint32_t sys_freq=0;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  if(IS_ENGINEERING_BOOT_MODE())
  {
    /* Configure the system clock */
    SystemClock_Config();
  }

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  sys_freq=HAL_RCC_GetSystemCoreClockFreq();
  if(!sys_freq){
	  return -1;
  }

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  Scan_key1();
	  Scan_key2();

  }
  /* USER CODE END 3 */
}

实验结果

按下和松开KEY2,黄灯进行熄灭。同理KEY1

按键中断

设计需求

通过按键中断的方式实现,按下KEY2,点亮黄灯,再次按下,熄灭黄灯。同理按下KEY1,控制绿灯

基础知识

  • 中断的基本概念
    正常情况下,微处理器根据代码内容,按顺序执行指令。执行过程中,如果遇到其他紧急的事件需要处理,则先暂定当前任务,执行紧急事件,待紧急事件处理完后,再恢复到刚才暂定的地方继续执行。这个紧急事件就叫做中断。中断的执行流程如下图
    在这里插入图片描述

  • 中断的分类
    CPU在执行指令时,检测到非法指令,比如除0,地址越界访问等,会产生中断,这种中断属于内部中断,也叫系统异常。由CPU外部设备引起的外部事件,比如GPIO中断,USART中断等,这属于外部中断。
    ARM CM4内核可以支持256个中断(2^8=256,说明是用一个8至少8位的寄存器来表示中断)16个内部中断和240个外部中断。**对于stm32mp157的M4,没有用到CM4内核的所有资源,只是用到了一部分,只有10个内部中断和150个外部中断,总计160个中断。**如下图
    在这里插入图片描述

  • 中断优先级
    M4拥有这么多中断,当这些中断同时发生时,CPU应该怎么来处理呢?因此就有了中断优先级的概念。中断优先级数越小,优先级越高。
    抢占优先级:M4支持嵌套中断,所以当CPU在进行一个中断的时候,如果来了一个优先级更高的中断,CPU就立马取执行优先级更高的中断
    响应优先级:响应优先级就是当优先级相同的中断同时发生,谁的响应优先级更高,就先执行谁,另一个则等待上一个执行完了在被执行。

  • 中断优先级的分组
    在这里插入图片描述这是需要我们根据实际情况进行设计的

  • GPIO的中断
    STM32MP157有PA-PI、PZ共10组GPIO,每组GPIO又有0~15共16个GPIO口。数字编号相同的GPIO(PA0,PB0.PC0…)共享一个中断源。如下图
    在这里插入图片描述

硬件设计

就是按键的原理图,同上面的扫描实验

STM32CubeIDE设计

MX设置

在这里插入图片描述

在这里插入图片描述

代码设计

GPIO_init.c

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOG_CLK_ENABLE();//时钟使能
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);//初始化绿灯

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_YELLOW_GPIO_Port, LED_YELLOW_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pins : KEY_USER3_Pin KEY_USER2_Pin */
  GPIO_InitStruct.Pin = KEY_USER3_Pin|KEY_USER2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;//上升沿触发中断
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

  /*Configure GPIO pin : LED_GREEN_Pin */
  GPIO_InitStruct.Pin = LED_GREEN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(LED_GREEN_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LED_YELLOW_Pin */
  GPIO_InitStruct.Pin = LED_YELLOW_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(LED_YELLOW_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI2_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

  HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);

}

在这里插入图片描述
头文件

/*
 * driver_key_int.h
 *
 *  Created on: Jan 1, 2022
 *      Author: lenovo
 */

#ifndef DRIVER_KEY_INT_H_
#define DRIVER_KEY_INT_H_

#include "main.h"
#include "stm32mp1xx_hal.h"

#define LED_GREEN_ON()      HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_RESET);
#define LED_GREEN_OFF()	  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_10,GPIO_PIN_SET);

#define LED_YELLOW_ON()     HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,GPIO_PIN_RESET);
#define LED_YELLOW_OFF()    HAL_GPIO_WritePin(GPIOG,GPIO_PIN_8,GPIO_PIN_SET);

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin);
#endif /* DRIVER_KEY_INT_H_ */

.c文件

/*
 * driver_key_int.c
 *
 *  Created on: Jan 1, 2022
 *      Author: lenovo
 */

#include "driver_key_int.h"
#include <stdbool.h>
static bool key1_flag=false;
static bool key2_flag=false;

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin){
	switch(GPIO_Pin){
	case KEY_USER1_Pin:
	{
		key1_flag=!key1_flag;
		if(key1_flag){
			LED_GREEN_ON();
		}else{
			LED_GREEN_OFF();
		}
		break;
	}

	case KEY_USER2_Pin:
	{
		key2_flag=!key2_flag;
		if(key2_flag){
			LED_YELLOW_ON();
		}else{
			LED_YELLOW_OFF();
		}
		break;
	}
	break;
	}
}

总结

加油

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32MP157实验(三)——按键扫描和中断 的相关文章

随机推荐

  • APP连接ESP8266——采用AT指令

    1 主要实验设备及器材 1 1一块ESP8266 xff08 如图1 xff09 图 1 ESP8266模块 1 2 一个USB转TTL模块 xff08 如图2 xff09 图 2 USB转TTL模块 2 测试ESP8266模块 2 1连接
  • 【shell】shell字符串分割|文件分割|剪切|截取

    目录 一 字符串分割 1 awk分割 xff08 按位字节 分隔符 通配符分割 xff09 print 按列和字节分割截取 split 按分割符分割截取 按通配符分割 2 利用shell 中 变量 的字符串替换成空格分割 3 设置分隔符 x
  • 【解决】Avoid mutating a prop directly since the value will be overwritten whenever the parent compon...

    完整报错信息 xff1a Vue warn Avoid mutating a prop directly since the value will be overwritten whenever the parent component r
  • MAC安装JD-GUI反编译工具

    JD GUI 是一款反编译工具 本文介绍的是 JD GUI的安装方式 xff0c very easy 首先打开官网 xff1a http java decompiler github io 无法访问的朋友可以私信我要jar包 当然你也可以去
  • 转载:配置darknet_ros实现yolo检测

    来自第三届华南农业大学人工智能协会 xff1a 会长部 麦彦恒出品 配置darknet ros实现yolo检测 M朗拿度的博客 CSDN博客
  • AUTOSAR(一)基本概述

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一 什么是AUTOSAR xff1f 二 为什么要使用AUTOSAR xff1f 三 AUTOSAR版本 一 什
  • 台达PLC与单片机的通讯

    最近由于工作需要用PLC与单片机通讯 xff0c 以此用PLC来控制单片机 xff0c 使单片机作为一个IO扩展模块来使用 这是第一次尝试自己写代码来使两个器件通讯 xff0c 故在此做一下笔记 xff0c 顺便巩固一下在这个过程中所学到的
  • VirtualBox 创建了备份(系统快照),如何恢复备份

    打开软件 xff0c 就进入了以下界面 这里并没有什么备份操作 xff0c 然后我们点开这个位置 点击备份就会到达这个页面 点击自己想要恢复的备份就可以了 xff0c 不过得先要关机
  • 详细讲解算术/范围编码(AC)

    算术编码 xff08 Arithmetic coding xff09 是一种无损数据压缩技术 xff0c 它能够将任意离散的符号串 xff08 如字母 像素值等 xff09 压缩为一个实数区间 xff0c 并可以通过解码还原出原始数据 范围
  • 50家大厂面试万字精华总结,数据库事务深入分析,最全指南

    什么是自旋锁和互斥锁 xff1f 由于CLH锁是一种自旋锁 xff0c 那么我们先来看看自旋锁是什么 xff1f 自旋锁说白了也是一种互斥锁 xff0c 只不过没有抢到锁的线程会一直自旋等待锁的释放 xff0c 处于busy waiting
  • MySQL万字精华总结!你连基础的JVM运行时内存布局都忘了?含面试题+答案

    前言 Netty 是一款基于 Java 的网络编程框架 xff0c 能为应用程序管理复杂的网络编程 多线程处理以及并发 Netty 隐藏了样板和底层代码 xff0c 让业务逻辑保持分离 xff0c 更加易于复用 使用 Netty 可以得到一
  • 【STM32】 AMS1117(稳压)模块

    目录 一 xff1a 介绍 二 xff1a 应用 三 xff1a AMS1117 3 3芯片实物图 四 xff1a 特性 五 xff1a 典型应用 六 xff1a 引脚分配 七 xff1a 可调 固定低压差线性稳压器结构 一 xff1a 介
  • 【网络】连接服务器失败(错误原因:Connection refused)| error 111: (111) Connection refused 原因分析

    服务器拒绝原因 xff1a connect 发起TCP连接请求被拒绝是由于目标服务器上无对应的监听套接字 xff08 IP amp amp PORT xff09 xff08 没有监听 无法创建 监听别的IP 端口 xff09 有几个可能性
  • 【C++软件开发】Linux相关面试题型

    一 xff1a Linux的I O模型介绍以及同步异步阻塞非阻塞的区别 xff08 超级重要 xff09 xff08 IO过程包括两个阶段 xff1a xff08 1 xff09 内核从IO设备读写数据和 xff08 2 xff09 进程从
  • 【C++】 STL详解

    目录 一 xff1a 泛型编程 二 xff1a 什么是STL 三 xff1a STL发展 四 xff1a STL组件 五 xff1a 容器 六 xff1a 类型成员 七 xff1a 适配器 八 xff1a 迭代器 九 xff1a 算法 十
  • 12.STM32freeRTOS---递归互斥信号量

    文章目录 前言一 创建递归互斥信号量二 释放递归互斥信号量三 获取递归互斥信号量四 官方例程总结 前言 递归互斥信号量可以看成是一个特殊的互斥信号量 对于互斥信号量 xff0c 获取了互斥信号量的任务就不能再次获取这个互斥信号量 xff0c
  • toString用法

    toString是定义在java lang Object的方法 xff0c 因此所有类都可以使用toString方法 xff0c 但是 toString方法本身返回的是地址信息而对于String Date File 包装类 等都重写了toS
  • 商医通项目总结

    一 项目概述 简介 尚医通即为网上预约挂号系统 xff0c 网上预约挂号是近年开展的一项便民就医服务 xff0c 旨在缓解看病难 挂号难的就医难题 网上预约挂号全面提供的预约挂号业务从根本上解决了这一就医难题 随时随地轻松挂号 xff0c
  • docker安装以及遇到的问题

    目录 一 docker安装 二 安装中可能碰到的问题 1 WSL 2 installation is incomplete 一 docker安装 docker官网下载 xff1a Docker Desktop Docker xff0c 下载
  • STM32MP157实验(三)——按键扫描和中断

    文章目录 按键扫描设计需求基础知识硬件设计STM32CubeIDE设计MX设置代码设计 实验结果 按键中断设计需求基础知识硬件设计STM32CubeIDE设计MX设置代码设计 总结 按键扫描 设计需求 通过按键扫描的方式实现 xff0c 按