1.前言
上一篇文章已经介绍了如何使用STM32单片机点亮LED灯,实现了STM32的入门,这篇文章介绍将如何使用按键去控制LED灯的亮灭。同样地,我们所使用的硬件设备仍然是STM32RCT6单片机以及ST-link烧录器等基础设备。
2.硬件介绍
单片机原理图
按键介绍
按键就是一种电子开关,按下按钮后开关导通,弹起后开关断开,说白了按键就是用来实现一个电路的通路以及断开操作的开关。
由原理图我们可以看出,按键按下后对应的引脚连接至GND,将对应引脚置于低电平。同时,按键按下后并不是一个稳态的过程,会产生相应的电平波动,我们需要通过延时来进行按键消抖。同时,当按键一直处于按下的状态时,这时我们的灯的亮灭是不能够改变的,否则会产生灯反复亮灭的情况,这里我们就需要对程序进行暂时卡死的操作。
如图为按键按下的电平变化过程:
3.软件介绍
同样地,我们使用Keil v5进行开发,LED灯的部分上一篇博客已经详细介绍,这里将不做赘述。
按键GPIO配置
GPIO模式有推挽输出、开漏输出、浮空输入、上拉输入和下拉输入等。按键和LED灯不同在于LED灯是输出电平去控制灯的亮灭,而按键则作为一个输入去读取电平,从而进行相应的操作。由上述原理图我们可以得知,该按键按下后电平置0,因此在按键弹起(不按下)的时候应当默认设置为高电平,因此我们应当将按键的GPIO引脚设置为上拉输入。如果我们设置了浮空输入,那么可能该引脚的电平在按键按下后会产生相应的浮动,可能会产生较大的电平波动,导致按键按下后相应的指令无法执行。其他的按键GPIO配置同LED灯。
使用的函数
GPIO_ReadInputDataBit(GPIOx,GPIO_Pin);
上面我们已经讲述了按键是一个输入读取电平的过程,而该函数就是读取IO口的引脚电平。第一个参数为读取电平的GPIO口,第二个参数为相应的端口号,使用该函数我们就能得到目标引脚的电平,并对其进行判断。
代码编写
直接上代码!!!
1.Main.c:
main函数中没啥特别的,就是不断判断按键是否按下,并进行相应的LED电平翻转动作。
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "Led.h"
#include "Key.h"
#include "sys.h"
#include "delay.h"
int main(void)
{
LED_Init();//LEDÒý½Å³õʼ»¯
KEY_Init();
while (1)//ÅÜËÀÑ»·
{
if(Key_Scan(KEY0_GPIO,KEY0_GPIO_PIN)==KEY_ON)
LED0_TOGGLE;
if(Key_Scan(KEY1_GPIO,KEY1_GPIO_PIN)==KEY_ON)
LED1_TOGGLE;
}
}
2.key.c
key.c中主要是按键的初始化配置,按键扫描函数以及Delay函数的定义。这里我们通过判断按键按下后进行软件延时的方法进行消抖,同时按键按下后若未弹起,程序将进入while死循环,只有当按键松开后才会进行相应的动作。这里我们宏定义了一个KEY_ON,代表按键按下。
#include <Key.h>
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "sys.h"
#include "led.h"
void Delay(uint32_t time)
{
uint32_t i,j;
for(i=0;i<time;++i)
{
for(j=0;j<1000;++j)
{
}
}
}
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(KEY0_RCC_CLOCK , ENABLE);
GPIO_InitStructure.GPIO_Pin = KEY0_GPIO_PIN ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY0_GPIO , &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(KEY1_RCC_CLOCK, ENABLE);
GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(KEY1_GPIO , &GPIO_InitStructure);
}
u8 Key_Scan(GPIO_TypeDef*GPIOx,u16 GPIO_Pin)
{
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON)
{
Delay(Delay_time);
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON)
{
while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==KEY_ON);
}
return KEY_ON;
}
}
3.key.h
key.h中主要是按键引脚以及按键函数的定义,如下:
#ifndef __KEY_H
#define __KEY_H
#include <stm32f10x.h>
#define KEY0_RCC_CLOCK RCC_APB2Periph_GPIOC
#define KEY0_GPIO_PIN GPIO_Pin_12
#define KEY0_GPIO GPIOC
#define KEY1_RCC_CLOCK RCC_APB2Periph_GPIOD
#define KEY1_GPIO_PIN GPIO_Pin_2
#define KEY1_GPIO GPIOD
#define KEY_ON 0
#define KEY_OFF 1
#define Delay_time 2000
void KEY_Init(void);//IO³õʼ»¯
u8 Key_Scan(GPIO_TypeDef*GPIOx,u16 GPIO_Pin);
#endif
4.实验效果
按键控制两个LED灯的亮灭
5.结束语
本次实验讲解了按键控制LED灯的亮灭,这也是STM32单片机比较入门的一部分内容,希望以上内容对各位朋友有所帮助。未来还有很长一段路要走,我们继续前进。
欢迎大家在评论区留言批评指正。谢谢!