龙空技术网

按键控制LED灯——STM32应用实战

精彩刘昊 780

前言:

此时你们对“stm32控制灯光”大约比较讲究,小伙伴们都需要了解一些“stm32控制灯光”的相关知识。那么小编也在网摘上搜集了一些关于“stm32控制灯光””的相关内容,希望兄弟们能喜欢,咱们快快来学习一下吧!

在我们的日常生活中,使用按键控制电器开关的情况还是非常多的,比如说按键控制LED灯的亮灭,按键控制继电器的吸合,按键控制电机的正反转等操作。同样按键在嵌入式开发也非常的重要,比如说按下KEY1,使LED1点亮,再按下KEY1,LED1熄灭。按键的种类有很多,然而今天我们要研究的是贴片按键的使用,我们今天的实例为:通过KEY1的状态来控制LED的点亮与熄灭。

一 按键的原理

大多数的按键都是这两种连接方式,首先看IO口的默认状态,这两张原理图都是默认IO状态为高电平1,按下时按键与GND短接,所以其为低电平0状态,那么我们就可以通过读取按键的IO电平状态来判断按键是否按下了。

二 硬件平台与IO口详情

我们使用的是洋桃1号核心板来跑这次的例程,其芯片型号为STM32F103C8T6,我们来一起看看它的原理图

LED1连接的IO口为PB0 LED2连接的IO口为PB1

KEY1的IO口为PA0

三 代码实现

初始化LED灯

首先我们在led.h中对LED初始定义

#define LEDPORT GPIOB //IO组#define LED1 GPIO_Pin_0 //定义LED1#define LED2 GPIO_Pin_1 //定义LED2

接下来对LED做初始化函数说明

void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;//构造结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能其所在时钟 GPIO_InitStructure.GPIO_Pin = LED1 | LED2;//定义IO端口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//定义IO端口输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//定义IO端口输出速度GPIO_Init(LEDPORT, &GPIO_InitStructure);//写入其中 }

按键宏定义

#define KEYPORT GPIOA#define KEY1 GPIO_Pin_0 

初始化按键

void KEY_Init(void){ GPIO_InitTypeDef GPIO_InitStructure; //构造结构体  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能其所在时钟  GPIO_InitStructure.GPIO_Pin = KEY1;//定义IO端口  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//定义IO端口模式为上啦输入   GPIO_Init(KEYPORT,&GPIO_InitStructure); }

我们把按键操作分为两个不同的版本:一个为有锁存,另外一个为无锁存。接下来我们来分别解释一下什么是有锁存,什么是无锁存。

比如我们按下按键以后,LED常亮,但是我们想要再次关闭LED灯,那么就再次按一下按键,我们按下第一次按键以后,无论等待多长时间,直到再次按下按键以后才能关闭LED,这种情况我们称为是有锁存,另外一种情况就是无锁存,那么什么是无锁存呢?我们按下按键,LED点亮,松开按键,LED熄灭,这种情况就叫无锁存。

锁存有还是没有并没有孰是孰非,在不同的场合使用不同的程序才是最机智的选择。

接下来我们就分别来讨论两种情况都是如何实现的。

无锁存:按下按键,LED点亮,松开按键,LED熄灭。

我们刚才说我们要通过读取IIO端口的电平来判断按键是否按下,那么我们就要调用GPIO库函数,我们来看看库函数使用手册。

while(1) { if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)) { GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1)); } else { GPIO_WriteBit(LEDPORT,LED1,(BitAction)(0)); } }

通过原理图可知,按键按下的时候MCU读取到的应该是低电平,那么在前面加一个取反的符号,于是按下的时候读取到的电平为0,取反以后得到的为1,于是if条件成立。

那么接着就会执行函数括号里面的内容,GPIO置位函数就会将其位设为1,于是LED接收到高电平,LED被点亮。

如果函数条件不成立,那么就不会执行函数里面的内容。这种代码就是无锁存的情况。

接下来我们再来看看有锁存的情况。

if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ delay_ms(20); if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)) {  GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); }}

我们引入了延时消抖的思想,因为按键是机械开关,所以在按下的时候会产生电平的抖动,这在51单片机中经常使用。我个人认为延时消抖应该是一种思想。

第一步先检查按键是否按下,如果按下了,那么就延时20毫秒,再次判断按键是否按下,确保其不是因为机械抖动造成的误判断。两次判断以后,其结果基本确定,如果按键按下了,就点亮LED灯,然后再加入一个死循环,等待按键被松开。就是通过一个等待按键松开的函数来跳出循环,达到按键锁存的目的。

我是精彩刘昊,一昊科技账号所有人,头条作者。我的文章就到此结束了,创作不易,目前不请求各位打赏,希望各位能点点文章中的广告,也是给我的鼓励,可能是一杯咖啡钱,也足够温暖本人了。我有一壶酒,足以慰风尘。

标签: #stm32控制灯光 #stm32开关控制灯程序