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

按键控制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(),设置引脚值库函数
————————————————————————————————————————————————

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现STM32按键控制LED亮灭,可以采用以下步骤: 1. 初始化GPIO口(包括按键和LEDGPIO口)和外部中断(对应按键的GPIO口); 2. 在中断服务函数中读取按键状态,根据按键状态改变LED状态; 3. 在主程序中启用中断,并进入循环等待中断事件的发生。 以下是示例代码: ```c #include "stm32f10x.h" #define LED_PIN GPIO_Pin_8 #define LED_PORT GPIOA #define KEY_PIN GPIO_Pin_0 #define KEY_PORT GPIOB void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA、GPIOB时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // 配置PA8为推挽输出,用作LED GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); // 配置PB0为上拉输入,用作按键输入 GPIO_InitStructure.GPIO_Pin = KEY_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(KEY_PORT, &GPIO_InitStructure); // 配置EXTI0为中断模式 GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { // 检测按键状态 if (GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == SET) { // 点亮LED GPIO_SetBits(LED_PORT, LED_PIN); } else { // 熄灭LED GPIO_ResetBits(LED_PORT, LED_PIN); } EXTI_ClearITPendingBit(EXTI_Line0); // 清除中断标志位 } } int main(void) { GPIO_Configuration(); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); while (1) { // 等待中断事件的发生 } } ``` 在上述示例代码中,我们通过 `GPIO_Configuration` 函数初始化了LED和按键的GPIO口,并将PB0配置为中断模式。在 `EXTI0_IRQHandler` 中断服务函数中,当检测到按键按下时,点亮LED;当检测到按键释放时,熄灭LED。在主程序中,我们启用中断并进入循环等待中断事件的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值