找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2072|回复: 0
收起左侧

STC15单片机—矩阵键盘程序的写法

[复制链接]
ID:787358 发表于 2020-6-23 10:58 | 显示全部楼层 |阅读模式
矩阵键盘Proteus仿真
一、Proteus仿真STC15的问题
> 据说P0口存在BUG,不会被正常拉低,而是产生短路。
  • 1
二、原理图1、CPU 51hei.png

2、矩阵键盘 51hei.png

3、显示部分
51hei.png

程序
一、矩阵键盘_单行扫描_普通写法
  1. #include<STC15.H>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define KeyBus P6    //定义矩阵键盘接口

  6. uchar Key_res =0;
  7. uchar i=0;

  8. void GPIO(void);    //IO口初始化函数
  9. void Delay10ms();                //@12.000MHz
  10. void Delay5ms();                //@12.000MHz
  11. void Delay1ms();          //@12.000MHz
  12. uchar Key16_Scan(void);//矩阵键盘扫描函数子程序
  13. void Key16_Function(void); //矩阵键盘服务(功能)子函数

  14. void main(void)
  15. {
  16.     GPIO();

  17.         while(1)
  18.         {
  19.                 Key_res =0;
  20.                 i=Key16_Scan();   //矩阵键盘扫描函数子程序
  21.         Key16_Function(); //矩阵键盘服务(功能)子函数
  22.         }
  23. }

  24. //-----------------------------------IO口初始化函数-----------------------------//
  25. void GPIO(void)
  26. {
  27.         P0M1=0;
  28.         P0M0=0;
  29.         P1M1=0;
  30.         P1M0=0;
  31.         P2M1=0;
  32.         P2M0=0;
  33.         P3M1=0;
  34.         P3M0=0;
  35.         P4M1=0;
  36.         P4M0=0;
  37.         P5M1=0;
  38.         P5M0=0;
  39. }

  40. //------------------------------------软件延时---------------------------------------//
  41. void Delay10ms()                //@12.000MHz
  42. {
  43.         unsigned char i, j;

  44.         i = 117;
  45.         j = 184;
  46.         do
  47.         {
  48.                 while (--j);
  49.         } while (--i);
  50. }

  51. void Delay5ms()                //@12.000MHz
  52. {
  53.         unsigned char i, j;

  54.         i = 59;
  55.         j = 90;
  56.         do
  57.         {
  58.                 while (--j);
  59.         } while (--i);
  60. }

  61. void Delay1ms()                //@12.000MHz
  62. {
  63.         unsigned char i, j;

  64.         i = 12;
  65.         j = 169;
  66.         do
  67.         {
  68.                 while (--j);
  69.         } while (--i);
  70. }



  71. //---------------------------------------矩阵键盘扫描函数子程序-------------------------//

  72. uchar Key16_Scan(void)
  73. {
  74.         uchar temp = 0;
  75.         uchar Key_res = 0;
  76.         
  77.     KeyBus = 0XFF;        
  78.         KeyBus = 0X7F;         //0111 1111 扫描第一行
  79.          temp=KeyBus;
  80.         temp=temp&0X0F;
  81.         if(temp!=0X0F)
  82.         {
  83.           Delay10ms();   //按键消抖
  84.           temp=KeyBus;
  85.           temp=temp&0X0F;
  86.           if(temp!=0X0F)
  87.                 {
  88.                         temp=temp&0X0F;
  89.                         switch(temp)
  90.                         {
  91.                                 case 0X0E: Key_res=16;break;
  92.                                 case 0X0D: Key_res=15;break;
  93.                                 case 0X0B: Key_res=14;break;
  94.                                 case 0X07: Key_res=13;break;
  95.                                 default: break;
  96.                         }
  97.                         while(temp!=0X0F)     //松手检测
  98.                         {
  99.                                 temp=KeyBus;
  100.                                 temp=temp&0X0F;
  101.                         }        
  102.                 }
  103.         }
  104.         
  105.         KeyBus = 0XFF;
  106.         KeyBus = 0XBF;         //1011 1111  扫描第二行
  107.          temp=KeyBus;
  108.         temp=temp&0X0F;
  109.         if(temp!=0X0F)
  110.         {
  111.           Delay10ms();
  112.           temp=KeyBus;
  113.           temp=temp&0X0F;
  114.           if(temp!=0X0F)
  115.                 {
  116.                         temp=temp&0X0F;
  117.                         switch(temp)
  118.                         {
  119.                                 case 0X0E: Key_res=12;break;
  120.                                 case 0X0D: Key_res=11;break;
  121.                                 case 0X0B: Key_res=10;break;
  122.                                 case 0X07: Key_res=9;break;
  123.                                 default: break;
  124.                         }
  125.                         while(temp!=0X0F)     //松手检测
  126.                         {
  127.                                 temp=KeyBus;
  128.                                 temp=temp&0X0F;
  129.                         }        
  130.                 }
  131.         }

  132.         KeyBus = 0XFF;        
  133.         KeyBus = 0XDF;         //1101 1111  扫描第三行
  134.          temp=KeyBus;
  135.         temp=temp&0X0F;
  136.         if(temp!=0X0F)
  137.         {
  138.           Delay10ms();
  139.           temp=KeyBus;
  140.           temp=temp&0X0F;
  141.           if(temp!=0X0F)
  142.                 {
  143.                         temp=temp&0X0F;
  144.                         switch(temp)
  145.                         {
  146.                                 case 0X0E: Key_res=8;break;
  147.                                 case 0X0D: Key_res=7;break;
  148.                                 case 0X0B: Key_res=6;break;
  149.                                 case 0X07: Key_res=5;break;
  150.                                 default: break;
  151.                         }
  152.                         while(temp!=0X0F)    //松手检测
  153.                         {
  154.                                 temp=KeyBus;
  155.                                 temp=temp&0X0F;
  156.                         }        
  157.                 }
  158.         }

  159.         KeyBus = 0XFF;        
  160.         KeyBus = 0XEF;         //1110 1111  扫描第四行
  161.          temp=KeyBus;
  162.         temp=temp&0X0F;
  163.         if(temp!=0X0F)
  164.         {
  165.           Delay10ms();
  166.           temp=KeyBus;
  167.           temp=temp&0X0F;
  168.           if(temp!=0X0F)
  169.                 {
  170.                         temp=temp&0X0F;
  171.                         switch(temp)
  172.                         {
  173.                                 case 0X0E: Key_res=4;break;
  174.                                 case 0X0D: Key_res=3;break;
  175.                                 case 0X0B: Key_res=2;break;
  176.                                 case 0X07: Key_res=1;break;
  177.                                 default: break;
  178.                         }
  179.                         while(temp!=0X0F)     //松手检测
  180.                         {
  181.                                 temp=KeyBus;
  182.                                 temp=temp&0X0F;
  183.                         }        
  184.                 }
  185.         }
  186.         return Key_res;
  187. }


  188. //-----------------------------------矩阵键盘服务(功能)子函数-------------------//
  189. void Key16_Function(void)
  190. {
  191.         if(i != 0)
  192.                 {
  193.                         switch(i)
  194.                         {
  195.                           case  1: P1=0XFE;P2=0XFF;break;
  196.                           case  2: P1=0XFD;P2=0XFF;break;
  197.                       case  3: P1=0XFB;P2=0XFF;break;
  198.                       case  4: P1=0XF7;P2=0XFF;break;
  199.                           case  5: P1=0XEF;P2=0XFF;break;
  200.                           case  6: P1=0XDF;P2=0XFF;break;
  201.                           case  7: P1=0XBF;P2=0XFF;break;
  202.                           case  8: P1=0X7F;P2=0XFF;break;
  203.                           case  9: P1=0XFF;P2=0XFE;break;
  204.                           case 10: P1=0XFF;P2=0XFD;break;
  205.                           case 11: P1=0XFF;P2=0XFB;break;
  206.                           case 12: P1=0XFF;P2=0XF7;break;
  207.                           case 13: P1=0XFF;P2=0XEF;break;
  208.                           case 14: P1=0XFF;P2=0XDF;break;
  209.                           case 15: P1=0XFF;P2=0XBF;break;
  210.                           case 16: P1=0XFF;P2=0X7F;break;
  211.                           default:P1=0X00;P2=0X00;break;
  212.                         }
  213.         }
  214. }
复制代码
二、矩阵键盘_单行扫描_外部中断

(代码未能实现,改进ing)


  1. #include<STC15.H>
  2. #include<intrins.h>


  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define KeyBus P6    //定义矩阵键盘接口

  6. uchar Key_res =0;
  7. uchar i=0;

  8. void GPIO(void);    //IO口初始化函数
  9. void Delay10ms();                //@12.000MHz
  10. void Delay5ms();                //@12.000MHz
  11. void Delay1ms();          //@12.000MHz
  12. void INT1_INIT(void);    //外部中断1初始化函数
  13. uchar Key16_Scan(void);//矩阵键盘扫描函数子程序
  14. void Key16_Function(void); //矩阵键盘服务(功能)子函数

  15. void main(void)
  16. {
  17.   GPIO();
  18.   INT1_INIT();
  19.         while(1)
  20.         {
  21.            KeyBus=0X0F;               
  22.        Key16_Function(); //矩阵键盘服务(功能)子函数
  23.         }
  24. }

  25. //-----------------------------------IO口初始化函数-----------------------------//
  26. void GPIO(void)
  27. {
  28.         P0M1=0;
  29.         P0M0=0;
  30.         P1M1=0;
  31.         P1M0=0;
  32.         P2M1=0;
  33.         P2M0=0;
  34.         P3M1=0;
  35.         P3M0=0;
  36.         P4M1=0;
  37.         P4M0=0;
  38.         P5M1=0;
  39.         P5M0=0;

  40. }

  41. //------------------------------------软件延时---------------------------------------//
  42. void Delay10ms()                //@12.000MHz
  43. {
  44.         unsigned char i, j;

  45.         i = 117;
  46.         j = 184;
  47.         do
  48.         {
  49.                 while (--j);
  50.         } while (--i);
  51. }

  52. void Delay5ms()                //@12.000MHz
  53. {
  54.         unsigned char i, j;

  55.         i = 59;
  56.         j = 90;
  57.         do
  58.         {
  59.                 while (--j);
  60.         } while (--i);
  61. }

  62. void Delay1ms()                //@12.000MHz
  63. {
  64.         unsigned char i, j;

  65.         i = 12;
  66.         j = 169;
  67.         do
  68.         {
  69.                 while (--j);
  70.         } while (--i);
  71. }

  72. //---------------------------------------外部中断1初始化函数-----------------------------//
  73. void INT1_INIT(void)
  74. {
  75.         IT1=1;
  76.         EX1=1;
  77.   EA=1;

  78. }

  79. //---------------------------------------矩阵键盘扫描函数子程序-------------------------//

  80. uchar Key16_Scan(void)
  81. {
  82.         uchar temp = 0;
  83.         uchar Key_res = 0;
  84.         
  85.     KeyBus = 0XFF;        
  86.         KeyBus = 0X7F;         //0111 1111
  87.          temp=KeyBus;
  88.         temp=temp&0X0F;
  89.         if(temp!=0X0F)
  90.         {
  91.           Delay10ms();
  92.           temp=KeyBus;
  93.           temp=temp&0X0F;
  94.           if(temp!=0X0F)
  95.                 {
  96.                         temp=temp&0X0F;
  97.                         switch(temp)
  98.                         {
  99.                                 case 0X0E: Key_res=16;break;
  100.                                 case 0X0D: Key_res=15;break;
  101.                                 case 0X0B: Key_res=14;break;
  102.                                 case 0X07: Key_res=13;break;
  103.                                 default: break;
  104.                         }
  105.                         while(temp!=0X0F)     //松手检测
  106.                         {
  107.                                 temp=KeyBus;
  108.                                 temp=temp&0X0F;
  109.                         }        
  110.                 }
  111.         }
  112.         
  113.         KeyBus = 0XFF;
  114.         KeyBus = 0XBF;         //1011 1111
  115.          temp=KeyBus;
  116.         temp=temp&0X0F;
  117.         if(temp!=0X0F)
  118.         {
  119.           Delay10ms();
  120.           temp=KeyBus;
  121.           temp=temp&0X0F;
  122.           if(temp!=0X0F)
  123.                 {
  124.                         temp=temp&0X0F;
  125.                         switch(temp)
  126.                         {
  127.                                 case 0X0E: Key_res=12;break;
  128.                                 case 0X0D: Key_res=11;break;
  129.                                 case 0X0B: Key_res=10;break;
  130.                                 case 0X07: Key_res=9;break;
  131.                                 default: break;
  132.                         }
  133.                         while(temp!=0X0F)     //松手检测
  134.                         {
  135.                                 temp=KeyBus;
  136.                                 temp=temp&0X0F;
  137.                         }        
  138.                 }
  139.         }

  140.         KeyBus = 0XFF;        
  141.         KeyBus = 0XDF;         //1101 1111
  142.          temp=KeyBus;
  143.         temp=temp&0X0F;
  144.         if(temp!=0X0F)
  145.         {
  146.           Delay10ms();
  147.       temp=KeyBus;
  148.           temp=temp&0X0F;
  149.           if(temp!=0X0F)
  150.                 {
  151.                         temp=temp&0X0F;
  152.                         switch(temp)
  153.                         {
  154.                                 case 0X0E: Key_res=8;break;
  155.                                 case 0X0D: Key_res=7;break;
  156.                                 case 0X0B: Key_res=6;break;
  157.                                 case 0X07: Key_res=5;break;
  158.                                 default: break;
  159.                         }
  160.                         while(temp!=0X0F)    //松手检测
  161.                         {
  162.                                 temp=KeyBus;
  163.                                 temp=temp&0X0F;
  164.                         }        
  165.                 }
  166.         }

  167.         KeyBus = 0XFF;        
  168.         KeyBus = 0XEF;         //1110 1111
  169.          temp=KeyBus;
  170.         temp=temp&0X0F;
  171.         if(temp!=0X0F)
  172.         {
  173.       Delay10ms();
  174.           temp=KeyBus;
  175.           temp=temp&0X0F;
  176.           if(temp!=0X0F)
  177.                 {
  178.                         temp=temp&0X0F;
  179.                         switch(temp)
  180.                         {
  181.                                 case 0X0E: Key_res=4;break;
  182.                                 case 0X0D: Key_res=3;break;
  183.                                 case 0X0B: Key_res=2;break;
  184.                                 case 0X07: Key_res=1;break;
  185.                                 default: break;
  186.                         }
  187.                         while(temp!=0X0F)     //松手检测
  188.                         {
  189.                                 temp=KeyBus;
  190.                                 temp=temp&0X0F;
  191.                         }        
  192.                 }
  193.         }
  194.         return Key_res;
  195. }

  196. //--------------------------------------外部中断1服务函数-----------------------------//
  197. void INT1_ISR() interrupt 2
  198. {
  199.                 i = Key16_Scan();   //矩阵键盘扫描函数子程序
  200. }



  201. //-----------------------------------矩阵键盘服务(功能)子函数-------------------//
  202. void Key16_Function(void)
  203. {
  204.         if(i != 0)
  205.                 {
  206.                         switch(i)
  207.                         {
  208.                           case  1: P1=0XFE;P2=0XFF;break;
  209.                           case  2: P1=0XFD;P2=0XFF;break;
  210.                       case  3: P1=0XFB;P2=0XFF;break;
  211.                       case  4: P1=0XF7;P2=0XFF;break;
  212.                           case  5: P1=0XEF;P2=0XFF;break;
  213.                           case  6: P1=0XDF;P2=0XFF;break;
  214.                           case  7: P1=0XBF;P2=0XFF;break;
  215.                           case  8: P1=0X7F;P2=0XFF;break;
  216.                           case  9: P1=0XFF;P2=0XFE;break;
  217.                           case 10: P1=0XFF;P2=0XFD;break;
  218.                           case 11: P1=0XFF;P2=0XFB;break;
  219.                           case 12: P1=0XFF;P2=0XF7;break;
  220.                           case 13: P1=0XFF;P2=0XEF;break;
  221.                           case 14: P1=0XFF;P2=0XDF;break;
  222.                           case 15: P1=0XFF;P2=0XBF;break;
  223.                           case 16: P1=0XFF;P2=0X7F;break;
  224.                           default:P1=0X00;P2=0X00;break;
  225.                         }
  226.         }
  227. }

复制代码


三、矩阵键盘_多行扫描_普通写法
  1. #include<STC15.H>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define KeyBus P6    //定义矩阵键盘接口

  6. uchar Key_res =0;
  7. uchar i=0;

  8. void GPIO(void);    //IO口初始化函数
  9. void Delay10ms();                //@12.000MHz
  10. void Delay5ms();                //@12.000MHz
  11. void Delay1ms();          //@12.000MHz
  12. uchar Key16_Scan(void);//矩阵键盘扫描函数子程序
  13. void Key16_Function(void); //矩阵键盘服务(功能)子函数

  14. void main(void)
  15. {
  16.   GPIO();    //IO口初始化函数

  17.         while(1)
  18.         {
  19.                 Key_res =0;
  20.                 i=Key16_Scan();   //矩阵键盘扫描函数子程序
  21.     Key16_Function(); //矩阵键盘服务(功能)子函数
  22.         }
  23. }

  24. //-----------------------------------IO口初始化函数-----------------------------//
  25. void GPIO(void)
  26. {
  27.         P0M1=0;
  28.         P0M0=0;
  29.         P1M1=0;
  30.         P1M0=0;
  31.         P2M1=0;
  32.         P2M0=0;
  33.         P3M1=0;
  34.         P3M0=0;
  35.         P4M1=0;
  36.         P4M0=0;
  37.         P5M1=0;
  38.         P5M0=0;

  39. }

  40. //------------------------------------软件延时---------------------------------------//
  41. void Delay10ms()                //@12.000MHz
  42. {
  43.         unsigned char i, j;

  44.         i = 117;
  45.         j = 184;
  46.         do
  47.         {
  48.                 while (--j);
  49.         } while (--i);
  50. }

  51. void Delay5ms()                //@12.000MHz
  52. {
  53.         unsigned char i, j;

  54.         i = 59;
  55.         j = 90;
  56.         do
  57.         {
  58.                 while (--j);
  59.         } while (--i);
  60. }

  61. void Delay1ms()                //@12.000MHz
  62. {
  63.         unsigned char i, j;

  64.         i = 12;
  65.         j = 169;
  66.         do
  67.         {
  68.                 while (--j);
  69.         } while (--i);
  70. }



  71. //---------------------------------------矩阵键盘扫描函数子程序-------------------------//

  72. uchar Key16_Scan(void)
  73. {
  74.         uchar X_temp = 0,Y_temp = 0;
  75.         uchar Key_down = 0;
  76.         
  77.         KeyBus = 0XFF;        
  78.         KeyBus = 0X0F;        //高4位置0,低4位置1,此时有按键按下时,低四位的某一位会被拉低,由此定位按下的按键在第几列
  79.         Y_temp = KeyBus&0X0F;
  80.         
  81.         if(Y_temp!=0X0F)        //如果检测到某列有按键按下(有按键按下时,低四位会有一位被拉低)
  82.         {
  83.                 Delay5ms();    //按键消抖(不知道有无必要)
  84.                 KeyBus = 0X0F;         
  85.             Y_temp = KeyBus&0X0F;//将KeyBus低四位的按键信息赋值给Y_temp
  86.                 if(Y_temp!=0X0F)
  87.                 {
  88.                         KeyBus = 0X0F;
  89.                         Y_temp = KeyBus&0X0F;  //将KeyBus低四位的按键信息赋值给Y_temp,反应列信息
  90.                         KeyBus = 0XF0;
  91.                         X_temp = KeyBus&0XF0;  //将KeyBus高四位的按键信息赋值给X_temp,反应行信息
  92.                         if(Key_down == 0)      //按键抬起检测,        
  93.                         {
  94.                           switch(Y_temp)    //判断列
  95.                           {
  96.                                   case 0X07: Key_res=1; break;
  97.                                   case 0X0B: Key_res=2; break;
  98.                                   case 0X0D: Key_res=3; break;
  99.                                   case 0X0E: Key_res=4; break;
  100.                                   default: return 0;    //无按键按下,返回0
  101.                           }
  102.                          switch(X_temp)    //判断行
  103.                           {
  104.                                 case 0X70: return Key_res+12;break;
  105.                              case 0XB0: return Key_res+ 8;break;
  106.                 case 0XD0: return Key_res+ 4;break;
  107.                 case 0XE0: return Key_res;   break;
  108.                 default: return 0;         //无按键按下,返回0        
  109.                          }
  110.                  }
  111.          }
  112.         }
  113.         else
  114.                 Key_down = 0;        //按键被松开
  115.         
  116.         if(Key_res)
  117.                 Key_down = 1;        //标志按键被按下,防止重入

  118.         return Key_res;
  119. }
  120.    

  121. //-----------------------------------矩阵键盘服务(功能)子函数-------------------//
  122. void Key16_Function(void)
  123. {
  124.         if(i != 0)    //按键按下
  125.                 {
  126.                         switch(i)
  127.                         {
  128.                           case  1: P1=0XFE;P2=0XFF;break;
  129.                           case  2: P1=0XFD;P2=0XFF;break;
  130.                       case  3: P1=0XFB;P2=0XFF;break;
  131.                       case  4: P1=0XF7;P2=0XFF;break;
  132.                           case  5: P1=0XEF;P2=0XFF;break;
  133.                           case  6: P1=0XDF;P2=0XFF;break;
  134.                           case  7: P1=0XBF;P2=0XFF;break;
  135.                           case  8: P1=0X7F;P2=0XFF;break;
  136.                           case  9: P1=0XFF;P2=0XFE;break;
  137.                           case 10: P1=0XFF;P2=0XFD;break;
  138.                           case 11: P1=0XFF;P2=0XFB;break;
  139.                           case 12: P1=0XFF;P2=0XF7;break;
  140.                           case 13: P1=0XFF;P2=0XEF;break;
  141.                           case 14: P1=0XFF;P2=0XDF;break;
  142.                           case 15: P1=0XFF;P2=0XBF;break;
  143.                           case 16: P1=0XFF;P2=0X7F;break;
  144.                           default:P1=0X00;P2=0X00;break;
  145.                         }
  146.         }
  147. }
复制代码



四、矩阵键盘_多行扫描_外部中断

(仅能检测到列,检测不到行,改进ing)


  1. #include<STC15.H>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define KeyBus P6    //定义矩阵键盘接口

  6. uchar Key_res =0;
  7. uchar i=0;

  8. void GPIO(void);    //IO口初始化函数
  9. void Delay10ms();                //@12.000MHz
  10. void Delay5ms();                //@12.000MHz
  11. void Delay1ms();          //@12.000MHz
  12. void INT1_INIT(void); //外部中断1初始化函数
  13. uchar Key16_Scan(void);//矩阵键盘扫描函数子程序
  14. void Key16_Function(void); //矩阵键盘服务(功能)子函数

  15. void main(void)
  16. {
  17.    GPIO();    //IO口初始化函数
  18.    INT1_INIT();
  19.         while(1)
  20.         {
  21.           KeyBus = 0X0F;
  22.       Key16_Function(); //矩阵键盘服务(功能)子函数
  23.         }
  24. }

  25. //-----------------------------------IO口初始化函数-----------------------------//
  26. void GPIO(void)
  27. {
  28.         P0M1=0;
  29.         P0M0=0;
  30.         P1M1=0;
  31.         P1M0=0;
  32.         P2M1=0;
  33.         P2M0=0;
  34.         P3M1=0;
  35.         P3M0=0;
  36.         P4M1=0;
  37.         P4M0=0;
  38.         P5M1=0;
  39.         P5M0=0;

  40. }

  41. //------------------------------------软件延时---------------------------------------//
  42. void Delay10ms()                //@12.000MHz
  43. {
  44.         unsigned char i, j;

  45.         i = 117;
  46.         j = 184;
  47.         do
  48.         {
  49.                 while (--j);
  50.         } while (--i);
  51. }

  52. void Delay5ms()                //@12.000MHz
  53. {
  54.         unsigned char i, j;

  55.         i = 59;
  56.         j = 90;
  57.         do
  58.         {
  59.                 while (--j);
  60.         } while (--i);
  61. }

  62. void Delay1ms()                //@12.000MHz
  63. {
  64.         unsigned char i, j;

  65.         i = 12;
  66.         j = 169;
  67.         do
  68.         {
  69.                 while (--j);
  70.         } while (--i);
  71. }

  72. //---------------------------------------外部中断1初始化函数-----------------------------//
  73. void INT1_INIT(void)
  74. {
  75.         IT1=1;
  76.         EX1=1;
  77.     EA=1;

  78. }

  79. //---------------------------------------矩阵键盘扫描函数子程序-------------------------//

  80. uchar Key16_Scan(void)
  81. {

  82.         uchar X_temp = 0,Y_temp = 0;
  83.         uchar Key_down = 0;
  84.         
  85.         KeyBus = 0XFF;        
  86.         KeyBus = 0X0F;        //高4位置0,低4位置1,此时有按键按下时,低四位的某一位会被拉低,由此定位按下的按键在第几列
  87.         Y_temp = KeyBus&0X0F;
  88.         
  89.         if(Y_temp!=0X0F)        //如果检测到某列有按键按下(有按键按下时,低四位会有一位被拉低)
  90.         {
  91.                 Delay1ms();    //按键消抖(不知道有无必要)
  92.                 KeyBus = 0X0F;         
  93.             Y_temp = KeyBus&0X0F;//将KeyBus低四位的按键信息赋值给Y_temp
  94.                 if(Y_temp!=0X0F)
  95.                 {
  96.                         KeyBus = 0X0F;
  97.                         Y_temp = KeyBus&0X0F;  //将KeyBus低四位的按键信息赋值给Y_temp,反应列信息
  98.                         KeyBus = 0XF0;
  99.                         X_temp = KeyBus&0XF0;  //将KeyBus高四位的按键信息赋值给X_temp,反应行信息
  100.                         if(Key_down == 0)      //按键抬起检测,        
  101.                         {
  102.                           switch(Y_temp)    //判断列
  103.                           {
  104.                                   case 0X07: Key_res=1; break;
  105.                                   case 0X0B: Key_res=2; break;
  106.                                   case 0X0D: Key_res=3; break;
  107.                                   case 0X0E: Key_res=4; break;
  108.                                   default: return 0;    //无按键按下,返回0
  109.                           }
  110.                          switch(X_temp)    //判断行
  111.                           {
  112.                                 case 0X70: return Key_res+12;break;
  113.                                    case 0XB0: return Key_res+ 8;break;
  114.                 case 0XD0: return Key_res+ 4;break;
  115.                 case 0XE0: return Key_res;   break;
  116.                 default: return 0;         //无按键按下,返回0        
  117.                          }
  118.                  }
  119.          }
  120.         }
  121.         else
  122.                 Key_down = 0;        //按键被松开
  123.         
  124.         if(Key_res)
  125.                 Key_down = 1;        //标志按键被按下,防止重入

  126.         return Key_res;
  127. }
  128.    
  129. //--------------------------------------外部中断1服务函数-----------------------------//
  130. void INT1_ISR() interrupt 2
  131. {
  132.                 i = Key16_Scan();   //矩阵键盘扫描函数子程序
  133. }

  134. //-----------------------------------矩阵键盘服务(功能)子函数-------------------//
  135. void Key16_Function(void)
  136. {
  137.         EX1=0;
  138.         if(i != 0)    //按键按下
  139.                 {
  140.                         switch(i)
  141.                         {
  142.                           case  1: P1=0XFE;P2=0XFF;break;
  143.                           case  2: P1=0XFD;P2=0XFF;break;
  144.                       case  3: P1=0XFB;P2=0XFF;break;
  145.                       case  4: P1=0XF7;P2=0XFF;break;
  146.                           case  5: P1=0XEF;P2=0XFF;break;                                    
  147.                           case  6: P1=0XDF;P2=0XFF;break;
  148.                           case  7: P1=0XBF;P2=0XFF;break;
  149.                           case  8: P1=0X7F;P2=0XFF;break;
  150.                           case  9: P1=0XFF;P2=0XFE;break;
  151.                           case 10: P1=0XFF;P2=0XFD;break;
  152.                           case 11: P1=0XFF;P2=0XFB;break;
  153.                           case 12: P1=0XFF;P2=0XF7;break;
  154.                           case 13: P1=0XFF;P2=0XEF;break;
  155.                           case 14: P1=0XFF;P2=0XDF;break;
  156.                           case 15: P1=0XFF;P2=0XBF;break;
  157.                           case 16: P1=0XFF;P2=0X7F;break;
  158.                           default:P1=0X00;P2=0X00;break;
  159.                         }
  160.         }
  161.         EX1=1;
  162. }

复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表