STM32—启用按键

news2024/11/16 16:30:49

目录

1 、电路构成及原理图 

2、编写实现代码

main.c 

main.h

 key.c

3、代码讲解

4、 烧录到开发板调试、验证代码

5、检验效果


本人使用的是朗峰 STM32F103 系列开发板,此笔记基于这款开发板记录。


1 、电路构成及原理图 

重要!一定先用短路帽短接板上P5的2-3引脚,否则KEY_WKUP按键无效

通过按键原理图我们可以看到,按键 KEY1 和按键 KEY2 的各一端接到了 GND 端低电平端,KEY1 的另一端连接到 STM32 的 PC8 引脚;KEY2 的另一端连接到 STM32 的 PC9 引脚。而 KEY_WKUP 按键的一端接到了 VCC3.3V 高电平端另一端连接到了 STM32 的 PA0 引脚
(WKUP/唤醒)。 

通过原理图可知,当 KEY1 按下时 PC8 会被拉低为低电平,KEY2按下时 PC9 会被拉低为低电平,KEY_WKUP 按下时 PA0 会被拉高为高电平。 我们把 PC8、PC9、PA0 引脚的模式初始为输入模式,那么通过判断 PC8、PC9、PA0 引脚的低、高电平我们就可以知道哪一个按键被按下了。

2、编写实现代码

实现效果:

当按下 KEY1 按键,LED1 亮起。放开按键时 LED1 熄灭。 
当按下 KEY2 按键,LED2 亮起。放开按键时 LED2 熄灭。 
当按下 KEY_WKUP 按键,蜂鸣器响起。放开按键时蜂鸣器停止发声。 

main.c 

#include "main.h"


int main(void)
{
	uint8_t i;
 /*HAL库初始化*/
  HAL_Init(); 
 /*初始化系统时钟频率为72MHz及延时函数初始化*/
  SystemClock_init(RCC_PLL_MUL9);
 /*初始化按键通用输入输出端口*/
  key_Init();
 /*初始化LED通用输入输出端口*/
  Led_Init();
 /*蜂鸣器IO初始化*/
  beep_init();

    while (1)
    {
     i=key_scan();          //检测按键按下情况
			switch(i){            
			case KEY_1_PUSH:      //如果KEY_1按下,LED1(红色)亮起
       LED1_L;
       break;
	  	case KEY_2_PUSH:      //如果KEY_2按下,LED2(绿色)亮起
       LED2_L;
				break;
			case KEY_WKUP_PUSH:   //如果KEY_WKUP按下,蜂鸣器响起
       beep_L;
				break;
      case 0:               //如果没有按键按下LED熄灭蜂鸣器不发声
				LED1_H;
				LED2_H;
				beep_H;
							 }
    }
}

main.h

#ifndef __main_H_
#define __main_H_

#include "stm32f1xx.h"
#include "stm32f1xx_hal.h"
#include "User_Settings.h"
#include "key.h"
#include "led.h"
#include "beep.h"

 key.c


/**
  * @brief   检测按键输入代码
  * @file    key.c
  * @Board   朗峰 STM32 F103RCT6系列开发板  
  */

#include "key.h"

/**
* @brief  初始化按键通用输入输出端口       
* @param  none
* @retval none
*/
void key_Init(void)
{
	GPIO_InitTypeDef GPIO_Init;          //GPIO_Init:GPIO_InitTypeDef结构体类型的变量
                                       //使用GPIO之前必须开启GPIO端口时钟
	__HAL_RCC_GPIOA_CLK_ENABLE();        //开启GPIOA时钟
	__HAL_RCC_GPIOC_CLK_ENABLE();        //开启GPIOC时钟


	GPIO_Init.Pin=GPIO_PIN_0;            //KEY_WUKP引脚PA0
	GPIO_Init.Mode=GPIO_MODE_INPUT;      //模式为输入模式
	GPIO_Init.Pull=GPIO_PULLDOWN;        //激活下拉
	GPIO_Init.Speed=GPIO_SPEED_FREQ_HIGH;//端口速度选择高速
	HAL_GPIO_Init(GPIOA,&GPIO_Init);     //按以上设置初始化引脚PA0

	GPIO_Init.Pin=GPIO_PIN_8|GPIO_PIN_9; //KEY_1引脚PC8,KEY_2引脚PC9
	GPIO_Init.Mode=GPIO_MODE_INPUT;      //模式为输入模式
	GPIO_Init.Pull=GPIO_PULLUP;          //激活上拉
	GPIO_Init.Speed=GPIO_SPEED_FREQ_HIGH;//端口速度选择高速
	HAL_GPIO_Init(GPIOC,&GPIO_Init);     //按以上设置初始化引脚PC8,PC9
}


/**
* @brief  检测按键输入       
* @param  none
* @retval KEY_1按下时返回 KEY_1_PUSH
          KEY_2按下时返回 KEY_2_PUSH
          KEY_WKUP按下时返回 KEY_WKUP_PUSH
          无按键按下时返回0
*/

uint8_t key_scan(void)
{
	delay_ms(15);
	if(KEY_1==0) return KEY_1_PUSH;
		else if(KEY_2==0) return KEY_2_PUSH;
			else if(KEY_WKUP==1) return KEY_WKUP_PUSH;              
				return 0;
							
}

 led.c


/**
  * @brief   led驱动代码
  * @file    led.c
  * @Board   朗峰 STM32 F103RCT6系列开发板  
  */

#include "led.h"

/**
* @brief  初始化LED通用输入输出端口     
* @param  none
* @retval none
*/
void Led_Init(void)
{
	GPIO_InitTypeDef GPIO_Init;             //GPIO_Init:GPIO_InitTypeDef 结构体类型的变量
                                          //使用GPIO之前必须开启GPIO端口时钟
	__HAL_RCC_GPIOB_CLK_ENABLE();           //开启GPIOB时钟
	__HAL_RCC_GPIOC_CLK_ENABLE();           //开启GPIOC时钟

	GPIO_Init.Pin=GPIO_PIN_9; 				      //LED2 IO引脚PB9
	GPIO_Init.Mode=GPIO_MODE_OUTPUT_PP;  	  //输出模式选择推挽输出
	GPIO_Init.Pull=GPIO_PULLUP;            	//激活上拉
	GPIO_Init.Speed=GPIO_SPEED_FREQ_HIGH;   //端口速度选择高速
	HAL_GPIO_Init(GPIOB,&GPIO_Init);        //按以上设置初始化引脚PB9

	GPIO_Init.Pin=GPIO_PIN_6|GPIO_PIN_13; 	//LED1 IO引脚PC6 PC13是LCD屏背光
	HAL_GPIO_Init(GPIOC,&GPIO_Init);
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12|GPIO_PIN_13,GPIO_PIN_RESET);//未使用LCD屏关闭背光以节电

	LED1_H;                                  //LED1置高电平。默认led1不亮起
  LED2_H;                                  //LED2置高电平。默认led2不亮起

}

3、代码讲解

源文件 main.c 只 include “main.h”一个头文件而没有
包含其它外设等的头文件,这样看起来页面很清爽简洁,那其它的头
文件都放在哪里了呐?答案是都放在了 main.h 中,其它地方也可以
这样使用哦。

先看按键的初始化函数 void key_Init(void),这里的第一个void 表示这是个无返回值的函数,第二个在括号的 void 表示这个函数无参数。 
按照流程,依旧是先开启端口 A 和端口 C 的时钟、端口模式为输入模式、速度为高速、其中 PA0 设置为下拉,PC8,PC9 设置为上拉 ,最后按以上设置初始化。 
再接着看检测按键输入函数 uint8_t  key_scan(void),这里的uint8_t 表示函数的类型,void 依旧说明该函数无参。 

 最后回头看一下主 main 函数:按照流程的初始化 HAL 库、设置系统时钟(72Mhz)、初始化按键、初始化 LED、初始化蜂鸣器。 
接下来进入 while()循环,首先就是循环检测是否有按键按下,之后使用了 switch 条件判断语句来判断具体是哪个按键被按下了而且实现对应的控制。 
具 体 看 , 当 被 key_scan() 返 回 值 赋 值 的 变 量 i 满 足 条 件KEY_1_PUSH:即 KEY1 按键被按下了,那就点亮 LED1:LED1_L;这句应该就很熟悉了; 

当 i 满足条件 KEY_2_PUSH:即 KEY2 按键被按下了,  那就点亮LED2:LED2_L; 
当 i 满足条件 KEY_WKUP_PUSH:即 KE_WKUP 按键被按下了,  那就驱动蜂鸣器发声。 
如果三个判断条件都不被满足,也就是没有按键按下那就将LED1、LED2、beep 都置高电平即 LED 不点亮蜂鸣器不发声。

4、 烧录到开发板调试、验证代码

编译一次,编译结果显示 0 错误 0 警告就 OK ,之后再按 将代码下载到开发板。 (具体可参考之前的内容,重复不赘述)

5、检验效果

连接好开发板电源并按下电源开关就可以通过分别按下KEY1,KEY2,KEY_WKUP 按键观察结果是否与代码中设置的结果一致了。 

检验效果:

当按下 KEY1 按键,LED1 亮起。放开按键时 LED1 熄灭。 
当按下 KEY2 按键,LED2 亮起。放开按键时 LED2 熄灭。 
当按下 KEY_WKUP 按键,蜂鸣器响起。放开按键时蜂鸣器停止发声。 


完美契合!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1462976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决Uncaught SyntaxError: Cannot use import statement outside a module(at XXX)报错

报错原因:这个错误通常是因为你正在尝试在一个不支持 ES6 模块语法的环境中使用 import 语句。这可能是因为你的代码是在一个只支持 CommonJS 或 AMD 模块系统的环境中运行的,或者你的代码运行的环境没有正确配置以支持 ES6 模块。如果是在浏览器环境&am…

Predis Multi-Zone

A Data Flow Framework with High Throughput and Low Latency for Permissioned Blockchains 联盟链的吞吐瓶颈由共识层和网络层的数据分发过程共同决定。 Predis 协议利用了共识节点的空闲带宽,提前分发区块中的内容即bundle,减少了共识区块中的内容&…

服务器运维小技巧(三)——如何进行服务器批量管理

运维工程师在进行服务器运维时,往往一个人要同时监控几十甚至成百上千的机器,当机器数量增加时,服务器管理的难度将会大大增加。很多工程师在工作中会使用一些运维面板,比如bt,1panel等,但是这些工具往往一…

力扣 面试题 05.06. 整数转换

思路: 牵扯到二进制数,基本上要考虑位运算符,相关知识可以见http://t.csdnimg.cn/fzts7 之前做过类似的题目,大致思路就是先用按位异或^找出不同位,再用n&(n-1)计算出不同位的个数&#x…

利用Dynamo辅助设置项目浏览器——替换视图名称及子规程

前言 今天的案例,来自群友长不大的唐三岁,他自己也一直在学习Dynamo,同时他希望把自己的学习成果分享出来,本期带来的,就是他自己的研究成果: 视图名称统一替换及视图子规程自动添加 先给大家看一段视频&…

通信入门系列——线性空间理论知识

微信公众号上线,搜索公众号小灰灰的FPGA,关注可获取相关源码,定期更新有关FPGA的项目以及开源项目源码,包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 本节目录 一、线性空间 1、欧几里…

Docker本地部署Rss订阅工具并实现公网远程访问

文章目录 1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 Rsshub是一个开源、简单易用、易于扩展的RSS生成器,它可以为各种内容生成RSS订阅源。 Rsshub借助于开源社…

Android Studio创建项目时gradle下载慢

先停止当前Sync,找到gradle-wrapper.properties文件,将distributionUrl修改为腾讯镜像源: distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-6.5-bin.zip

Java 学习和实践笔记(16):类的理解以及初始值

类,英文名叫class。基本上对应的就是语言里的名词。 比如,房子、人、树、花、汽车等等,这些名词,这些可以定义成类。 以房子为例,作为一个房子,它一定有相应的属性,比如房顶、墙、门、窗等等&…

ElasticSearch DSL查询、排序 、分页的原理及语法

1. DSL查询分类和基本语法 ElasticSearch提供了基于Json的DSL来定义查询,常见的查询类型包括: • 查询所有:查询出所有数据,一般测试用,一般不是查出所有,一次性查询20条。例如 match_all • 全文检索(ful…

『智能遥控新境界』:远程控制APP,高效生活的秘诀!

在这个科技日新月异的时代,我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机,你是否也有遇到过需要远程操作自己某一台手机的场景呢?今天,我要向大家推荐一款神奇的手机远程操作神器,让你可以随时随地…

基于 java springboot+layui仓库管理系统

基于 java springbootlayui仓库管理系统设计和实现 博主介绍:5年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

力扣102 二叉树的层序遍历 Java版本

文章目录 题目描述思路代码 题目描述 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],[…

VsCode编译wxWidgets的HelloWorld

wxWidgets 环境搭建 在wxWidgets 官网下载页面点击Download Windows Binaries选择TDM-GCC 10.3和MinGW-w64 8.1下的头文件和开发包进行下载。这儿我们会用两种 gcc 编译器进行对比,所以下载 2 个种编译器对应的库文件。正常只需根据自己安装的编译器下载对应的 1 种…

Stable Diffusion 模型分享:Indigo Furry mix(人类与野兽的混合)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

再添数十种回归模型!最全机器学习预测全家桶,MATLAB代码,这次千万别再错过了!

截止到本期,一共发了14篇关于机器学习预测全家桶MATLAB代码的文章。算上这一篇,一共15篇!参考文章如下: 1.五花八门的机器学习预测?一篇搞定不行吗?http://mp.weixin.qq.com/s?__bizMzkyNDUwMjc3Mg&m…

UIKit 在 UICollectionView 中拖放交换 Cell 视图的极简实现

概览 UIKit 中的 UICollectionView 视图是我们显示多列集合数据的不二选择,而丰富多彩的交互操作更是我们选择 UICollectionView 视图的另一个重要原因。 如上图所示:我们实现了在 UICollectionView 中拖放交换任意两个 Cell 子视图的功能,这…

JAVAEE初阶 网络编程(十二)

HTTP协议 一. 状态码1.200 OK2. 404 NOT FOUND3.403 forbidden4. 405 Method Not Allowed5. 500 Interval Server Error6.504 Gateway Timeout7.302 Move temporarily 二. 如何构造HTTP请求1.通过第三方工具构造. 二.HTTPS三. 密码学中的重要概念1.明文2.密文3.密钥4.对称加密5…

SpringBoot+MybatisPlus+Mysql实现批量插入万级数据多种方式与耗时对比

场景 若依前后端分离版本地搭建开发环境并运行项目的教程: 若依前后端分离版手把手教你本地搭建环境并运行项目_本地运行若依前后端分离-CSDN博客 若依前后端分离版如何集成的mybatis以及修改集成mybatisplus实现Mybatis增强: https://blog.csdn.net…

“TypeError: utils request jS WEBPACK IMPORTED MODULE O .default is undefined‘报错

写项目时报下列错误,找了半天,结果才发现自己在request.js中少写了一行代码 一定不要少些代码 export default requestrequest.js完整代码 import axios from axios;//创建一个新的axios对象 const request axios.create({baseURL:http://localhost:…