【按键控制LED】需要两个按键两个LED

发布时间 2023-04-09 17:38:15作者: 整点薯条拯救一切

【按键+按键抖动】

按键:常用的输入设备,按下导通,松手断开

按键抖动:按键内部的机械式弹簧片,按下和松手的瞬间会伴有一系列的抖动,最简单的过滤方法是加一段延时,把抖动的时间耗过去。(施密特触发器解决的是信号因电压不稳定导致的问题 而消抖是解决这些是硬件影响的信号不稳定)

KEY1| KEY2(常用) :通过GPIO口(例如PE3)通过K1接地。当按键按下时,PA0被下拉到GND,此时读取PE3口的电压就是低电平。松手时PA0被悬空,且PA0是上拉输入模式,PA0就是高电平。

WK_UP:要求GPIO口(PA0)必须配置成下拉输入的模式。

【原理图】

 

 【模块化编程】

  • 这种驱动代码一般要封装起来,单独放在.C和.h文件里。

 【单纯的灯】套路很固定:(.C里面初始化灯+点灯+灭灯)+(.h里面声明各函数可以被外界调用)+(main函数里面调用点灯+调用灭灯+延时)

 

 【按键】

  • 首先介绍几个读取端口信息的函数
  • uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

    这个函数是用来读取输入数据寄存器某一个端口的输入值的。参数GPIOx和GPIO_Pin用来指定某一个端口。返回值uint8_t代表这个端口的高低电平。

  • uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

    这个函数用来读取整个输入寄存器。参数GPIOx用来指定外设。返回值uint16_t代表端口值(16位数据)

  • uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

    这个函数用来读取输出数据寄存器的某一位。一般用于输出模式下,查看自己输出的是什么。

  • uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

    这个函数用来读取整个输出数据寄存器。

【代码理解】

从main函数读起

 

 

KEY的初始化

 

 

 

  •  开启时钟,选择到GPIO口(的工作模式/的具体端口/的速度)
  • 按键是输入设备,采用【上拉输入】方式。具体表现为默认高电平,按键按下为低电平,再次松手高电平。

LED的初始化

 

 

  • 开启时钟,选择到GPIO口(的工作模式/的具体端口/的速度)
  • 灯是输出设备,采用【推挽输出】方式。具体表现为数据寄存器为1时输出高电平。数据寄存器为0时输出低电平。

回到main函数

 

 

  •  刚刚下载程序到板子上,没有任何操作前,先把KeyNum置0
  • 利用GPIO_ReadInputDataBit检测到PE3(key1)位目前处于低电平,代表按键Ley0被按下。
  • 按键按下瞬间由于内部机械结构可能使波形抖动,这是使用Delay函数延时20毫秒,躲过这一段可能抖动的时间
      • 正常情况:按下按键就松开。松开代表高电平。同样为躲过抖动延时一会儿。最后为KeyNum赋值为1,代表按键Key1被完整按过一次了
      • 异常情况:按下就不松手。如果是异常情况会卡在while这一句,直到松手为止。松开代表高电平。同样为躲过抖动延时一会儿。最后为KeyNum赋值为1,代表按键Key1被完整按过一次了
  • 结论1:若取得KeyNum为1,代表按键Key1被完整按过一次了
  • 结论2同上:若取得KeyNum为2,代表按键Key2被完整按过一次了

看不同KeyNum对应什么操作

 

  • 最终想达到的效果是按键按一次,改变一次灯的状态。所以是将当前LED的状态取反
  • 利用GPIO_ReadOutputDataBit函数读取PB5(LED1)是否处于低电平状态,如果是就取反,如果不是就保持。
  • 同理:用GPIO_ReadOutputDataBit函数读取PE5(LED0)是否处于低电平状态,如果是就取反,如果不是就保持。

还是很简单哒!