STM32f103 标准库 零基础学习之按键点灯(不涉及中断)

注意,此次代码不涉及中断,不涉及中断,不涉及中断

目录

1.初始化LED

2.初始化按键

3.粗略的延时函数

4.判断引脚电平

5.通过异或反转电平


复制代码
开始
│
├── 初始化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);
        }
    }
}
相关推荐
希和202713 分钟前
江科大 51 单片机课程笔记:DS1302 实时时钟 + LCD1602 可调电子钟(小白逐行讲解)
笔记·单片机·嵌入式硬件
女神下凡16 分钟前
芯参谋(107):杰理AC_中科蓝讯_开发指南
linux·服务器·网络·单片机·嵌入式硬件
乌暮2 小时前
Spring AOP 与 Spring 事务:用大白话彻底理解原理与实践
java·数据库·spring boot·后端·sql·学习·spring
蒸蒸yyyyzwd7 小时前
从邓明学习的后端笔记
笔记·学习
机器学习之心7 小时前
基于变量相关图与残差学习的 GCN 多变量回归方法——混凝土 28 天抗压强度预测
学习·回归·gcn
Rabitebla19 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
Gary移动存储固件20 小时前
eMMC5.1协议中文学习讲解(6.6.17~6.6.22.4.6)
学习·ufs·emmc·nand·存储固件
一个天蝎座 白勺 程序猿20 小时前
别让收藏夹替你学习:我搭AI知识体系的完整方法,脚本直接拿去用
人工智能·学习·ai·ai学习
楚山之石21 小时前
【Nat Biomed Eng】Connectome 2.0 超高梯度扫描仪:500 mT/m 与 600 T/m/s 把活体人脑微观结构分辨推进到亚微米级
图像处理·学习·数据分析·mri
坤坤子吖1 天前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习