這是我修改后的代碼,實現了十二個按鍵的循環掃描,試運行了下基本邏輯是對的,希望大家幫我看看有什么需要改進的,初學者還有很多不懂的。
#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);
}
}
}
}
} |