【STM32】按键控制LED亮灭实验——GPIO、LED、KEY、SYS

该实验介绍了如何使用STM32微控制器实现LED的无锁存和锁存控制。在无锁存模式下,按下按键LED亮,松开则灭;在锁存模式下,按键按下的状态下LED亮,直到再次按下才熄灭。实验涉及RCC配置、LED及按键初始化,以及利用GPIO读写和延迟函数实现功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

按键控制LED亮灭实验

实验目的

无锁存时:当按下独立按钮时LED亮,松开LED灭。
锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。

实验过程

硬件部分

在这里插入图片描述

软件部分

1、引入头文件

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h" 

2、主函数
首先时钟、led、按键初始化

int main (void)//主程序
{   u8 a; //定义变量
	//初始化程序
	RCC_Configuration(); //时钟设置 修改需要去sys.c内修改
	LED_Init();//LED初始化 LED连接哪个IO口、输入输出等修改需要去led.c内修改

	KEY_Init();//按键初始化 按键连接哪个IO口、输入输出等修改需要去key.c内修

	//主循环
	while(1){

		//示例1:无锁存
		if(GPIO_ReadInputDataBit(KEYPORT,KEY1)){ //读按键接口的电平 KEYPORT定义IO口组GPIOA或GPIOB,KEY1定义IO口如GPIO_Pin_0等,修改在key.h里修改
			GPIO_ResetBits(LEDPORT,LED1); //LED灯都为低电平(0) (LEDPORT定义IO口组GPIOA或GPIOB,LED1定义IO口如GPIO_Pin_0等,修改在led.h里修改
		}else{	
        	GPIO_SetBits(LEDPORT,LED1); //LED灯都为高电平(1) 
		}

		示例2:无锁存
		GPIO_WriteBit(LEDPORT,LED1,(BitAction)(!GPIO_ReadInputDataBit(KEYPORT,KEY1))); //引脚输出状态取反     GPIO_ReadInputDataBit(KEYPORT,KEY1)读key1电平,读出输出状态

		示例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)); //等待按键松开 
//			}
//		}


	}
}

锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。常用类似电灯开关。
程序:
1、读取IO口的电平
2、延时去抖动
3、读取IO口电平
4、如果为高电平则进入循环,灯常亮,直至按键再次按下转换电平,灯熄灭。

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_WriteBit单个IO口置0或1

GPIO_WriteBit(GPIOB,GPIO_Pin_3 , 0);

GPIO_SetBits多个IO口置0或1

GPIO_SetBits(GPIOD,GPIO_Pin_0 | GPIO_Pin_5 | GPIO_Pin_7);

区别
一个只能单个引脚操作
一个可对多个引脚操作
————————————————————————————————————————————————
STM32引脚输出状态取反方法,学习原子板时,原码LED0,LED1,用位带操作取反状态,不习惯,从别的图书中找到用库函数取反方法,摘录如下:
使用的是PB5,PE5,这两个分别连一个LED灯。

GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5)));
GPIO_WriteBit(GPIOE,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5)))

简释:
GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5),是输出状态;
GPIO_WriteBit(),设置引脚值库函数
————————————————————————————————————————————————

<think>嗯,用户想用STM32和HAL库实现按键控制LED的功能,需要示例代码。首先,我得回忆一下STM32的开发流程,特别是使用HAL库和STM32CubeMX的情况。根据之前的引用内容,用户可能已经看过一些相关资料,比如引用[3]提到了使用HAL库和中断方式,引用[5]讲到了STM32CubeMX的配置步骤。所以,我应该结合这些信息来给出一个清晰的步骤。 首先,用户可能需要知道如何配置GPIO引脚,包括按键LED的设置。按键通常需要设置为输入模式,并且如果使用中断的话,要配置外部中断。LED则需要配置为输出模式。根据引用[3],中断方式可以节省CPU资源,提高实时性,所以可能推荐使用中断而不是轮询。 接下来,代码部分需要初始化GPIO,配置中断,然后编写中断回调函数。引用[4]提到了使用HAL_GPIO_WritePin函数来控制LED,这应该在中断处理函数中被调用。需要注意的是,HAL库的中断处理流程,比如EXTI的中断服务函数会自动调用HAL_GPIO_EXTI_Callback,所以用户需要重写这个回调函数。 另外,引用[5]提到STM32CubeMX可以简化配置,所以步骤中应该包括使用CubeMX进行引脚配置和生成代码的步骤。用户可能需要配置按键对应的GPIO为输入,开启中断,设置边沿触发条件,比如上升沿或下降沿。LED引脚配置为输出模式。 还要考虑消抖处理,因为机械按键会有抖动,可能在中断中处理或者使用定时器延时。不过中断中不宜做延时,所以可能建议在回调函数中添加简单的延时检测,或者提示用户需要消抖处理。 然后,代码示例部分需要展示关键部分,比如回调函数中的逻辑,判断按键按下的情况,并切换LED状态。同时,需要提醒用户根据实际硬件修改引脚定义,比如GPIO端口和引脚号,以及上下拉配置。 可能还需要提到,如果用户不需要实时性,轮询方式也是一种选择,但中断方式更高效。此外,编译和下载程序后的测试步骤,确保按键LED连接正确。 最后,生成相关问题,帮助用户深入理解,比如中断和轮询的区别、消抖方法、CubeMX的其他功能,以及多按键控制等扩展问题。这些问题可以引导用户进一步学习和实践。</think>### 分步实现说明 #### 1. 硬件配置要求 - 按键连接到STM32GPIO引脚(如`PA0`),配置为上拉输入模式 - LED连接到GPIO输出引脚(如`PF9`),配置为推挽输出模式 - 通过STM32CubeMX配置外部中断(EXTI) #### 2. STM32CubeMX配置步骤 1. 创建新工程选择对应芯片型号(如STM32F407ZGT6) 2. 配置系统时钟(SYS和RCC设置) 3. 配置LED引脚为`GPIO_Output` 4. 配置按键引脚为`GPIO_External_Interrupt` 5. 在NVIC设置中启用对应中断通道 6. 生成代码时选择HAL库[^5] #### 3. 核心代码实现 ```c /* 引脚定义 */ #define LED_PIN GPIO_PIN_9 #define LED_PORT GPIOF #define KEY_PIN GPIO_PIN_0 #define KEY_PORT GPIOA /* 中断回调函数 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == KEY_PIN) { // 添加消抖延时 HAL_Delay(20); // 检测按键状态 if(HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET) { // 翻转LED状态 HAL_GPIO_TogglePin(LED_PORT, LED_PIN); } } } /* 主函数初始化 */ int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); while (1) { __WFI(); // 进入低功耗模式等待中断 } } ``` #### 4. 注意事项 - 按键硬件需要设计消抖电路,或通过软件消抖(如示例中的20ms延时) - GPIO引脚号需根据实际电路修改 - 中断优先级需根据系统需求配置[^3] - 上拉/下拉电阻配置需与硬件设计匹配[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值