找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 439|回复: 1
收起左侧

包含长短按组合按键的单片机矩阵键盘扫描C语言程序

[复制链接]
ID:467203 发表于 2024-2-26 16:33 | 显示全部楼层 |阅读模式
分享一个刚开始学51时的一个矩阵键盘扫描程序
算法还是比较简单的,供初学者学习
单片机源程序如下:
  1. <span style="line-height: 1.5;">//此程序可以实现短按键、长按键、组合键三种操作。双击按键操作还未实现,要进一步研究</span>
  2. //
  3. #include<reg52.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. uchar flag;

  7. uchar key;
  8. bit key_flag;
  9. bit time_10ms_ok=0;
  10. bit time_2ms_ok=0;
  11. sbit dula=P2^6;                //段选信号的锁存器控制
  12. sbit wela=P2^7;                //位选信号的锁存器控

  13. uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  14.                         0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  15. uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
  16.                                                 //数码管各位的码表
  17. void delay(unsigned int i)
  18. {
  19. unsigned int m,n;
  20. for(m=i;m>0;m--)
  21. for(n=90;n>0;n--);
  22. }

  23. void display(uchar a,b,c,d,e,f)
  24. {
  25. P0=table[a];
  26. dula=1;
  27. dula=0;
  28. P0=wei[0];
  29. wela=1;
  30. wela=0;
  31. delay(5);

  32. P0=table[b];
  33. dula=1;
  34. dula=0;
  35. P0=wei[1];
  36. wela=1;
  37. wela=0;
  38. delay(5);

  39. P0=table[c];
  40. dula=1;
  41. dula=0;
  42. P0=wei[2];
  43. wela=1;
  44. wela=0;
  45. delay(5);

  46. P0=table[d];
  47. dula=1;
  48. dula=0;
  49. P0=wei[3];
  50. wela=1;
  51. wela=0;
  52. delay(5);

  53. P0=table[e];
  54. dula=1;
  55. dula=0;
  56. P0=wei[4];
  57. wela=1;
  58. wela=0;
  59. delay(5);

  60. P0=table[f];
  61. dula=1;
  62. dula=0;
  63. P0=wei[5];
  64. wela=1;
  65. wela=0;
  66. delay(5);
  67. }


  68. void InitTimer0(void)
  69. {
  70.   TMOD = 0x01;
  71.   TH0 = 0xFC;//延时1ms,请在中断处理函数中,重新装入该数值。
  72.   TL0 = 0x6;
  73.   TR0=1;
  74.   EA = 1;
  75.   ET0 = 1;
  76. }

  77. void Timer0Interrupt(void) interrupt 1
  78. {
  79. TH0 = 0xFC;//延时1ms,请在中断处理函数中,重新装入该数值。
  80. TL0 = 0x6;
  81. flag++;
  82. if(flag==10)
  83. {flag=0;
  84.   time_10ms_ok=1;}
  85. if(flag%2==0)
  86.   time_2ms_ok=1;
  87. }


  88. uchar KeyRead( void )
  89. {
  90.   uchar ReadData;        // 读按键的实时值
  91.   static uchar i;         //长按键按下时间计数
  92.   static uchar trg,cont,cont1;        //按键按下时的状态,trg用来描述短按键,cont用来描述长按键

  93.   P3=0x0f;
  94.   ReadData=P3;
  95.   P3=0xf0;
  96.   ReadData=(ReadData | P3)^0xff;

  97. //if...else;        语句作用 是当第一次按键按下时,退出按键扫描程序,
  98. //一来可以实现消抖,二来可以防止第一次按下按键时,程序刚好执行到按键扫描程序的中间部分,造成结果不准确
  99.   if(ReadData==cont1)                                          
  100.   {
  101.    trg  = ReadData & (ReadData ^ cont);
  102.    cont = ReadData;
  103.   }
  104.    else
  105.   {
  106.    cont1=ReadData;
  107.   return;
  108.    }


  109.   if(cont)                                        //长按键计时
  110.   {
  111.    i++;
  112.   }
  113.   else                                           //按键释放时
  114.   {
  115.   i=0;
  116.   return;
  117.   }


  118. switch(trg)
  119. {
  120.   case 0x11:   key=0;key_flag=1;  break;
  121.   case 0x21:   key=1;key_flag=1;  break;
  122.   case 0x41:   key=2;key_flag=1;  break;
  123.   case 0x61:   key=8;key_flag=1;  break;  //1和2同时按下组成的组合键
  124.   case 0x81:   key=3;key_flag=1;  break;
  125.   case 0x12:   key=4;key_flag=1;  break;
  126.   case 0x22:   key=5;key_flag=1;  break;
  127.   case 0x42:   key=6;key_flag=1;  break;
  128.   case 0x82:   key=7;key_flag=1;  break;   
  129.   case 0x14:   key=8;key_flag=1;  break;
  130.   case 0x24:   key=9;key_flag=1;  break;
  131.   case 0x44:   key=10;key_flag=1; break;
  132.   case 0x84:   key=11;key_flag=1; break;
  133.   case 0x18:   key=12;key_flag=1;  break;
  134.   case 0x28:   key=13;key_flag=1;  break;
  135.   case 0x48:   key=14;key_flag=1; break;
  136.   case 0x88:   key=15;key_flag=1;  break;
  137. }

  138. if(i==100)
  139. {
  140.   i=90;
  141.   switch(cont)
  142.   {
  143.    case 0x11:   key++;key_flag=1;  break;
  144.   case 0x21:   key++;;key_flag=1;  break;
  145.   case 0x41:   key++;;key_flag=1;  break;
  146.   case 0x81:   key++;;key_flag=1;  break;
  147.   case 0x12:   key++;;key_flag=1;  break;
  148.   case 0x22:   key++;;key_flag=1;  break;
  149.   case 0x42:   key++;;key_flag=1;  break;
  150.   case 0x82:   key++;;key_flag=1;  break;   
  151.   case 0x14:   key++;;key_flag=1;  break;
  152.   case 0x24:   key++;;key_flag=1;  break;
  153.   case 0x44:   key++;;key_flag=1; break;
  154.   case 0x84:   key++;;key_flag=1; break;
  155.   case 0x18:   key++;;key_flag=1;  break;
  156.   case 0x28:   key++;;key_flag=1;  break;
  157.   case 0x48:   key++;;key_flag=1; break;
  158.   case 0x88:   key++;;key_flag=1;  break;     
  159.   }
  160. }
  161. return key;
  162. }

  163. void main(void)
  164. {
  165. uchar a,b,c,d,e,f;
  166. InitTimer0();
  167. while(1)
  168. {
  169. if(key_flag )
  170.   {
  171.     key_flag=0;
  172.     f=e;
  173.     e=d;
  174.     d=c;
  175.     c=b;
  176.     b=a;
  177.     a=key;
  178.   }       
  179.   if(time_10ms_ok)
  180.    {
  181.     time_10ms_ok=0;
  182.     KeyRead();

  183.    }
  184.   display(a,b,c,d,e,f);
  185. }
  186. }
复制代码


回复

使用道具 举报

ID:1064915 发表于 2024-2-27 10:42 | 显示全部楼层
TH0 = 0xFC;//延时1ms,51@11.0592mhz
TL0 = 0x66;
漏写6
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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