开发者社区> 文艺小青年> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

MSP430学习笔记7-4*4键盘的对应数码管显示

简介:
+关注继续查看

  这个例程也是开发板上面的一个经典例程,我对程序的框架进行了修改,更适合以后的调用。具体的4*4键盘扫描原理较为基础这里不再赘述,这里我认为比较重要的是要养成一个良好的写程序的习惯,想4*4键盘扫描这样的函数可以写成一个固定的C或者H文件,便于以后调用。先看看主程序:

  1. /*********************************************** 
  2. 程序功能:扫描4X4键盘并将键值在数码管上显示 
  3.  
  4. ------------------------------------------------ 
  5. 测试说明:按动K1~K16按键,观察数码管显示 
  6. ************************************************/  
  7. #include <msp430x14x.h>  
  8. #include "Keypad.C"  
  9.   
  10. //数码管7位段码:0--f  
  11. unsigned char scandata[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,  
  12.                               0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};  
  13. //记录显示位数的全局变量  
  14. unsigned char cnt = 0;  
  15. //显示缓存  
  16. unsigned char Dispbuf[2];  
  17.   
  18. //引用外部变量的声明  
  19. extern unsigned char key_Pressed;        
  20. extern unsigned char key_val;           
  21. extern unsigned char key_Flag;   
  22.   
  23.   
  24. /********************主函数********************/  
  25. void main(void)  
  26. {  
  27.     /*下面六行程序关闭所有的IO口*/  
  28.     P1DIR = 0XFF;P1OUT = 0XFF;  
  29.     P2DIR = 0XFF;P2OUT = 0XFF;  
  30.     P3DIR = 0XFF;P3OUT = 0XFF;  
  31.     P4DIR = 0XFF;P4OUT = 0XFF;  
  32.     P5DIR = 0XFF;P5OUT = 0XFF;  
  33.     P6DIR = 0XFF;P6OUT = 0XFF;  
  34.     
  35.     P6DIR |= BIT2;P6OUT |= BIT2;  //关闭电平转换        
  36.     WDTCTL = WDT_ADLY_1_9;        //设置内部看门狗工作在定时器模式,1.9ms中断一次  
  37.     IE1 |= WDTIE;                 //使能看门狗中断  
  38.     
  39.     _EINT();                      //打开全局中断  
  40.     Init_Keypad();  
  41.     while(1)  
  42.     {  
  43.         Key_Event();  
  44.       
  45.         if(key_Flag == 1)  
  46.         {  
  47.             key_Flag = 0;  
  48.             Dispbuf[1] = key_val / 10;  
  49.             Dispbuf[0] = key_val % 10;  
  50.               
  51.         }  
  52.     }  
  53. }  
  54. /******************************************* 
  55. 函数名称:watchdog_timer 
  56. 功    能:看门狗中断服务函数,在这里输出数码管的 
  57.           段选和位选信号 
  58. 参    数:无 
  59. 返回值  :无 
  60. ********************************************/  
  61. #pragma vector=WDT_VECTOR  
  62. __interrupt void watchdog_timer(void)  
  63. {   
  64.     P4OUT = 0xff;  
  65.     P5OUT = scandata[Dispbuf[cnt]];         //输出段选信号  
  66.     P4OUT &= ~(1 << (cnt+2));               //输出位选信号  
  67.     
  68.     cnt++;                                  //位计数变量在0~1之间循环  
  69.     if(cnt == 2) cnt = 0;  
  70. }  

      主程序较为简单,具体的原理参见上一个笔记,在主程序中与键盘扫描相关的函数被击中在Keypad.C中,需要说明的是在主函数中需要对Keypad.C的部分变量做声明,这样才能使用Keypad.C中的变量。Keypad.C代码如下:

  1. /******************************************************** 
  2. 4*4键盘扫描函数 
  3. 作者:孙浩 
  4. 修改时间:2010.8.2 
  5. 程序说明: 
  6. 此程序以开发板的例程做部分修改,更方便程序调用。 
  7. 在调用之前需要注意需要在主函数中对程序中使用的变量做外部变量声明 
  8. 需要在主函数中声明的变量如下: 
  9. //引用外部变量的声明 
  10. extern unsigned char key_Pressed; //按键是否被按下:1--是,0--否      
  11. extern unsigned char key_val;     //存放键值     
  12. extern unsigned char key_Flag;    //按键是否已放开:1--是,0--否 
  13. 另外对应的键值可以在本文件的全局变量中修改,只需要对应修改 
  14. 数组uchar key_Map[]的对应的值即可。 
  15. 调用示例如下: 
  16. Init_Keypad();        //先进行初始化 
  17.     while(1) 
  18.     { 
  19.         Key_Event();  //在死循环中进行键值扫描 
  20.      
  21.         if(key_Flag == 1)//用来判断有无按键按下,从而读取键值进行操作 
  22.         { 
  23.             key_Flag = 0;//key_Flag需要手动清零 
  24.         } 
  25.     } 
  26. **********************************************************/  
  27. #include  <msp430x14x.h>  
  28. //相应的函数声明  
  29. void Init_Keypad(void);//键盘初始化  
  30. void Check_Key(void);  
  31. void delay();  
  32. void Key_Event(void);//读取键盘函数,在使用时通过此函数进行键盘扫描  
  33.   
  34. //选择对应的端口  
  35. #define KEYOUT P1OUT  
  36. #define KEYIN P1IN  
  37. #define KEYDIR P1DIR  
  38.   
  39. typedef unsigned char uchar;  
  40. typedef unsigned int  uint;  
  41.   
  42. /***************全局变量***************/  
  43. uchar key_Pressed;      //按键是否被按下:1--是,0--否  
  44. uchar key_val;          //存放键值  
  45. uchar key_Flag;         //按键是否已放开:1--是,0--否  
  46. //设置键盘逻辑键值与程序计算键值的映射  
  47. uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};  
  48.   
  49. /******************************************* 
  50. 函数名称:Init_Keypad 
  51. 功    能:初始化扫描键盘的IO端口 
  52. 参    数:无 
  53. 返回值  :无 
  54. ********************************************/  
  55. void Init_Keypad(void)  
  56. {       
  57.     KEYDIR = 0xf0;       //KEY.0~KEY.3设置为输入状态, KEY.4~KEY.7设置为输出状态  
  58.     KEYOUT |= 0xf0;      // KEY.4~KEY.7输出高电平  
  59.     key_Flag = 0;         
  60.     key_Pressed = 0;     
  61.     key_val = 0;  
  62. }  
  63. /********************************************* 
  64. * Check_Key(),检查按键,确认键值 
  65. *********************************************/  
  66. /******************************************* 
  67. 函数名称:Check_Key 
  68. 功    能:扫描键盘的IO端口,获得键值 
  69. 参    数:无 
  70. 返回值  :无 
  71. ********************************************/  
  72. void Check_Key(void)  
  73. {  
  74.     uchar row ,col,tmp1,tmp2;  
  75.       
  76.     tmp1 = 0x80;  
  77.     for(row = 0;row < 4;row++)              //行扫描  
  78.     {  
  79.         KEYOUT = 0xf0;                      //KEY.4~KEY.7输出全1  
  80.         KEYOUT -= tmp1;                      //KEY.4~p1.7输出四位中有一个为0  
  81.         tmp1 >>=1;                                
  82.         if ((KEYIN & 0x0f) < 0x0f)           //是否KEYIN的KEY.0~KEY.3中有一位为0  
  83.         {                         
  84.             tmp2 = 0x01;                         // tmp2用于检测出那一位为0    
  85.             for(col = 0;col < 4;col++)              // 列检测   
  86.             {            
  87.                 if((KEYIN & tmp2) == 0x00)           // 是否是该列,等于0为是  
  88.                 {            
  89.                     key_val = key_Map[row * 4 + col];  // 获取键值  
  90.                     return;                         // 退出循环  
  91.                 }  
  92.                 tmp2 <<= 1;                        // tmp2右移1位   
  93.             }  
  94.         }  
  95.     }        
  96. }  
  97. /******************************************* 
  98. 函数名称:delay 
  99. 功    能:延时约15ms,完成消抖功能 
  100. 参    数:无 
  101. 返回值  :无 
  102. ********************************************/  
  103. void delay()  
  104. {  
  105.     uint tmp;  
  106.        
  107.     for(tmp = 12000;tmp > 0;tmp--);  
  108. }  
  109. /******************************************* 
  110. 函数名称:Key_Event 
  111. 功    能:检测按键,并获取键值 
  112. 参    数:无 
  113. 返回值  :无 
  114. ********************************************/  
  115. void Key_Event(void)  
  116. {       
  117.     uchar tmp;  
  118.        
  119.     KEYOUT &= 0x00;              // 设置KEYOUT全为0,等待按键输入  
  120.     tmp = KEYIN;                 // 获取 p1IN  
  121.     if ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下  
  122.     {                       
  123.         key_Pressed = 1;        // 如果有按键按下,设置key_Pressed标识  
  124.         delay();                //消除抖动  
  125.         Check_Key();            // 调用check_Key(),获取键值   
  126.     }       
  127.     else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放  
  128.     {                       
  129.         key_Pressed = 0;        // 清除key_Pressed标识  
  130.         key_Flag    = 1;        // 设置key_Flag标识  
  131.     }  
  132.     else   
  133.     {  
  134.         _NOP();  
  135.     }       
  136. }  

具体的注意提防都已经在注释中做了说明,在原来的程序中这个文件是分为Keypad.C和Keypad.h两个文件,键盘扫描函数的声明单独为一个头文件,我觉得并不是特别需要。源程序中全局变量是单独列为一个头文件gdata.h的。这样在全局变量比较多的情况下可以使程序更有条理可以参考。

本文转自emouse博客园博客,原文链接:http://www.cnblogs.com/emouse/archive/2010/08/02/2198218.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
MQ 介绍|学习笔记
快速学习 MQ 介绍
7 0
JAP4|学习笔记
快速学习JAP4
12 0
Map 的基本介绍和创建 | 学习笔记
快速学习 Map 的基本介绍和创建
10 0
Service Mesh 介绍| 学习笔记
快速学习 Service Mesh 介绍
15 0
MQ 介绍|学习笔记
快速学习 MQ 介绍
47 0
学习C++笔记259
C++ 日期 & 时间
35 0
【STM32 .Net MF开发板学习-25】LED数码管显示
在单片机系统中,LED数码管的应用是很常见的,不过对我们偏软件开发的人来说,要想研究LED还得储备一定的知识才能进行近一步的工作。不过采用.NET Micro Framework系统,我们马上就可以站在软件人员的角度来研究LED数码管显示0~F数字的原理了。
463 0
MSP430矩阵及独立键盘
  在学习MSP430的时候,总是有很多东西记不住,同时又是英文的资料,好多东西也是没怎么看透,英文虽过六级但是看英文资料还是有一种想睡的冲动啊,在学习键盘的时候,我的这块板子有些不同,矩阵键盘和独立键盘公用的,组合式的按键。
761 0
【STM32 .Net MF开发板学习-25】LED数码管显示
在单片机系统中,LED数码管的应用是很常见的,不过对我们偏软件开发的人来说,要想研究LED还得储备一定的知识才能进行近一步的工作。
560 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载