矩阵键盘行列扫描

  1. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义  
  2.   
  3.   
  4. #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换  
  5. #define KeyPort  P1  
  6.   
  7. sbit LATCH1=P2^2;//定义锁存使能端口 段锁存  
  8. sbit LATCH2=P2^3;//                 位锁存  
  9.   
  10. unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,  
  11.                                      0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F  
  12. unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码  
  13. unsigned char TempData[10]; //存储显示值的全局变量  
  14.   
  15. void DelayUs2x(unsigned char t);//us级延时函数声明   
  16. void DelayMs(unsigned char t); //ms级延时  
  17. void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数  
  18. unsigned char KeyScan(void);//键盘扫描  
  19. unsigned char KeyPro(void);  
  20. void Init_Timer0(void);//定时器初始化  
  21.   
  22. void main (void)  
  23. {  
  24. unsigned char num,i,j;                    
  25. unsigned char temp[8];  
  26. Init_Timer0();  
  27.   
  28. while (1)         //主循环  
  29.   {  
  30.   
  31.   
  32.  num=KeyPro();  
  33.  if(num!=0xff)  
  34.    {  
  35.     if(i<8)  
  36.       {  
  37.        temp[i]=dofly_DuanMa[num];  
  38.        for(j=0;j<=i;j++)  
  39.           TempData[7-i+j]=temp[j];  
  40.        }  
  41.     i++;  
  42.     if(i==9)//多出一个按键输入为了清屏 原本应该为8  
  43.       {  
  44.       i=0;  
  45.          for(j=0;j<8;j++)//清屏  
  46.          TempData[j]=0;  
  47.        }  
  48.    }  
  49.   //Display(0,8); //显示全部8位  
  50.      //主循环中添加其他需要一直工作的程序  
  51.       
  52.   }  
  53. }  
  54.   
  55. void DelayUs2x(unsigned char t)  
  56. {     
  57.  while(--t);  
  58. }  
  59.   
  60. void DelayMs(unsigned char t)  
  61. {  
  62.        
  63.  while(t--)  
  64.  {  
  65.      //大致延时1mS  
  66.      DelayUs2x(245);  
  67.      DelayUs2x(245);  
  68.  }  
  69. }  
  70.   
  71. void Display(unsigned char FirstBit,unsigned char Num)  
  72. {  
  73.       static unsigned char i=0;  
  74.         
  75.   
  76.        DataPort=0;   //清空数据,防止有交替重影  
  77.        LATCH1=1;     //段锁存  
  78.        LATCH1=0;  
  79.   
  80.        DataPort=dofly_WeiMa[i+FirstBit]; //取位码   
  81.        LATCH2=1;     //位锁存  
  82.        LATCH2=0;  
  83.   
  84.        DataPort=TempData[i]; //取显示数据,段码  
  85.        LATCH1=1;     //段锁存  
  86.        LATCH1=0;  
  87.          
  88.        i++;  
  89.        if(i==Num)  
  90.           i=0;  
  91.   
  92.   
  93. }  
  94.   
  95. void Init_Timer0(void)  
  96. {  
  97.  TMOD |= 0x01;    //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响            
  98.  //TH0=0x00;          //给定初值  
  99.  //TL0=0x00;  
  100.  EA=1;            //总中断打开  
  101.  ET0=1;           //定时器中断打开  
  102.  TR0=1;           //定时器开关打开  
  103. }  
  104.   
  105. void Timer0_isr(void) interrupt 1   
  106. {  
  107.  TH0=(65536-2000)/256;        //重新赋值 2ms  
  108.  TL0=(65536-2000)%256;  
  109.    
  110.  Display(0,8);       // 调用数码管扫描  
  111.   
  112. }  
  113.   
  114.   
  115. unsigned char KeyScan(void)  //键盘扫描函数,使用行列逐级扫描法  
  116. {  
  117.  unsigned char Val;  
  118.  KeyPort=0xf0;//高四位置高,低四位拉低  
  119.  if(KeyPort!=0xf0)//表示有按键按下  
  120.    {  
  121.     DelayMs(10);  //去抖  
  122.     if(KeyPort!=0xf0)  
  123.       {           //表示有按键按下  
  124.         KeyPort=0xfe; //检测第一行  
  125.         if(KeyPort!=0xfe)  
  126.             {  
  127.               Val=KeyPort&0xf0;  
  128.               Val+=0x0e;  
  129.               while(KeyPort!=0xfe);  
  130.               DelayMs(10); //去抖  
  131.               while(KeyPort!=0xfe);  
  132.               return Val;  
  133.             }  
  134.         KeyPort=0xfd; //检测第二行  
  135.         if(KeyPort!=0xfd)  
  136.             {  
  137.               Val=KeyPort&0xf0;  
  138.               Val+=0x0d;  
  139.               while(KeyPort!=0xfd);  
  140.               DelayMs(10); //去抖  
  141.               while(KeyPort!=0xfd);  
  142.               return Val;  
  143.             }  
  144.         KeyPort=0xfb; //检测第三行  
  145.         if(KeyPort!=0xfb)  
  146.             {  
  147.               Val=KeyPort&0xf0;  
  148.               Val+=0x0b;  
  149.               while(KeyPort!=0xfb);  
  150.               DelayMs(10); //去抖  
  151.               while(KeyPort!=0xfb);  
  152.               return Val;  
  153.             }  
  154.         KeyPort=0xf7; //检测第四行  
  155.         if(KeyPort!=0xf7)  
  156.             {  
  157.               Val=KeyPort&0xf0;  
  158.               Val+=0x07;  
  159.               while(KeyPort!=0xf7);  
  160.               DelayMs(10); //去抖  
  161.               while(KeyPort!=0xf7);  
  162.               return Val;  
  163.             }  
  164.      }  
  165.    }  
  166.   return 0xff;  
  167. }  
  168.   
  169. unsigned char KeyPro(void)  
  170. {  
  171.  switch(KeyScan())  
  172.  {  
  173.   case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值  
  174.   case 0x7d:return 1;break;//1  
  175.   case 0x7b:return 2;break;//2  
  176.   case 0x77:return 3;break;//3  
  177.   case 0xbe:return 4;break;//4  
  178.   case 0xbd:return 5;break;//5  
  179.   case 0xbb:return 6;break;//6  
  180.   case 0xb7:return 7;break;//7  
  181.   case 0xde:return 8;break;//8  
  182.   case 0xdd:return 9;break;//9  
  183.   case 0xdb:return 10;break;//a  
  184.   case 0xd7:return 11;break;//b  
  185.   case 0xee:return 12;break;//c  
  186.   case 0xed:return 13;break;//d  
  187.   case 0xeb:return 14;break;//e  
  188.   case 0xe7:return 15;break;//f  
  189.   default:return 0xff;break;  
  190.  }  
  191. }  

你可能感兴趣的:(矩阵键盘行列扫描)