STM32F4学习笔记—GPIO_按键扫描(基于寄存器)
一、硬件原理
1.1原理图分析



通过上面的原理图分析可知,KEY0、1、2连接方式为共阴极,也就是说当GPIO引脚检测到低电平时,说明按键按下;KEY_UP连接为共阳极,同理,当检测到GPIO引脚为高电平时,说明按键按下。
1.2思路分析
1.2.1使能GPIOE和GPIOA的时钟

位 5 GPIOFEN: IO 端口 F 时钟使能 (IO port F clock enable)
由软件置 1 和清零。
0:禁止 IO 端口 F 时钟
1:使能 IO 端口 F 时钟
在手册中可以看到,往这个寄存器写1就是使能,代码就这么写:
// 1.使能GPIO时钟
RCC->AHB1ENR |= 1 << 4; // 使能GPIOE时钟
RCC->AHB1ENR |= 1 << 0; // 使能GPIOA时钟
2.2.2初始化GPIOE和GPIOA
在这个环节里主要注意这几个参数就可以了
1.端口模式寄存器

2.端口上拉/下拉寄存器


代码如下:
// 2.2端口上拉/下拉(00:不拉 01:上拉 10:下拉 11:保留)
GPIOE->PUPDR |= 1 << 8;
GPIOE->PUPDR |= 1 << 6;
GPIOE->PUPDR |= 1 << 4;
GPIOA->PUPDR |= 1 << 1; // 设置为上拉模式(2y+1:2y)->PA0
3.端口输出速度寄存器

代码如下:
// 2.3速度设置
GPIOE->OSPEEDR |= 1 << 9;
GPIOE->OSPEEDR |= 1 << 7;
GPIOE->OSPEEDR |= 1 << 5;
GPIOA->OSPEEDR |= 1 << 1;
二、软件设计
2.1key.c
#include "key.h"
static void gpio_init(void)
{
// 1.使能GPIO时钟
RCC->AHB1ENR |= 1 << 4; // 使能GPIOE时钟
RCC->AHB1ENR |= 1 << 0; // 使能GPIOA时钟
// 2.初始化GPIO
// 2.1端口模式(00:输入 01:通用输出 10:复用功能 11:模拟模式)
GPIOE->MODER &= ~(3 << 8); // 设置为输入模式(2y+1:2y)->PE4
GPIOE->MODER &= ~(3 << 6); // 设置为输入模式(2y+1:2y)->PE3
GPIOE->MODER &= ~(3 << 4); // 设置为输入模式(2y+1:2y)->PE2
GPIOA->MODER &= ~(3 << 0); // 设置为输入模式(2y+1:2y)->PA0
// 2.2端口上拉/下拉(00:不拉 01:上拉 10:下拉 11:保留)
GPIOE->PUPDR |= 1 << 8;
GPIOE->PUPDR |= 1 << 6;
GPIOE->PUPDR |= 1 << 4;
GPIOA->PUPDR |= 1 << 1; // 设置为上拉模式(2y+1:2y)->PA0
// 2.3速度设置
GPIOE->OSPEEDR |= 1 << 9;
GPIOE->OSPEEDR |= 1 << 7;
GPIOE->OSPEEDR |= 1 << 5;
GPIOA->OSPEEDR |= 1 << 1;
}
uint8_t get_keynum(void)
{
uint8_t key_num = 0;
//1.判断PE2
if (!(GPIOE->IDR &= 1 << 2))
{
HAL_Delay(20);
if (!(GPIOE->IDR &= 1 << 2))
key_num = 2;
}
//2.判断PE3
else if (!(GPIOE->IDR &= 1 << 3)){
HAL_Delay(20);
if (!(GPIOE->IDR &= 1 << 3))
key_num = 3;
}
//3.判断PE4
else if (!(GPIOE->IDR &= 1 << 4)){
HAL_Delay(20);
if (!(GPIOE->IDR &= 1 << 4))
key_num = 4;
}
//4.判断PA0
else if(GPIOA->IDR &= 1<<0)
{
HAL_Delay(20);
if(GPIOA->IDR &= 1<<0)
key_num = 1;
}
else
key_num = 0;
return key_num;
}
void key_test()
{
// 1.初始化GPIO
gpio_init();
while(1)
{
// 2.读取按键
if(get_keynum() == 2)
//ds0亮
GPIOF->ODR &= ~(1<<9);
if(get_keynum() == 3)
//ds0灭
GPIOF->ODR |= 1<<9;
}
}
2.2key.h
#ifndef __KEY_H
#define __KEY_H
#include "main.h"
#include "led.h"
void key_test(void);
#endif
2.3main.c
#include "main.h"
#include "key.h"
void SystemClock_Config(void);
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
HAL_Init();
SystemClock_Config();
led_test();
key_test();
while (1)
{
}
}
三、下载验证
代码没问题的话,现象如下:

本文详细介绍了STM32F4的GPIO模块如何用于按键扫描,包括硬件原理图分析、GPIOE和GPIOA时钟的使能与初始化,以及端口模式、上拉/下拉和输出速度设置。软件设计部分展示了C语言代码,包括关键函数如gpio_init和get_keynum的实现。
&spm=1001.2101.3001.5002&articleId=134042663&d=1&t=3&u=40ac5e848e8b46f9ae910b1fd06065cf)
3665

被折叠的 条评论
为什么被折叠?



