一个按键实现多个功能

        我最近在某宝买了一块stm32f103的开发板,于是开启了我的stm32学习之旅。在学习了GPIO的操作之后,于是突发奇想,可不可以用一个按键实现多个功能呢?经过思考于是就实现了(第一次按下按键LED灯亮,第二次按下按键蜂鸣器发出声音,第三次按下按键LED熄灭,第四次按下按键蜂鸣器停止发出声音,实验现象:https://b23.tv/VxFXfMd)这个功能。当然在写代码的时候出现了一些问题,下面就有我来分享一下经验(参考代码在最下面):

一、首先我们操作的是外设,当然要把这个外设·对应的GPIO口使能时钟。

二、由于我们用到了LED、蜂鸣器、按键,我们肯定要配置GPIO输入,和输出模式。

三、读出对应GPIO口的电平状态,或者输出高低电平。

逻辑分享:

     由于我们使用了GPIO的输出模式点亮LED(蜂鸣器发出声音)或者熄灭LED灯(蜂鸣器停止发出声音),所以要把GPIO设置成推完输出模式,至于输出速度,我是选择50mhz,我们还使用了按键,肯定要配置相应GPIO口为输入模式,至于是上拉输入模式还是下拉模式,取决于硬件的连接(如果按键的一端的电平为低电平,我们就采用上拉输入,如果按键的一端的电平为高电平,那么我们就采用下拉输入)我们这个按键采用的是上拉输入模式。

    我们到底怎么实现这个功能呢?要实现一个按键实现多个功能,我们可以想到定义一个标志位,当按键按下,这个标志就加一,然后再主函数里面用switch语句,根据标志位的值的不同,我们case语句实现不同的功能,那么就有一个问题出来了,我们怎么再主函数面使用这个标志位的值?这个时候我们会想到用函数返回值,但是这个时候就会出现怎么判断按键按下呢?这个时候extern这个关键字就非常的重要,它可以扩大变量的范围,我们在LED.c文件中定义全局变量flag ,然后用extern在main.c来声明这个变量,于是我们就可以使用这个变量的值,在mian.c中。我们写一个普通的按键按下的函数,当按键按下我们就认flag加一。最后在主函数里面用switch就可以了。

#include "LED.h"
#include "delay.h"
 u8 flag=0;
void LED_init(void)
{
	 GPIO_InitTypeDef GPIO_InitStructe;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	 GPIO_InitStructe.GPIO_Pin= GPIO_Pin_5;
   GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;
	 GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	 GPIO_Init(GPIOB,&GPIO_InitStructe);
	 GPIO_SetBits(GPIOB,GPIO_Pin_5);

}
void BEEP_init(void)
{
	 GPIO_InitTypeDef GPIO_InitStructe;
	 GPIO_InitStructe.GPIO_Pin= GPIO_Pin_8;
   GPIO_InitStructe.GPIO_Mode=GPIO_Mode_Out_PP;
	 GPIO_InitStructe.GPIO_Speed=GPIO_Speed_50MHz;
	 GPIO_Init(GPIOB,&GPIO_InitStructe);
	 GPIO_ResetBits(GPIOB,GPIO_Pin_8);

}
void key_init(void)
{
		GPIO_InitTypeDef GPIO_InitStructe1;
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);
		GPIO_InitStructe1.GPIO_Pin=GPIO_Pin_3;
		GPIO_InitStructe1.GPIO_Mode=GPIO_Mode_IPU;
		GPIO_Init(GPIOE,&GPIO_InitStructe1);

}

u8 key_scan()
{ 
	if(KEY==0)
	{
		delay_ms(20);
		if(KEY==0)
		{ 
			 flag++;
			if(flag>4)
				flag=0;
			return 1;
		}
	}
	return 0;
}

#include "LED.h"
#include "delay.h"
extern u8 flag;
int main()
{
 
	LED_init();
	BEEP_init();
	key_init();
	delay_init();
	while(1)
	{   delay_ms(200);
		 if(key_scan())
		 {   
				switch (flag)
					{
					 case 1: GPIO_ResetBits(GPIOB,GPIO_Pin_5); break;//led灯开
					 case 3: GPIO_SetBits(GPIOB,GPIO_Pin_5);   break;//led灯关
					 case 2: GPIO_SetBits(GPIOB,GPIO_Pin_8);   break;//蜂鸣器开
					 case 4: GPIO_ResetBits(GPIOB,GPIO_Pin_8); break;//蜂鸣器关
						
					}
		 }
		
	}
}

  • 13
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值