原文链接
https://www.amobbs.com/thread-4308630-1-1.html
#define Number 20
unsigned char Jitter = Number; //连续检测20次,每次间隔1ms
unsigned int Value; //读取的端口,每次和次数据做或操作,原始值为0
unsigned int SaveData;//保存读取的去抖动后的端口数据
unsigned int Trg;
unsigned int Cont;
void KeyRead(unsigned char Time)
{
if(Time != 0) //不为0时,1ms时间间隔已到
{
if(Jitter == 0)
{
SaveData = Value; //去抖动次数到,保存读取的数据
Value = 0; //和端口做or操作
Jitter =Number;
}
else
{
--Jitter;
Value |= GPIO_ReadInputData(GPIOC);//每次去抖动时都是0为有按下,有一次为1,
//表示已松开,置读取数据以后都为1,到去抖动次数到,再读取是否为0
}
}//以上为添加部分
unsigned int ReadData = SaveData^0xffff; // 1
Trg = ReadData & (ReadData ^ Cont); // 2
Cont = ReadData; // 3
}
我也喜欢这样写,我感觉很爽就行。
这个逻辑容易理解些,不错。
添加去抖动
对单个按键操作,不使用定时器
sbit Key = P1.0;
u8 Keyscan(void)
{
u8 ReadKey;
u8 i = 0;
static bit Key_Trge = 0;
static bit ContKey = 0;
static u16 LoopCnt_Key = 0;
LoopCnt_Key ++;
if(LoopCnt_Key >= 10000)
{
LoopCnt_Key = 0;
//按键算法的精髓在于==响应且只响应一次按键操作,并具有抗干扰(再一次确认)。
//此算法是第二次读按键仍然有效才响应按键操作
ReadKey = Key ^ 1; //当前I/O状态(按下为“真”)
if(Key_Trge && ReadKey)
{
i |= 0x01;
// 或直接响应按键操作
}
Key_Trge = ReadKey & (ReadKey ^ ContKey);
//如果 当前状态为“真”,且当和“上次状态”不一致,则Trg为“真”
//即:如果当前检测到按键按下且上次未按下,则是一次有效的触发;
//如果连续按下,则只视为一次有效触发。
//这里的ContKey_RUN表示为“上次状态”。
ContKey = ReadKey; //保存当前状态
}
return i;
}
一周热门 更多>