MSP430学习笔记7-4*4键盘的对应数码管显示-阿里云开发者社区

开发者社区> 文艺小青年> 正文

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,如需转载请自行联系原作者

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

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10062 0
duilib 修复CTreeViewUI控件动态添加子控件时,对是否显示判断不足的bug
转载请说明出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42264947         这个bug我在仿酷狗开发日志里提到过,不过后来发现修复的不够好,后来重新修改了代码,并记录到博客。
1155 0
如何用C#显示竖排文字?
看这个题目,应该觉的这个问题不难,刚开始我也是这么想,可是目前我手头上的参考资料上没有一个介绍竖直显示文字的,上网查资料只发现一个有用的,可是实现起来比较麻烦,需要进行坐标转换,旋转,还得平移,没办法,为了实现下图Y方向坐标的标注,只好这样了
905 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13875 0
论文笔记之:Optical Flow Estimation using a Spatial Pyramid Network
  Optical Flow Estimation using a Spatial Pyramid Network   spynet      本文将经典的 spatial-pyramid formulation 和 deep learning 的方法相结合,以一种 coarse to fine approach,进行光流的计算。
2048 0
短视频APP制作开发,滑动显示按钮,点击按钮置顶
短视频APP制作开发,滑动显示按钮,点击按钮置顶
626 0
AliOS Things 3.0应用笔记:摄像头配网 + 钉钉群通知 + 天气显示
AliOS Things 3.0应用笔记:摄像头配网 + 钉钉群通知 + LCD天气显示
2602 0
3576
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载