STN32单片机学习笔记(五)-按键检测
写在前面:本系列内容均为自学笔记,参考资料为野火指南者开发板资料及芯片参考手册等,使用野火指南者开发板进行学习,该系列内容仅用于记录笔记,不做其他用途,笔记的内容可能会存在不准确或者错误等,如有大佬看到错误内容还望能够评论指正,感谢各位。
本节包括前几节的程序,请参考野火开发板资料,里面由更加清晰的教学,野火B站账号:野火官方B站账号链接。
修改记录:
各位在复制程序时注意一下下面的小问题,程序中部分注释是笔者复制程序过来之后才注释的,可能会有所疏漏
1、对bsp_key.c中的注释修改,注释时有一个标点未注释掉;已更改
学习目标
1、检测一个按键,并通过按键控制LED灯的亮灭;
2、检测两个按键,并用按键控制LED灯的亮灭,且两个按键的功能不可以相互影响(本节用的灯与上一节相同,是一个红绿蓝三色混色灯(RGB灯),该灯最多可组合出256中颜色,本节只使用红绿两种颜色)。
电路图
本电路图仅供参考。
一、检测一个按键,并控制LED灯亮灭
由于学习目标二的程序是紧接着目标一的,所以在定义函数及声明时会连带目标二所需要的函数及声明一起定义好;
bsp_key.c中的程序如下:
#include "bsp_key.h"void KEY_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct; //定义变量,方便赋值//初始化GPIOARCC_APB2PeriphClockCmd(KEY1_GPIO_CLK,ENABLE); //打开APB2时钟,GPIOA挂载在APB2GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN; //设置需要用到的管脚,KEY1_GPIO_PIN看.h文件GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置输入模式为浮空输入GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct); //加上&,方便取值 //初始化GPIOA//初始化GPIOCRCC_APB2PeriphClockCmd(KEY2_GPIO_CLK,ENABLE); //打开APB2时钟,GPIOC挂载在APB2GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN; //设置需要用到的管脚,KEY2_GPIO_PIN看.h文件GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置输入模式为浮空输入GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct); //加上&,方便取值 //初始化GPIOC
}uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{//按键检测if(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON) //GPIO状态读取函数{while(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);//松手检测return KEY_ON;}else return KEY_OFF;
}
bsp_key.h中的程序如下:
#ifndef _BSP_KEY_H
#define _BSP_KEY_H#include "stm32f10x.h" //要包含固件库的.h文件#define KEY_ON 1
#define KEY_OFF 0
//按键1的声明
#define KEY1_GPIO_PIN GPIO_Pin_0 //按键1管脚
#define KEY1_GPIO_PORT GPIOA //定义用到的GPIO
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA //定义RCC时钟寄存器
//按键2的声明
#define KEY2_GPIO_PIN GPIO_Pin_13 //按键2管脚
#define KEY2_GPIO_PORT GPIOC //定义用到的GPIO
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC //定义RCC时钟寄存器void KEY_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin);#endif
上述两程序是关于按键的定义,由于是定义按键,在实际操作时,单片机只需要读取按键所在管脚的状态即可,所以对于单片机来说,按键属于输入信号,因此按键管脚要定义为输入模式,而通过电路图可知,按键是由接下拉电阻的,所以设置为浮空输入即可;按键检测函数Key_Scan()中的程序表示当识别按键按下时,将1返回,此时单片机就可以读取到返回值,进而可以通过程序进行控制,反之则返回0,此时将不能进行控制(这是return的用法,本人不是很熟悉,应该是这个意思);另外Key_Scan()函数中的while循环是松手检测用的,当手按下按键,按键端口电平变为1,就会进入该循环,当检测到手松开按键即按键弹起,按键端口电平重新变为0时,将会退出循环并将检测到的值1返回,同理反之,返回0;
bsp_led.c中的程序如下:
//BSP:board support package 板级支持包,仅适用于野火开发板#include "bsp_led.h"void LED_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct; //定义变量,方便赋值RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE); //打开APB2时钟,GPIO挂载在APB2//GPIO_PIN的部分用或将用到的管脚初始化为一个十六进制数据,原本是三个十六进制GPIO_InitStruct.GPIO_Pin = (LED_G_GPIO_PIN|LED_R_GPIO_PIN); //设置需要用到的管脚,LED_G_GPIO_PIN看.h文件GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置输出模式为推挽输出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速率为50MHz,LED_G_GPIO_CLK看.h文件GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct); //加上&,方便取值 //初始化GPIO
}
bsp_led.h中的程序如下:
#ifndef _BSP_LED_H
#define _BSP_LED_H#include "stm32f10x.h" //要包含固件库的.h文件#define LED_G_GPIO_PIN GPIO_Pin_0 //定义绿灯管脚号
#define LED_R_GPIO_PIN GPIO_Pin_5 //定义红灯管脚号
#define LED_G_GPIO_PORT GPIOB //定义用到的GPIO
#define LED_G_GPIO_CLK RCC_APB2Periph_GPIOB //定义RCC时钟寄存器
//下面这个声明是用于将PIN0取反的,“^”为异或符号,同0不同1
#define LED_G_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_G_GPIO_PIN;}
#define LED_R_TOGGLE {LED_G_GPIO_PORT->ODR ^= LED_R_GPIO_PIN;}void LED_GPIO_Config(void); //.c文件中的函数声明#endif /*_BSP_LED_H*/
上述程序主要是对LED灯所在的端口进行初始化定义,配置端口为推挽输出模式
main.c中的程序如下:
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"int main(void)
{// 来到这里的时候,系统的时钟已经被配置成72M。LED_GPIO_Config(); //LED端口初始化KEY_GPIO_Config(); //按键端口初始化while(1){if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON){LED_G_TOGGLE;}}
}
在上述程序中,通过Key_Scan()函数来检测按键状态,当检测到KEY_ON时,此时表示按键已经按下,当按键松开后就会执行LED_G_TOGGLE;程序,该程序在bsp_led.h文件中有定义,当执行该程序时,GPIO_ODR寄存器就会与相关GPIO_Pin的值相异或,我们用到的GPIO_Pin为16位的数值,其中只有1位为1,当ODR寄存器与之相异或时,若相对应位的数值相同,则ODR中相应位的值变为0,反之如果不同,则ODR寄存器相应位变为1,以此来实现对LED灯的控制;
二、检测两个按键,并分别控制1种颜色的灯
这个学习目标我们只改变两个文件的程序,其他按照上面的即可,程序如下:
bsp_led.c中的程序
//BSP:board support package 板级支持包,仅适用于野火开发板#include "bsp_led.h"void LED_GPIO_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct; //定义变量,方便赋值RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK,ENABLE); //打开APB2时钟,GPIO挂载在APB2//GPIO_PIN的部分用或将用到的管脚初始化为一个十六进制数据,原本是三个十六进制GPIO_InitStruct.GPIO_Pin = (LED_G_GPIO_PIN|LED_R_GPIO_PIN); //设置需要用到的管脚,LED_G_GPIO_PIN看.h文件GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //设置输出模式为推挽输出GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //设置输出速率为50MHz,LED_G_GPIO_CLK看.h文件GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct); //加上&,方便取值 //初始化GPIO//由于默认开灯,所以先关闭红灯和绿灯,防止混色//下面这两段程序最好放在初始化函数里,放main主函数灯上电会闪一下GPIO_SetBits(GPIOB,LED_G_GPIO_PIN); GPIO_SetBits(GPIOB,LED_R_GPIO_PIN);
}
这个文件中我们增加了最后两行程序,这两行是为了将灯关闭,由于GPIO_ODR寄存器复位值为0,所以默认GPIO输出0,此时在我们所用的电路中灯会上电点亮,由于我们只有一个灯,为了防止两种灯混色所以先将灯熄灭,当然这两行程序也可以放在主函数中,不过可能会出现上电灯闪一下立即灭的状况;
main.c中的程序如下:
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"int main(void)
{// 来到这里的时候,系统的时钟已经被配置成72M。LED_GPIO_Config(); //GPIO初始化KEY_GPIO_Config();while(1){if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_PIN) == KEY_ON){//按键1,控制绿灯GPIO_SetBits(GPIOB,LED_R_GPIO_PIN);LED_G_TOGGLE;}if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_PIN) == KEY_ON){//按键2,控制红灯GPIO_SetBits(GPIOB,LED_G_GPIO_PIN);LED_R_TOGGLE;}}
}
该程序中需要注意的是当按下其中一个按键的时候会将另一个按键所控制的灯熄灭,使用GPIO_SetBits()函数实现,这是因为如果不熄灭,灯就有可能会混色成其他颜色,这与我们目标颜色不符,所以先将另外一个灯熄灭,再点亮自己控制的灯,就可以稳定实现两个按键控制两个灯的功能,在该程序下,当按下按键1时,将会亮起绿灯,再次按下,绿灯熄灭;同理按下按键2将亮起红灯,再次按下按键2,红灯熄灭;假设先按下按键1,此时绿灯亮起,在这种状态下按下按键2,绿灯将被熄灭,而红灯将被点亮,再次按下按键2,红灯熄灭,当然此时绿灯由于之前的熄灭所以并不会亮起,反之同理。
以上仅作笔记参考,不作教学,感谢观看。
STN32单片机学习笔记(五)-按键检测相关推荐
- STM32学习笔记——(5)按键检测
按键检测 一.按键检测 一.按键检测 如上图所示, 若按键KEY1未按下时检测点为低电平,按下时检测点为高电平. 若按键KEY2/3/4未按下时检测点为高电平,按下时检测点为低电平. 程序如下: /* ...
- 51单片机学习笔记之按键控制一盏小灯
我们今天学习一下单片机的案件,其实和小灯一样,大家不用紧张,简单的很. 首先我们新建个工程,如果有同学忘记了,可以看我之前的博客.下面是链接. https://blog.csdn.net/qq_408 ...
- 单片机学习笔记 —— 导航按键
在ADC模数转换的基础上,我们可以设计一个导航按键案例,通过将模拟电压转化为数字电压,根据数字电压值进行相应的处理. 一.导航按键电路 电流图: 说明:左边有6个电阻,加起来700Ω,当按下/松开 ...
- 单片机学习笔记 —— 按键消抖
按键是我们学习单片机时一个重要的器件,我们在按下按键时,难免会一位手抖动或者接触不稳定,但如果不消抖,按键按下的瞬间将会产生成百上千次按键有效的结果,最终的现象不可预料,所以有必要进行消抖. 一. ...
- 【C51单片机学习笔记--DS1302时钟芯片蜂鸣器I2C总线AT24C02存储器】
C51单片机学习笔记–DS1302时钟芯片&&蜂鸣器&&I2C总线&&AT24C02存储器 文章目录 一.DS1302时钟芯片介绍 二.DS1302时钟 ...
- 51单片机学习笔记-1简介及点灯
51单片机学习笔记 文章目录 51单片机学习笔记 1. 51单片机简介 1.1 安装软件 1.2 单片机简介 2. LED灯 2.1点亮一个LED 2.1.1原理分析 2.1.2 创建工程 2.2LE ...
- stm32正常运行流程图_STM32单片机学习笔记(超详细整理143个问题,学习必看)...
原标题:STM32单片机学习笔记(超详细整理143个问题,学习必看) 1.AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中2>1,意思是APB2接高速设备 2.Stm32f ...
- 【K210】K210学习笔记五——串口通信
[K210]K210学习笔记五--串口通信 前言 K210如何进行串口通信 K210串口配置 K210串口发送相关定义 K210串口接收相关定义 K210串口发送接收测试 完整源码 前言 本人大四学生 ...
- ESP32 单片机学习笔记 - 06 - (以太网)Ethernet转Wifi
ESP32 单片机学习笔记 - 06 - (以太网)Ethernet转Wifi 暂停了半个多月的学习,去调车了.现在课设开始了,赶紧回来把一开始的"以太网"目标学完.但是却发现,好 ...
最新文章
- 修改Windows AD的LDAP查询限制
- (SQuirreL SQL Client 客户端 )使用Apache Phoenix 实现 SQL 操作HBase
- Oracle 备份与还原
- 什么样的文章更容易被编辑推荐?
- 【转】用户空间编写驱动程序
- Python 之 字典(dict)的创建、字典生成式、复制添加更新删除、查询遍历比较等
- 服务器中tomcat内存溢出配置文件修改
- win10文件误删除怎么恢复,不能错过的恢复方法
- 单元一: 全桥驱动电路(驱动MOS/IGBT均适用,附带硬件)
- ant-design vue上传 多文件 、单文件上传
- 22年上半年网络工程师考前知识集锦
- 企信下载的文件在哪里_苹果文件管理在哪里
- MLC转成SLC模式没有想象的那么好
- 深度学习论文-DAnetExFuseDFN
- LeetCode79 Word Search
- 电池管理系统(BMS)-SOC算法
- 微服务化的不同阶段 Kubernetes 的不同玩法
- Ubuntu 16.04-18.04中安装 WPS Office 2016 for Linux(集合篇含字体解决方法)简单好用
- H3C的HPE ProLiant DL380 Gen9 ILO、RAID、OS安装配置
- 【VUE实战问题记录】只能输入自然数,包括0及两位小数