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];
	}
 }
}
``
相关推荐
猫猫的小茶馆2 小时前
【ARM】ARM的介绍
c语言·开发语言·arm开发·stm32·单片机·嵌入式硬件·物联网
猫猫的小茶馆2 小时前
【PCB工艺】数模电及射频电路基础
驱动开发·stm32·单片机·嵌入式硬件·mcu·物联网·pcb工艺
小李做物联网5 小时前
【物联网毕业设计】60.1基于单片机物联网嵌入式项目程序开发之图像厨房监测系统
stm32·单片机·嵌入式硬件·物联网
@good_good_study6 小时前
STM32 ADC多通道采样实验
stm32·单片机·嵌入式硬件
Darken036 小时前
什么是“位带”?;在STM32单片机中有什么作用?
stm32·单片机·嵌入式硬件
Triumph++8 小时前
STM32工程(Kile5)生成Bin文件
stm32·嵌入式硬件
强化学习与机器人控制仿真10 小时前
Holosoma 开源人形机器人强化学习训练部署框架
人工智能·stm32·神经网络·机器人·强化学习·具身智能·人形机器人
d111111111d10 小时前
在stm32F103C8T6中,Thumb指令是什么?有什么作用?可以干什么?
笔记·stm32·单片机·嵌入式硬件·学习
DIY机器人工房10 小时前
简单理解:ESP32S3 开发板中通过什么控制舵机
stm32·单片机·嵌入式硬件·mcp·小智ai·diy机器人工房
victorwjw10 小时前
STM32 ISP下载原理
stm32·嵌入式硬件