35.成功解决编写关于“江协科技”编写技巧第二期标志位积累的问题

江科大学长又发布了第二期的编写技巧!

大家可以看看:https://space.bilibili.com/383400717

最后面给了一个未完成的任务:

这里我已经把这个问题给解决了!

总代码放在资源里面,key.c放在文章最后面!同时感兴趣的同学可以看看我的Linux驱动讲解!

1、保存上一次的标志位:

2、清零目标标志位

计划在同一个按键事件后的标志位发生变化时,判断上一个标志位和目前标志位不一样时进行清理:

为了简单理解,我们就以同一个按键,两位2进制标志位来讲。

假设上一个的标志位是10;如果按照之前的代码,切换模式的时候,那目前标志位就是11,因为假设并没有进行检查操作就想清零。解决标志位积累的问题!

所以进行:

复制代码
if(Last_Key_Flag[i]!=Key_Flag[i])
{
	Key_Flag[i]&=~Last_Key_Flag[i];
}
Last_Key_Flag[i]=Key_Flag[i];

3、同一个按键空闲的时候也清零标志位:

这样就行了!不过这里有一个问题,就是按键松开和按压时间交替太快了,程序会认为是清零标志位,而不是双击,太慢了,就会认为是单击。但是如果不这样设置,就会保留最后一次的标志位,目前我没有想到好的方法!就留给后来者了!

4、Key.c代码:

c 复制代码
 #include "stm32f10x.h"                  // Device header
 #include "Key.h"
 
#define KEY_PRESSED   1
#define KEY_UNPRESSED 0

#define KEY_TIME_DOUBLE 200
#define KEY_TIME_LONG   2000
#define KEY_TIME_REPEAT 100



u8 Key_Flag[KEY_COUNT];


void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef   GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;             //¶ÁÈ¡°´¼ü
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;             //¶ÁÈ¡°´¼ü
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

u8 Key_Getstate(u8 n)
{
	if(n==KEY_1)
	{
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)==0)
	{
		return KEY_PRESSED ;
	}
  }
	else if(n==KEY_2)
	{
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)==0)
	{
		return KEY_PRESSED ;
	}
  }
	else if(n==KEY_3)
	{
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13)==1)
	{
		return KEY_PRESSED ;
	}
	}
	else if(n==KEY_4)
	{
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==1)
	{
		return KEY_PRESSED ;
	}
	}
	return KEY_UNPRESSED;
 }

u8 Key_Check(u8 n,u8 Flag)
{
	if(Key_Flag[n]&Flag)
	{
		if(Flag!=KEY_HOLD)
		{
		Key_Flag[n]&=~Flag;
    }
		return 1;
	}
	return 0;
}

void Key_Tick(void)
{
	static u8  Count,i;
	static u8  CurrState[KEY_COUNT],PrevState[KEY_COUNT];
	static u8  S[KEY_COUNT];
	static u16 Time[KEY_COUNT];
	static u8  Last_Key_Flag[KEY_COUNT]; 
	for(i=0;i<KEY_COUNT;i++)
	{
	if(Time[i]>0)
	{
		Time[i]--;
	}
 }
	Count++;
	if(Count>=20)
	{
		Count=0;
		for(i=0;i<KEY_COUNT;i++)
		{
		PrevState[i]=CurrState[i];
		CurrState[i]=Key_Getstate(i);
		if(CurrState[i]==KEY_PRESSED)
		{
			//HOLD=1
			Key_Flag[i]|=KEY_HOLD;
		}else{
			//HOLD=0
			Key_Flag[i]&=~KEY_HOLD;
		}
		if(CurrState[i]==KEY_PRESSED&&PrevState[i]==KEY_UNPRESSED)
		{
			//Down=1
			Key_Flag[i]|=KEY_DOWN;
		}
		if(CurrState[i]==KEY_UNPRESSED&&PrevState[i]==KEY_PRESSED)
		{
			//UP=1
			Key_Flag[i]|=KEY_UP;
			
		}
		if(PrevState[i]==KEY_UNPRESSED&&CurrState[i]==KEY_UNPRESSED)
		{
				Key_Flag[i]&=0x00;
		}
		if(S[i]==0)
		{
			if(CurrState[i]==KEY_PRESSED)
			{
				Time[i]=KEY_TIME_LONG;//2s³¤°´Ê±¼äãÐÖµ
				S[i]=1;
			}
		}
		else if(S[i]==1)
		{
		 if(CurrState[i]==KEY_UNPRESSED)
			{
				Time[i]=KEY_TIME_DOUBLE;
				S[i]=2;
			}
			else if(Time[i]==0)
			{
				Time[i]=KEY_TIME_REPEAT;
				//LONG=1
				Key_Flag[i]|=KEY_LONG;
				S[i]=4;
			}
		}
		else if(S[i]==2)
		{
			if(CurrState[i]==KEY_PRESSED)
			{
				//DOUBLE=1
				Key_Flag[i]|=KEY_DOUBLE;
				S[i]=3;
			}
			else if(Time>0)
			{
				//SINGLE=1
				Key_Flag[i]|=KEY_SINGLE;
				S[i]=0;
			}
		}	
		else if(S[i]==3)
		{
			if(CurrState[i]==KEY_UNPRESSED)
			{
					S[i]=0;
			}
		}		
		else if(S[i]==4)
		{
			if(CurrState[i]==KEY_UNPRESSED)
			{
					S[i]=0;
			}
			else if(Time[i]==0)
			{
				Time[i]=KEY_TIME_REPEAT;
				//REPEAT=1
				Key_Flag[i]|=KEY_REPEAT;
				S[i]=4;
			}
		}	
		if(Last_Key_Flag[i]!=Key_Flag[i])
		{
			Key_Flag[i]&=~Last_Key_Flag[i];
		}
    Last_Key_Flag[i]=Key_Flag[i];
	}
 }
}
``
相关推荐
Truffle7电子2 小时前
STM32CubeIDE/Programmer/Touch GFX 应用
stm32·单片机·嵌入式硬件
richxu202510013 小时前
嵌入式学习之路->stm32篇->(14)通用定时器(上)
stm32·单片机·嵌入式硬件·学习
Deitymoon5 小时前
STM32——外部中断按键控制led
stm32·单片机·嵌入式硬件
czwxkn5 小时前
7STM32(stdl)flash内部闪存
stm32·单片机·嵌入式硬件
咕噜咕噜啦啦6 小时前
STlink下载程序
stm32·单片机
Deitymoon7 小时前
STM32——串口中断接收
stm32·单片机·嵌入式硬件
Deitymoon9 小时前
STM32——串口通信发送数据
stm32·单片机·嵌入式硬件
czwxkn10 小时前
8STM32(stdl)低功耗模式
stm32·单片机·嵌入式硬件
czwxkn10 小时前
9STM32(stdl)看门狗
stm32·单片机·嵌入式硬件
LCG元11 小时前
STM32实战:基于STM32F103的SPI通信驱动W25Qxx Flash存储
stm32·单片机·嵌入式硬件