注意,此次代码不涉及中断,不涉及中断,不涉及中断
目录
开始
│
├── 初始化LED(GPIOA Pin1 推挽输出)
├── 初始化按键(GPIOA Pin0 浮空输入)
│
└── 进入无限循环:
│
├── 检测按键是否被按下(KEY_Scan1)
│ ↓
│ 是
│ ↓
└── 翻转LED状态(LED_TOGGLE1)
1.初始化LED
这个就不赘述了,不会的可以看https://blog.csdn.net/a15884871479/article/details/147851781?spm=1001.2014.3001.5501
我们只保留初始化灯的就可以了。
2.初始化按键
初始化按键的代码和初始化LED灯的代码是相类似的
void KEY_Config(void){
// 定义一个 GPIO 结构体
GPIO_InitTypeDef gpio_initstruct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//IO输出状态初始化控制
//选择要控制的GPIO引脚、设置GPIO模式为 浮空输入、设置GPIO速率为50MHz
gpio_initstruct.GPIO_Pin = GPIO_Pin_0;
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpio_initstruct);
}
解释:我这里的电路图是配置的上拉输入,具体按键要具体配置。
3.粗略的延时函数
void Rough_Delay_Ms1(__IO uint32_t time) {
for (uint32_t i = 0; i < 7 * time; i++) {
__NOP();
}
}
- 实现一个粗略的毫秒级延时函数。
- 延时时间由参数
time
决定,乘以7是为了估算大约1ms的延迟(具体取决于系统主频)。 - 使用
__NOP()
指令进行空操作,占用CPU时间达到延时效果。
4.判断引脚电平
int KEY_Scan1(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t key_press_level)
{
if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == key_press_level)
{
Rough_Delay_Ms1(20); // 消抖延时
while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == key_press_level);
Rough_Delay_Ms1(20); // 释放消抖
return 1;
} else {
return 0;
}
}
- 判断指定的按键是否被按下(通过检测电平变化)。
- 包含两次延时(20ms)用于消除按键抖动:
- 第一次延时后再次检查按键状态,确保按键确实被按下。
- 第二次延时用于按键释放后的稳定。
解释:
PIO_ReadInputDataBit(GPIOx, GPIO_Pin)
作用:读取指定 GPIO 引脚的当前输入值。
返回值:
Bit_SET(即 1)表示该引脚为高电平;
Bit_RESET(即 0)表示该引脚为低电平。
5.通过异或反转电平
void LED_TOGGLE1(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
GPIOx->ODR ^= GPIO_Pin;
}
然后就把他们组合起来就可以了
#include "stm32f10x.h"
void Rough_Delay_Ms1(__IO uint32_t time){
for(uint32_t i = 0;i<7*time;i++)
{
__NOP();
}
}
void LED_Config(void){
GPIO_InitTypeDef gpio_initstruct = {0};//初始化gpio结构体
//开启端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //开启端口时钟
//关闭灯
GPIO_SetBits(GPIOA,GPIO_Pin_1);//让端口引脚输出1,使得灯灭
//配置io模式 推挽模式,50m
gpio_initstruct.GPIO_Pin = GPIO_Pin_1;
gpio_initstruct.GPIO_Mode = GPIO_Mode_Out_PP;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpio_initstruct);//配置端口引脚的模式
}
void KEY_Config(void){
// 定义一个 GPIO 结构体
GPIO_InitTypeDef gpio_initstruct = {0};
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//IO输出状态初始化控制
//选择要控制的GPIO引脚、设置GPIO模式为 浮空输入、设置GPIO速率为50MHz
gpio_initstruct.GPIO_Pin = GPIO_Pin_0;
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&gpio_initstruct);
}
int KEY_Scan1(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, uint8_t key_press_level)
{
if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == key_press_level)
{
Rough_Delay_Ms1(20); // 消抖延时
// 再次确认按键是否仍然处于按下状态
while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == key_press_level);
Rough_Delay_Ms1(20); // 释放消抖
return 1;
}
else
{
return 0;
}
}
void LED_TOGGLE1(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
GPIOx->ODR ^= GPIO_Pin;
}
int main(void)
{
LED_Config();
KEY_Config();
while(1)
{
if (KEY_Scan1(GPIOA, GPIO_Pin_0, 1) == 1)
{
LED_TOGGLE1(GPIOA, GPIO_Pin_1);
}
}
}