51單片機100例實例之16例
//項目名稱:4*4矩陣鍵盤控制條形LED
//項目再創(chuàng)作者:科技小宅神
//完成時間:2021/01/21

#include <reg52.h>//c51頭文件
#include <intrins.h>//c51內(nèi)部移位函數(shù)
#define uchar unsigned char
#define uint unsigned int
//定義鍵盤狀態(tài)數(shù)組 ? ? ? ? ?k1,k2,k3,k4,k5,k6,k7,k8,k9,k10,k11,k12,k13,k14,k15,k16,1k7,18
uchar code KeyCodeTable[]={0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28,0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};
//延時程序
void Delay(uint x)
{
? uchar i;
?while(x--)
?for(i=0;i<200;i++);
}
//鍵盤查詢子程序
uchar Keys_Scan()
{
? uchar hang,lie,i,k;//定義4個局部變量hang,lie,i,k
?P1 = 0xf0; //為P1口賦初值1111 0000,即低四位置0,放入4行
?if((P1&0xf0)!=0xf0)//(若高4位出現(xiàn)0,則有按鍵按下)判斷是否有按鍵按下
?{
? ? Delay(2);//延時函數(shù)進行防抖
? ? if((P1&0xf0)!=0xf0)//(若高4位出現(xiàn)0,則有按鍵按下)判斷是否有按鍵按下
? ? {
? ? ? ?hang = 0xfe;//行掃描初值
? ? ? ?for(k=0;k<4;k++)//對4行分別進行掃描
? ? ? ?{
? ? ? ?P1 = hang;//P1口為1111 0000,此處4個0剛好對應(yīng)P1.0-P.3等4行??
? ? ? ? ? if((P1&0xf0)!=0xf0)//(若高4位出現(xiàn)0,則有按鍵按下)判斷是否有按鍵按下
? ? ? ? ? {
? ? ? ? ? lie= ~P1;//lie為0000 1111,此處4個0剛好對應(yīng)P1.4-P.7等4列
? ? ? ? ? ? ?for(i=0;i<16;i++)//查表得到按鍵序號并返回
? ? ? ? ? ? ? ? ?if(lie == KeyCodeTable[i])//比較按鍵狀態(tài),判斷那個按鍵號
? ? ? ? ? ? ? ? ?return(i);//返回按鍵號? ? ? ? ? ?
? ? ? ? ? ? ?}
? ? ? ?else?
? ? ? ? ? ? hang = _crol_(hang,1);//比較不成功,循環(huán)到下一行
? ? ? }
? ?}
}
?return(-1);//沒有按鍵按下返回-1(-1,一改全改成一樣的)
}
//主程序
void main()
{
? uchar KeyNO =-1;//按鍵號 (-1,一改全改成一樣的) /*注意程序中-1,是個任意值,可以改成其他的,但是如果改就要全部都改成一樣的,否則功能實現(xiàn)不了*/
?uchar i,P2_LED,P3_LED;
?while(1)//死循環(huán)
?{
? ?KeyNO = Keys_Scan();//掃描鍵盤獲取按鍵序號KeyNO?
? if(KeyNO !=-1)//等于-1代表有按鍵按下,不等于則代表沒有(-1,一改全改成一樣的)
? {
? ? P2_LED = 0xff;//賦初值使P2口燈全滅
? ?P3_LED = 0xff;//賦初值使P3口燈全滅
? ?for(i=0;i<=KeyNO;i++)//按鍵號值越大,點亮的LED燈越多
? ?{
? ? ?if(i<8) ?P3_LED>>=1;//按鍵號值小于8,P3_LED右移1位,實際在原理中就是向下移1位???
? ? else ? ? P2_LED>>=1;//如果不是小于8,P2_LED向右移1位,實際在原理中就是向下移1位? ??
? ?}
? ?//這里安排是給按鍵號值等于16時,整個條形LED燈可以全部點亮
? ?P3 = P3_LED;
? ?P2 = P2_LED;
? }
?}
}