[51单片机] 基于stc89c52的4*4矩阵键盘输入数码管

[复制链接]
1670|3
 楼主| 大苏牙 发表于 2015-8-27 11:00 | 显示全部楼层 |阅读模式
///////////////////////////////////////////////////////////////////////////
实现功能:  完成独立按键的测试,当key5-key20这二十个按键中,有一个按下时,
             则在开发板的第一个数码管上会显示具体的数值,显示的数值是这样
    定义的,key5按下时,显示0,key6按下时显示2,然后依次这样类推,
    达到按下去相应的值显示相应数值的功能
实验板型号:BS-XYD-C52
实验名称:  静态数码管
编写人:  TabLee
  1. #include<reg52.h>
  2. #include <intrins.h>
  3.                     
  4. #define uchar unsigned char  //定义unsigned char 为 uchar
  5. #define uint  unsigned int

  6. sbit Duan=P2^6;     //定义数码管的段选使能端
  7. sbit Wei =P2^7;        //定义数码管的位选使能端

  8. #define Digital_tube_Wei_Enable Wei=1;  //开启控制数码管的位选使能端
  9. #define Digital_tube_Wei_Disable Wei=0;     //关闭控制数码管的位选使能端

  10. #define Digital_tube_Duan_Enable Duan=1; //开启控制数码管的段选使能端
  11. #define Digital_tube_Duan_Disable Duan=0; //关闭控制数码管的段选使能端

  12. #define Digital_tube_Duan P0    //定义数码管数据端口

  13. #define KEY_DOWN  0
  14. #define Keyport P3

  15. uchar code Dis_table[]=       //将BCD码转换成数码管扫描码的数组
  16. {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,
  17.                                                             0x79,0x71};
  18. uchar code Dis_Position[]=  //定义数码管位选的数组
  19. {0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
  20. ///////////////////////////////////////////////////////////////////////////
  21. 函数名称:毫秒延时函数
  22. 函数功能:实现毫秒级的延时
  23. 参数介绍:Delay_MS: 定义需要延时的毫秒的数值
  24.           iNumber: 记录Delay_MS的数值,以for语句实现所要求的延时
  25.     iValue: 要延时毫秒所要进行的循环数值,本数值为实际测得
  26. 返回值:  无
  27. 注意事项:本实验是在所用晶振为12M的前提下实现的毫秒延时,本函数是通过循环的形
  28.           式完成,所以如果改变了晶振的频率,请做相应的改变
  29. ///////////////////////////////////////////////////////////////////////////
  30. void DelayMs(uint Delay_MS)
  31. {
  32. uint iNumber,iValue;
  33. for(iNumber=0;iNumber<Delay_MS;iNumber++)
  34. {
  35.      iValue=107;
  36.      while(iValue--);
  37. }
  38. }
  39. ///////////////////////////////////////////////////////////////////////////

  40. 函数名称:One_DigitalTube_display
  41. 函数功能:完成在实验板上数码管指定显示,即在特定的数码管上显示特定的数字,比
  42.           在第一个数码管上显示0
  43. 参数介绍:uData:要显示的数字的BCD码数组
  44.           uNumber:选择哪个数码管显示,即让某个特定数码管显示
  45. 返回值:  无
  46. 注意事项:实验板上的数码管是共阴极的数码管,如果使用共阳极的数码管,请注意不
  47.           要弄反了
  48. ///////////////////////////////////////////////////////////////////////////

  49. void One_DigitalTube_display(uchar uData,uchar uNumber)
  50. {
  51.   Digital_tube_Duan=Dis_Position[uNumber]; //点亮特定的数码管
  52.   Digital_tube_Wei_Enable;      //使能数码管的位选
  53.   Digital_tube_Wei_Disable;      //关闭数码管的位选
  54.   DelayMs(5);         //调整时序,以实现稳定显示

  55.   Digital_tube_Duan_Enable;      //使能数码管的段选
  56.   Digital_tube_Duan=Dis_table[uData];//输入所要显示的数值
  57.   Digital_tube_Duan_Disable;      //关闭数码管的段选
  58. }
  59. ///////////////////////////////////////////////////////////////////////////
  60. 函数名称:Scan_Keyboard
  61. 函数功能:这是一个矩阵键盘扫描函数,主要是测试是否有按键按下,此函数是按一列
  62.           一列的形式扫描的,如果有按键按下,近一步判断是哪个按键按下,然后显
  63.     示在数码管上显示相应的数值
  64. 参数介绍:cTemp_Value: 记录按键端口数值的临时变量
  65. 返回值:  无
  66. 注意事项:无
  67. ///////////////////////////////////////////////////////////////////////////

  68. void Scan_Keyboard()
  69. {
  70. uchar cTemp_Value;
  71. //扫描矩阵键盘的第一列
  72. Keyport=0xef;              //赋给键盘端口特定的值,以实现后面的检测
  73. cTemp_Value=Keyport;   //把键盘端口值赋给临时变量
  74. if(cTemp_Value!=0xef)
  75. {
  76.   DelayMs(10);       //消除抖动,即消除干扰
  77.         cTemp_Value=Keyport;  //重新赋值于临时值
  78.         if(cTemp_Value!=0xef)   //再次检查
  79.         while((Keyport&0x0F)!=0x0F)  //再次判断是否有按键按下
  80.   {
  81.       switch(cTemp_Value)   
  82.       {
  83.        case 0xee:
  84.          One_DigitalTube_display(0,0);break;  //第五个按键按下,显示0
  85.        case 0xed:
  86.          One_DigitalTube_display(4,0);break;  //第九个按键按下,显示4
  87.        case 0xeb:
  88.          One_DigitalTube_display(8,0);break;  //第十三个按键按下,显示8
  89.        case 0xe7:
  90.          One_DigitalTube_display(12,0);break;  //第十七个按键按下,显示C
  91.       }
  92.   }
  93. }
  94. //扫描矩阵键盘的第二列
  95. Keyport=0xdf;              //赋给键盘端口特定的值,以实现后面的检测
  96. cTemp_Value=Keyport;   //把键盘端口值赋给临时变量
  97. if(cTemp_Value!=0xdf)
  98. {
  99.   DelayMs(10);       //消除抖动,即消除干扰
  100.         cTemp_Value=Keyport;  //重新赋值于临时值
  101.         if(cTemp_Value!=0xdf)   //再次检查
  102.         while((Keyport&0x0F)!=0x0F)    //再次判断是否有按键按下
  103.   {
  104.       switch(cTemp_Value)   
  105.       {
  106.        case 0xde:
  107.          One_DigitalTube_display(1,0);break;  //第六个按键按下,显示1
  108.        case 0xdd:
  109.          One_DigitalTube_display(5,0);break;  //第十个按键按下,显示5
  110.        case 0xdb:
  111.          One_DigitalTube_display(9,0);break;  //第十四个按键按下,显示9
  112.        case 0xd7:
  113.          One_DigitalTube_display(13,0);break;  //第十八个按键按下,显示D
  114.       }
  115.   }
  116. }
  117. //扫描矩阵键盘的第三列
  118. Keyport=0xbf;              //赋给键盘端口特定的值,以实现后面的检测
  119. cTemp_Value=Keyport;   //把键盘端口值赋给临时变量
  120. if(cTemp_Value!=0xbf)
  121. {
  122.   DelayMs(10);       //消除抖动,即消除干扰
  123.         cTemp_Value=Keyport;  //重新赋值于临时值
  124.         if(cTemp_Value!=0xbf)   //再次检查
  125.         while((Keyport&0x0F)!=0x0F)   //再次判断是否有按键按下
  126.   {
  127.       switch(cTemp_Value)   
  128.       {
  129.        case 0xbe:
  130.          One_DigitalTube_display(2,0);break;  //第七个按键按下,显示2
  131.        case 0xbd:
  132.          One_DigitalTube_display(6,0);break;  //第十一个按键按下,显示6
  133.        case 0xbb:
  134.          One_DigitalTube_display(10,0);break;  //第十五个按键按下,显示A
  135.        case 0xb7:
  136.          One_DigitalTube_display(14,0);break;  //第十九个按键按下,显示E
  137.       }
  138.   }
  139. }
  140. //扫描矩阵键盘的第四列
  141. Keyport=0x7f;              //赋给键盘端口特定的值,以实现后面的检测
  142. cTemp_Value=Keyport;   //把键盘端口值赋给临时变量
  143. if(cTemp_Value!=0x7f)
  144. {
  145.   DelayMs(10);       //消除抖动,即消除干扰
  146.         cTemp_Value=Keyport;  //重新赋值于临时值
  147.         if(cTemp_Value!=0x7f)   //再次检查
  148.         while((Keyport&0x0F)!=0x0F)    //再次判断是否有按键按下
  149.   {
  150.       switch(cTemp_Value)   
  151.       {
  152.        case 0x7e:
  153.          One_DigitalTube_display(3,0);break;  //第八个按键按下,显示3
  154.        case 0x7d:
  155.          One_DigitalTube_display(7,0);break;  //第十二个按键按下,显示7
  156.        case 0x7b:
  157.          One_DigitalTube_display(11,0);break;  //第十六个按键按下,显示B
  158.        case 0x77:
  159.          One_DigitalTube_display(15,0);break;  //第二十个按键按下,显示F
  160.       }
  161.   }
  162. }
  163. }
  164. ///////////////////////////////////////////////////////////////////////////

  165. 函数名称:main
  166. 函数功能:不断地循环扫描键盘,当有按键按下时,则在数码管上显示相应的数值
  167. 参数介绍:无
  168. 返回值:  无
  169. 注意事项:无
  170. ///////////////////////////////////////////////////////////////////////////

  171. void main()
  172. {
  173. DelayMs(50);
  174. while(1)
  175. {
  176.   Scan_Keyboard();    //调用键盘扫描函数
  177. }
  178. }



ayb_ice 发表于 2015-8-27 14:37 | 显示全部楼层
这样的代码只能DEMO用,我在主循环中加个任务,执行时间长短不一就挂了,

舒斯特尔 发表于 2015-8-27 16:01 | 显示全部楼层
代码里面有消抖的程序,看看用的什么算法
cjseng 发表于 2015-8-27 16:40 | 显示全部楼层
ayb_ice 发表于 2015-8-27 14:37
这样的代码只能DEMO用,我在主循环中加个任务,执行时间长短不一就挂了,

...

这个你多虑了,只要开始做实际的项目,他自然会想办法解决的。:lol
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

278

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部