STM32学习笔记-按键控制LED灯
文章目录
- 一、原理图分析
- 二、项目代码
-
- 1、按键无锁存main.c
- 2.按钮有锁main.c
- 3、key.c
- 4、key.h
- 三、代码分析
一、原理图分析
k2和k3左端连接PA0、PA1,右端连接GND。说明按下按钮时输出为低电平。
左端连接PA0、PA1使用了A组接口
二、项目代码
按钮无锁main.c
#include "stm32f10x.h" //STM32头文件#include "sys.h"#include "delay.h"#include "led.h"#include "key.h" int main (void){ //主程序 u8 a; //定义变量 ///初始化程序 RCC_Configuration(); ///时钟设置 LED_Init();//LED初始化 KEY_Init();//按键初始化 //主循环 while(1){ /例1:无锁 if(GPIO_ReadInputDataBit(KEYPORT,KEY1)){ ////读取按键接口的电平 GPIO_ResetBits(LEDPORT,LED1); //LED低电平(0) 灯 } else{ GPIO_SetBits(LEDPORT,LED1); //LED高电平(1) 灯 } /例2:无锁存(结果与上例相同) // GPIO_WriteBit(LEDPORT,LED1,(BitAction)(!GPIO_ReadInputDataBit(KEYPORT,KEY1))); }} 2.按钮有锁main.c
#include "stm32f10x.h" //STM32头文件#include "sys.h"#include "delay.h"#include "led.h"#include "key.h" int main (void){
//主程序 u8 a; //定义变量 //初始化程序 RCC_Configuration(); //时钟设置 LED_Init();//LED初始化 KEY_Init();//按键初始化 //主循环 while(1){
//示例3:有锁存 if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
//读按键接口的电平 delay_ms(20); //延时去抖动 if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){
//读按键接口的电平 GPIO_WriteBit(LEDPORT,LED1,(BitAction)(1-GPIO_ReadOutputDataBit(LEDPORT,LED1))); //LED取反 while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开 } }/* //示例4:有锁存(二进制加法) if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 delay_ms(20); //延时20ms去抖动 if(!GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 //在2个LED上显示二进制加法 a++; //变量加1 if(a>3){ //当变量大于3时清0 a=0; } GPIO_Write(LEDPORT,a); //直接数值操作将变量值写入LED(LED在GPIOB组的PB0和PB1上) while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开 } }*/}
3、key.c
#include "key.h"void KEY_Init(void){ //微动开关的接口初始化 GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的初始化枚举结构 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2; //选择端口号(0~15或all) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻 // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(KEYPORT,&GPIO_InitStructure); }
4、key.h
#ifndef __LED_H#define __LED_H #include "sys.h"//#define LED1 PBout(0)// PB0//#define LED2 PBout(1)// PB1 #define LEDPORT GPIOB //定义IO接口#define LED1 GPIO_Pin_0 //定义IO接口#define LED2 GPIO_Pin_1 //定义IO接口void LED_Init(void);//初始化 #endif
三、代码分析
KEY_Init();
此句源于key.c,定义接口的名称:GPIO_InitStructure;选择端号:KEY1和KEY2;定义输入输出模式:GPIO_Mode_IPU(上拉输入);输入模式不需要设置接口速度
void KEY_Init(void){
//微动开关的接口初始化 GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO的初始化枚举结构 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitStructure.GPIO_Pin = KEY1 | KEY2; //选择端口号(0~15或all) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择IO接口工作方式 //上拉电阻 // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz) GPIO_Init(KEYPORT,&GPIO_InitStructure); }
无锁存代码分析:按下点亮,松开熄灭
if(GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 GPIO_ResetBits(LEDPORT,LED1); //LED灯都为低电平(0) }else{ GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1) }
GPIO_ReadInputDataBit()函数:读取指定端口管脚的输出
输入参数1:KEYPORT(GPIOA的宏定义) 输入参数2:KEY1(GPIO_PIn_0的宏定义) 按键松开,GPIO_ReadInputDataBit()函数将会读出高电平1,if语句执行 GPIO_ResetBits()函数:清除指定的数据端口位 LED熄灭 按键按下,else语句执行 GPIO_SetBits()函数 设置指定的数据端口位 LED点亮
输出结果:按键按下,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))); //LED取反 while(!GPIO_ReadInputDataBit(KEYPORT,KEY1)); //等待按键松开 }}
按键按下时GPIO_ReadInputDataBit()读取按键为低电平0,通过“!”取反值1,if语句执行。 delay延时语句在此防止按键抖动造成的按键值读取不稳定。按键在按下时和松开时都会有抖动现象,此时可能识别为低电平也可能识别为高电平,所以加上一个延时语句,等待按键稳定后再次读取按键状态,若还是输出为低电平则表明按键按下。
按键确认按下后执行GPIO_WriteBit()函数,取LED灯当前状态的反值(亮取灭,灭取亮) while()函数,等待按键松开,防止松开时发生的按键抖动导致结果错乱。 输出结果:第一次按下后松开,LED点亮;第二次按下后松开,LED熄灭