/******************************************************************************
此程式是依據吳堅鴻程式框架,在普中51 A2微控制器開發板上的程式練習
程式目標:4*4矩陣按鍵
*******************************************************************************/
#include<REG51.H>
#define Main_Fosc 12000000L //預設系統時鐘12Mhz
#define T1MS (65536-Main_Fosc/12/1000) //12分頻下1ms定時器的裝載值,n=t/T=t/(12/f)=0.001*f/12=f/12/1000
#define Key_Debounce 40 //按鍵debounce time
sbit Key_Line1_Output=P1^7;
sbit Key_Line2_Output=P1^6;
sbit Key_Line3_Output=P1^5;
sbit Key_Line4_Output=P1^4;
sbit Key_Row1_Input=P1^3;
sbit Key_Row2_Input=P1^2;
sbit Key_Row3_Input=P1^1;
sbit Key_Row4_Input=P1^0;
sbit LED1=P2^0;
sbit LED2=P2^1;
sbit LED3=P2^2;
sbit LED4=P2^3;
sbit LED5=P2^4;
sbit LED6=P2^5;
sbit LED7=P2^6;
sbit LED8=P2^7;
unsigned char Key_Handle=0; //按鍵值
void Sys_Init(); //系統初始化
void Delay_Long(); //長延時,等待系統穩定
void Perpherial_Init(); //埠初始化
void Key_Scan(); //按鍵掃描函式
void Key_Service(); //按鍵響應函式
void main()
{
Sys_Init();
Delay_Long();
Perpherial_Init();
while (1)
{
Key_Service();
}
}
void Sys_Init()
{
TMOD=0X01; //定時器0模式1
TL0=T1MS;
TH0=T1MS>>8;
}
void Delay_Long()
{
unsigned char i,j;
for(i=0;i++;i<220)
{
for(j=0;j<220;j++)
;
}
}
void Perpherial_Init()
{
ET0=1;
TR0=1;
EA=1;
}
void Timer0_ISR() interrupt 1 //定時器0中斷函式
{
TL0=T1MS;
TH0=T1MS>>8;
Key_Scan();
}
void Key_Scan()
{
static unsigned int Key_CNT;
static unsigned char Key_Lock=0;
static unsigned char KeyScan_Step;
static unsigned char KeyOutput_LineNum=1;
switch (KeyScan_Step)
{
case 0:
if (1==KeyOutput_LineNum)
{
Key_Line1_Output=0;
Key_Line2_Output=1;
Key_Line3_Output=1;
Key_Line4_Output=1;
}
else if (2==KeyOutput_LineNum)
{
Key_Line1_Output=1;
Key_Line2_Output=0;
Key_Line3_Output=1;
Key_Line4_Output=1;
}
else if (3==KeyOutput_LineNum)
{
Key_Line1_Output=1;
Key_Line2_Output=1;
Key_Line3_Output=0;
Key_Line4_Output=1;
}
else if (4==KeyOutput_LineNum)
{
Key_Line1_Output=1;
Key_Line2_Output=1;
Key_Line3_Output=1;
Key_Line4_Output=0;
}
Key_CNT=0;
KeyScan_Step++;
break;
case 1:
Key_CNT++;
if (Key_CNT>=2)
{
Key_CNT=0;
KeyScan_Step++;
}
break;
case 2:
if ((1==Key_Row1_Input)&&(1==Key_Row2_Input)&&(1==Key_Row3_Input)&&(1==Key_Row4_Input))
{
Key_CNT=0;
Key_Lock=0;
KeyScan_Step=0;
KeyOutput_LineNum++;
if(KeyOutput_LineNum>=5)
{
KeyOutput_LineNum=1;
}
}
else if (0==Key_Lock)
{
if ((0==Key_Row1_Input)&&(1==Key_Row2_Input)&&(1==Key_Row3_Input)&&(1==Key_Row4_Input))
{
Key_CNT++;
if (Key_CNT>Key_Debounce)
{
Key_Lock=1;
Key_CNT=0;
if (1==KeyOutput_LineNum)
{
Key_Handle=1;
}
else if (2==KeyOutput_LineNum)
{
Key_Handle=5;
}
else if (3==KeyOutput_LineNum)
{
Key_Handle=9;
}
else if(4==KeyOutput_LineNum)
{
Key_Handle=13;
}
}
}
else if ((1==Key_Row1_Input)&&(0==Key_Row2_Input)&&(1==Key_Row3_Input)&&(1==Key_Row4_Input))
{
Key_CNT++;
if (Key_CNT>Key_Debounce)
{
Key_Lock=1;
Key_CNT=0;
if (1==KeyOutput_LineNum)
{
Key_Handle=2;
}
else if (2==KeyOutput_LineNum)
{
Key_Handle=6;
}
else if (3==KeyOutput_LineNum)
{
Key_Handle=10;
}
else if (4==KeyOutput_LineNum)
{
Key_Handle=14;
}
}
}
else if ((1==Key_Row1_Input)&&(1==Key_Row2_Input)&&(0==Key_Row3_Input)&&(1==Key_Row4_Input))
{
Key_CNT++;
if (Key_CNT>Key_Debounce)
{
Key_Lock=1;
Key_CNT=0;
if (1==KeyOutput_LineNum)
{
Key_Handle=3;
}
else if (2==KeyOutput_LineNum)
{
Key_Handle=7;
}
else if (3==KeyOutput_LineNum)
{
Key_Handle=11;
}
else if (4==KeyOutput_LineNum)
{
Key_Handle=15;
}
}
}
else if ((1==Key_Row1_Input)&&(1==Key_Row2_Input)&&(1==Key_Row3_Input)&&(0==Key_Row4_Input))
{
Key_CNT++;
if (Key_CNT>Key_Debounce)
{
Key_Lock=1;
Key_CNT=0;
if (1==KeyOutput_LineNum)
{
Key_Handle=4;
}
else if (2==KeyOutput_LineNum)
{
Key_Handle=8;
}
else if (3==KeyOutput_LineNum)
{
Key_Handle=12;
}
else if (4==KeyOutput_LineNum)
{
Key_Handle=16;
}
}
}
}
break;
}
}
void Key_Service()
{
if (0==Key_Handle)
{
return;
}
switch (Key_Handle)
{
case 1:
LED1=0;
Key_Handle=0;
break;
case 2:
LED2=0;
Key_Handle=0;
break;
case 3:
LED3=0;
Key_Handle=0;
break;
case 4:
LED4=0;
Key_Handle=0;
break;
case 5:
LED5=0;
Key_Handle=0;
break;
case 6:
LED6=0;
Key_Handle=0;
break;
case 7:
LED7=0;
Key_Handle=0;
break;
case 8:
LED8=0;
Key_Handle=0;
break;
case 9:
LED1=1;
Key_Handle=0;
break;
case 10:
LED2=1;
Key_Handle=0;
break;
case 11:
LED3=1;
Key_Handle=0;
break;
case 12:
LED4=1;
Key_Handle=0;
break;
case 13:
LED5=1;
Key_Handle=0;
break;
case 14:
LED6=1;
Key_Handle=0;
break;
case 15:
LED7=1;
Key_Handle=0;
break;
case 16:
LED8=1;
Key_Handle=0;
break;
}
}