06_STM32按键试验

这篇博客详细介绍了基于STM32芯片进行硬件控制的实现,包括按键扫描(支持连按与不支持连按模式)、蜂鸣器的开关控制以及LED灯的状态反转。通过GPIO初始化、按键处理函数和主循环,实现了按键按下时蜂鸣器响应、LED灯状态改变的功能。代码中定义了宏定义以简化操作,并提供了去抖动的延迟函数。

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

试验介绍,按下WK_up按键蜂鸣器响,在按下蜂鸣器停,按下KEY2按键LED0反转,按下KEY1按键LED1反转,按下KEY0按键LED0 LED1同时反转。

硬件连接:

        Key原理图:

 

由原理图可以看出KEY0 KEY1 KEY2一端是连接芯片引脚PE4 PE3 PE2按键按下是低电平

KEY_UP一端连接芯片引脚PA0,另一端连接的是3.3v按键按下会是高电平

按键扫描思路:

        支持连按:

        假设高电平是没有按下的,低电平是按键按下,100ms扫描一次,如果是按了1s我们会检测到10次都是低电平,如果是支持连按模式我们认为它是连续按了10次,可以写连续按下10次按键的逻辑代码。

        不支持连按:

        假设高电平是没有按下的,低电平是按键按下,,100ms扫描一次,我们会以上一次状态来判断,上一次状态是高的时候,这次还是高我们认为没有按下,当下一次扫描的时候是低我们认为它是按下按键的,在下一次扫描时,如果还是低我们认为他一直在按下,程序处理为只按下一次,只有当程序检测到是从高电平到低电平的时候认为是按下一次,一直保持低电平认为是按下没松开,作一次按下处理。

 蜂鸣器原理图:

        

 

 当我们给BEEP引脚为高时三级管导通,G端会接地,蜂鸣器会响

LED原理图:

 

 

由原理图可以看出LED0连接在芯片上的PB5引脚上,ED1连接在芯片上的PE5引脚上,又由2个LED一端连接的是VCC3.3伏,要想LED灯亮的话需要把所连的引脚拉低。

代码实现:

#define LED0(mode)	GPIO_WriteBit(GPIOB,GPIO_Pin_5,mode)
#define LED1(mode)	GPIO_WriteBit(GPIOE,GPIO_Pin_5,mode)
#define BEEP(mode)  GPIO_WriteBit(GPIOB,GPIO_Pin_8,mode)
/*!
	\brief		GPIO初始化函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Gpio_Init(void)
{	
	GPIO_InitTypeDef GPIO_InitStructure;  //GPIO结构体
	
	//GPIOE、GPIOB、GPIOA是挂在APB2上
	//使能GPIOA、GPIOE时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
	RCC_APB2Periph_GPIOB|
	RCC_APB2Periph_GPIOE,ENABLE);
	
	//KEY0 1 2 结构体配置
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU; 					   //上拉输入 没按下默认是高电平
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;  //引脚选择
	//初始化GPIOE Pin2 3 4 
	GPIO_Init(GPIOB,&GPIO_InitStructure); 
	
	//KEY_UP结构体配置		
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPD; 					   //下拉输入 没按下默认是低电平
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0;	   					   //引脚选择
	//初始化GPIOE Pin0 
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//蜂鸣器结构体配置
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;						 //pin8
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 		 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 	 		 //速度为50MHz
	//初始化GPIOB Pin8 	
	GPIO_Init(GPIOB, &GPIO_InitStructure);	 				         //根据参数初始化GPIOB.8	
	GPIO_ResetBits(GPIOB,GPIO_Pin_8);						 		 //输出0,关闭蜂鸣器输出
	
	//LED0结构体配置	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;  	     				 //LED0-->PB.5 端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 				 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;				 //IO口速度为50MHz
	//初始化GPIOB Pin5	
	GPIO_Init(GPIOB, &GPIO_InitStructure);					 		 //根据设定参数初始化GPIOB.5
	GPIO_SetBits(GPIOB,GPIO_Pin_5);						 			 //PB.5 输出高

	//LED1结构体配置	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 	     //LED1-->PE.5 端口配置, 推挽输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 				 //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;				 //IO口速度为50MHz
	//初始化GPIOE Pin5
	GPIO_Init(GPIOE, &GPIO_InitStructure);	  				         //推挽输出 ,IO口速度为50MHz
	GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 	     //PE.5 输出高 	
	
}
/*!
	\brief		按键处理函数
	\param[in]	mode: 0不支持连续按,1支持连续按
	\param[out]	none
	\retval 	返回按键按键值 1	KEY0按下 2 KEY1按下 KEY2_PRES 3 KEY2按下 4 KEY_UP按下
*/

uint8_t Key_Scan(uint8_t mode)
{
	
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		  
	
	
	if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(KEY0==0)return KEY0_PRES;
		else if(KEY1==0)return KEY1_PRES;
		else if(KEY2==0)return KEY2_PRES;
		else if(WK_UP==1)return WKUP_PRES;
		
	}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1; 	 

	
 	return 0;// 无按键按下

}

 int main(void)
 {	
	uint8_t key=0;	
	 
	delay_init();	    	 //延时函数初始化
	 
	Gpio_Init();			 //GPIO初始化函数
	
	while(1){
		key=Key_Scan(0);	//得到键值不支持连续按
		
		  if(key){
		
				switch(key){	
					
					case WKUP_PRES:	//控制蜂鸣器
						BEEP(!GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_8));
						break;
					case KEY2_PRES:	//控制LED0翻转
						LED0(!GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5));
						break;
					case KEY1_PRES:	//控制LED1翻转	 
						LED1(!GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5));
						break;
					case KEY0_PRES:	//同时控制LED0,LED1翻转 
						LED0(!GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5));
						LED1(!GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5));
						break;
					
				           }
		       }
	

	     } 
	 
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值