网站开发给网站设置图标在什么文件中写代码,广告宣传片公司,seo全称,wordpress500错误解决1.分析原理图 由上图可以看到若J5跳线帽接地#xff0c;就S4~S7就可以当做四路独立按键#xff0c;若接到P44#xff0c;则就是4*4的矩阵键盘。
2.独立按键处理
相对传统的按键延时消抖方案#xff0c;这里我采用更高效#xff0c;更经典#xff0c;更偏向产品级应用的…1.分析原理图 由上图可以看到若J5跳线帽接地就S4~S7就可以当做四路独立按键若接到P44则就是4*4的矩阵键盘。
2.独立按键处理
相对传统的按键延时消抖方案这里我采用更高效更经典更偏向产品级应用的状态机方案
u8 Trg0,Cont0;
//独立按键
void Key_Scan()
{//状态机u8 ReadData P3^0XFF;Trg ReadData(ReadData^Cont); //记录短按键值Cont ReadData; //记录长按键值Key_Read(); //判断哪个按键按下
}
void Key_Read()
{if(Trg 0x08){ //S4短按//按键任务区Set_Leds(1,1);//打开LED1}else if(Trg 0x04){ //S5短按Set_Leds(2,1); //打开LED2}else if(Trg 0x02){ //S6短按Set_Leds(3,1);}else if(Trg 0x01){ //S7短按Set_Leds(4,1);}else;
}在应用的时候我们只需要知道三个状态对应的按键情况就行 1.按键未按下或者松手时Trg0,Cont0 2.按键刚按下且Key_Scan只运行一遍时Trg键值Cont键值 3.按键持续按下状态时Trg0,Cont键值 然后我们就能根据这三个状态来判断长按短按未按下以及后续扩展双击等功能
扩展长按功能由于按键持续按下状态Cont键值且Trg0;因此我们可以在此条件基础上增加一个计时变量当变量大于一定值则判定为长按。
u8 Trg0,Cont0,Num0;
bit LONG_CLICKED0;
//独立按键
void Key_Scan() //20ms扫描一次
{//状态机u8 ReadData P3^0XFF;Trg ReadData(ReadData^Cont); //记录短按键值Cont ReadData; //记录长按键值if((Trg0)(Cont!0)) //记录按下时长{if(Num100) //满足长按2S{LONG_CLICKED1;Num;}}if((Trg0)(Cont0)) //松手或者未按下{//此处可扩展双击Num0;}Key_Read(); //判断哪个按键按下
}void Key_Read()
{if(Trg 0x08){ //S4短按//按键任务区Set_Leds(1,1);}else if(Trg 0x04){ //S5短按Set_Leds(2,1);}else if(Trg 0x02){ //S6短按Set_Leds(3,1);}else if(Trg 0x01){ //S7短按Set_Leds(4,1);}else;if(!LONG_CLICKED) return;if(Cont0x08){ //S4长按Set_Leds(1,0);}else if(Cont0x04){ //S5长按Set_Leds(2,0);}else if(Cont0x02){ //S6长按Set_Leds(3,0);}else if(Cont0x01){ //S7长按Set_Leds(4,0);}else;LONG_CLICKED0;
}扩展双击功能双击功能则是在松手状态下去判断长按功能的计时变量小于一定值则可认为按键短按一次此时再创建一个计时变量当此计时变量大于一定值而小于一定值时按键再次按下则可判定为双击。好像往年都未曾考查过此功能所以我就不写了有兴趣的同学可以试试。
3.矩阵键盘
矩阵键盘的处理方案同独立按键我就不细讲了理解记忆即可
u8 Trg0,Cont0,Num0;
bit LONG_CLICKED0;
//矩阵键盘
void Keys_Scan()
{//状态机u8 ReadData,ColumnData;P3 0XF0; //行低列高P42 1;P44 1;P36 P42; //IO映射便于数据操作P37 P44;ColumnData P3; //暂存列数据P3 0X0F; //行高列低P42 0;P44 0;ReadData(P3 | ColumnData)^0XFF;Trg ReadData(ReadData^Cont); //记录短按键值Cont ReadData; //记录长按键值if((Trg0)(Cont!0)) //记录按下时长{if(Num100) //满足长按2S{LONG_CLICKED1;Num;}}if((Trg0)(Cont0)) //松手或者未按下{//此处可扩展双击Num0;}Keys_Read(); //判断哪个按键按下
}/****************矩阵键码表******************
S7-0X81 S11-0X41 S15-0X21 S19-0X11
S6-0X82 S10-0X42 S14-0X22 S18-0X12
S5-0X84 S9-0X44 S13-0X24 S17-0X14
S4-0X88 S8-0X48 S12-0X28 S16-0X18
*******************************************/
void Keys_Read()
{ //用到再加一一列举程序运行慢if(Trg 0x81){ //S7按下Set_Leds(1,1);}else if(Trg 0x48){ //S8按下Set_Leds(2,1);}else;if(!LONG_CLICKED) return;if(Cont 0x81){ //S7长按Set_Leds(1,0);}else if(Cont 0X48){ //S8按下Set_Leds(2,0);}else;LONG_CLICKED0;
}4.使用示例
#include main.hvoid System_Init(void);void Delay20ms() //12.000MHz
{unsigned char data i, j;i 234;j 115;do{while (--j);} while (--i);
}void main()
{System_Init();while(1){Delay20ms();//Key_Scan();Keys_Scan();}
}void System_Init()//系统上电初始化
{//先锁存蜂鸣器,继电器所在573输出低电平防止上电乱叫P251;P260;P271; //74HC138--Y50,else1--Y5C1,else0P00X00; //ULN2003输入经过非门送入达林顿管低电平有效P250;P260;P270;//锁存数据//关闭所有LED灯P250;P260;P271; //74HC138--Y40,else1--Y4C1,else0P00XFF;P250;P260;P270;//锁存数据}如果有用到长按功能20ms运行一次最好是通过定时器去扫描实现后续笔记中我会提供示例。