这是我修改后的代码,实现了十二个按键的循环扫描,试运行了下基本逻辑是对的,希望大家帮我看看有什么需要改进的,初学者还有很多不懂的。
#include<reg52.h>
#define bitRead(Y,X) ( ~Y & (1 << (X-1)) ) // 读取 Y 的X位,其他位屏蔽为0,Y的X位为0则X位置为1,否则置位0
#define bitSet(Y,X) Y |= (1 << (X-1)) // Y的X位置1
#define bitClear(Y,X) Y &= ~(1 << (X-1)) // Y的X位置0
#define Merge_key ((P2>>4&0x08)|(P2&0x07))<<8|P3 //16位从高位到低位排序位:0 0 0 0 / P2.7 P2.2 P2.1 P2.0 / P3.7 P3.6 P3.5 P3.4 / P3.3 P3.2 P3.1 P3.0
/*------------------------------------------------
函数名称: KEY_Initialise()
函数功能: 按键初始化
入口参数:
出口参数: 无
备 注:
------------------------------------------------*/
uint data key_alarm=0xff; //按键按下是否生效标志位:LED1,LED2,...lLED10,test,mute,null,null,null,null
uint data key_value=0x00; //实时存储按键按下标志位:LED1,LED2,LED3...LED10,test,mute,LED_ALARM,buzzer,null,null;用于显示和通讯
void KEY_Initialise() //KEY1-KEY10,TEST,MUTE
{
static uint KEY ;
static uchar uckey_num ;
static uint code KEY_transient[]={0x0001,0x0002,0x0004,0x0008, //P3.0 P3.1 P3.2 P3.3
0x0010,0x0020,0x0040,0x080, //P3.4 P3.5 P3.6 P3.7
0x0100,0x0200,0x0400,0x0800}; //P2.0 P2.1 P2.2 P2.7
static uchar data keytime_Y[12]={0,0,0,0,0,0,0,0,0,0,0,0};//timeY按下计时消抖 LED1,LED2,...lLED10,test,mute
static uchar data keytime_N[12]={0,0,0,0,0,0,0,0,0,0,0,0};//timeN未按下计时消抖LED1,LED2,...lLED10,test,mute
static uchar code Const_Keysnake_time=200;
KEY = Merge_key ;
if ( KEY != 0X0FFF )
{
for ( uckey_num = 0 ; uckey_num < 13 ; uckey_num ++ )
{ uint abc=bitRead ( KEY,uckey_num+1);
if ( bitRead ( KEY,uckey_num+1 ) == KEY_transient[uckey_num] )//函数逻辑不对,需确定
{
keytime_Y[uckey_num]++; //按下消抖计时加1
keytime_N[uckey_num]=0; //未按下消抖计时清零
if(keytime_Y[uckey_num]>Const_Keysnake_time) //消抖滤波 ,受程序循环影响延时时间,需要程序完成后校准Const_Keysnake_time值
{
keytime_Y[uckey_num]=0; //按下消抖计时清零
bitSet(key_value,uckey_num+1); //是否按下标志位
}
}
else //按键1未按下
{
keytime_N[uckey_num]++; //未按下消抖计时加1
keytime_Y[uckey_num]=0; //按下消抖计时清零
if(keytime_N[uckey_num]>Const_Keysnake_time)
{
keytime_N[uckey_num]=0;
bitClear(key_value,uckey_num+1);
}
}
}
}
} |