蓝桥杯嵌入式——三行按键法

文章介绍了如何在Cubmx中配置GPIO并编写c.h和key.c文件,实现对4个按键的读取以及短按、长按和双击事件的处理,同时控制LED灯。关键函数如key_read用于读取按键状态,key_process处理按键触发的不同操作。
摘要由CSDN通过智能技术生成

1.Cubmx配置

按键1~4分别对应PB0,PB1,PB2,PA0.

在cubmx中使能为GPIO_INPUT

2.c.h文件编写

key.c

#include "key.h"
#define KB1 HAL_GPIO_ReadPin(GPIOB,GPIO_Pin_0)
#define KB2 HAL_GPIO_ReadPin(GPIOB,GPIO_Pin_1)
#define KB3 HAL_GPIO_ReadPin(GPIOB,GPIO_Pin_2)
#define KB4 HAL_GPIO_ReadPin(GPIOA,GPIO_Pin_0)

#define keyport KB1|(KB2<<1)|(KB3<<2)|(KB4<<3)|0xf0

u8 trg;
u8 cont;

void key_read()
{
    u8 readdata = (keyport) ^ 0xff;
    trg = readdata & (readdata ^ cont);
    cont = readdata;
}

key.h

在该文件中声明全局变量trg和cont声明函数key_read()

#ifndef __KEY_H
#define __KEY_H

#include "main.h"

extern u8 trg;
extern u8 cont;

void key_read();
#endif

3.函数调用

单击

u32 keyTick;

void key_process()
{
    if(uwTick-keyTick < 20) return ;
    keyTick=uwTick;

    key_read();
    if(trg & 0x01)    //按键1被按下
                ;     //执行对应函数
    if(trg & 0x02)    //按键2被按下
                ;    //执行对应函数
    if(trg & 0x04)    //按键3被按下
                ;    //执行对应函数
    if(trg & 0x08)    //按键4被按下
                ;    //执行对应函数
}

长按

u32 keyTick;
u32 key_time;
u8 double_key;
void key_process()
 {
    if(uwTick-keyTick<10) return;
    keyTick=uwTick;
    key_read();
    if(trg&0x01)
    {
        key_time=uwTick;
        double_key++;
        
        //view++; //界面切换标志位
    }
    //短按
    if(uwTick- key_time>220 && cont==0x00 &&double_key==1) //第一次按下松手
    {
        double_key=0;
        
        led_control(0x01);
       
    }
    //双击
    if(double_key==2 && uwTick- key_time<900)         
    {
        led_control(0x02);
				double_key=0;
    }
    //长按
    if(cont&0x01 && uwTick-key_time>2000)  
    {
        led_control(0x55);            
        double_key=0;
    }
}

 将编写好的key_process()在while(1)中调用即可
这里注意短按中的cont判断用==不要用&,会出错

长按按键一秒后数值快速上升

//按键
u32 keyTick;
u32 key4Tick;
u32 keypanduan;
void key_process()
{
	if(uwTick - keyTick<10) return ;
	keyTick=uwTick;
	
	key_read();
	
	
	if(trg & 0x02)
	{
		move_num++;
		if(move_num>7)
			move_num=0;
	}
	
	if(trg & 0x04)
	{
		keypanduan=uwTick;
	}
	if(cont & 0x04)
	{
		if(uwTick-keypanduan<1000) return ;
		
		if(uwTick-key4Tick>200)
		{
			key4Tick = uwTick;
			move_num++;
		if(move_num>7)
			move_num=0;
		}
		
	}
    if(trg & 0x08)
	{
		led_ctrl = 0x00;
		true_num=move_num;
	}
}

按下第三个按键,开始计时,一秒后,如果还在按着,200毫秒加一;

按下第四个按键后开始生效

两个按键同时长按才可触发

 按键3与4长按

	if((cont & 0x04) & (cont & 0x08))
	{
		if(uwTick-keypanduan<1000) return ;
		
		
		
		
	}

注意,两个按键同时按下的cont的状态其实是0000 1100,但是我们不能这样写

​
	if(cont & 0x0c)
	{
		if(uwTick-keypanduan<1000) return ;
	
		
	}

​

这样写的结果是无论你单独长按3或者4都会触发

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值