STM32—启用按键

目录

[1 、电路构成及原理图](#1 、电路构成及原理图)

2、编写实现代码

main.c

main.h

key.c

3、代码讲解

[4、 烧录到开发板调试、验证代码](#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 按键,蜂鸣器响起。放开按键时蜂鸣器停止发声。

完美契合!

相关推荐
iCxhust31 分钟前
Keil µVision 调试指南---UART#1 模拟/调试窗口 完全使用教程
stm32·单片机·嵌入式硬件
iCxhust32 分钟前
51单片机引脚 ALE EA PSEN的用途
单片机·嵌入式硬件·51单片机
碎像36 分钟前
51单片机创建项目
单片机·嵌入式硬件·51单片机
木白CPP42 分钟前
MCU 进程内存布局详解(.text, .rodata, .data, .bss, 堆, 栈)
单片机·嵌入式硬件
Lugas Luo1 小时前
车载录像存储性能模拟测试工具设计
linux·嵌入式硬件·测试工具
v132665623681 小时前
BK7258 wifi6音视频soc芯片应用分析
嵌入式硬件·物联网·音视频·iot·wifi6
風清掦1 小时前
【江科大STM32学习笔记-10】I2C通信协议 - 10.2 硬件 I2C 读写MPU6050
笔记·stm32·单片机·嵌入式硬件·学习
ALINX技术博客2 小时前
【黑金云课堂】FPGA技术教程Vitis开发:RTC中断讲解
单片机·嵌入式硬件·fpga开发
进击的小头2 小时前
第10篇:嵌入式芯片中断系统详解:NVIC与硬实时性优化设计
单片机·嵌入式硬件
菠萝地亚狂想曲2 小时前
Zephyr_02,SEM
单片机