【CC2530强化实训04】定时器间隔定时实现按键N连击

【CC2530强化实训04】定时器间隔定时实现按键N连击

【题目要求】
      2018年全国职业院校技能大赛“物联网技术应用”国赛(高职组)中关于感知层开发的难度陡然增大,三个题目均在Zigbee协议栈下完成。其中第一个题目“仓库温湿度智能控制系统”考查了按键单击、双击和三连击。为了让大家更好的掌握按键的复杂处理思路,在这里通过一个具体的实训案例,讲述通过间隔定时实现按键N连击的基本思路。
      在新大陆国赛设备的黑色Zigbee模块上,或者小蜜蜂制作的XMF09B和XMF09C中,按键SW1单击,切换D5灯的开关状态;按键SW1双击,切换D6灯的开关状态;按键SW1三连击,切换D3灯的开关状态;按键SW1四连击,切换D4灯的开关状态
      按键SW1----------P1_2
      D5灯--------------P1_3(高电平点亮)
      D6灯--------------P1_4(高电平点亮)
      D3灯--------------P1_0(高电平点亮)
      D4灯--------------P1_1(高电平点亮)

【实现思路】
      每个按键按下都定义一个生命周期,假如是0.5秒,生命周期结束的时候才确定按键的最终状态。如果在按键的生命周期内有新的按键按下,将会重新计算生命周期,这时候就是双击。在双击的生命周期中,又有新的按键按下,则生命周期会重新计算,这时候就是三连击。在整个生命周期中如果没有新的按键按下,那么最终的按键状态就是三连击。如此类推。

【实现代码】

  1 #include "ioCC2530.h"
  2 
  3 #define D3  P1_0
  4 #define D4  P1_1
  5 #define D5  P1_3
  6 #define D6  P1_4
  7 #define SW1 P1_2
  8 #define SW2 P0_1
  9 
 10 unsigned char count_t = 0;
 11 unsigned char K_Num = 0;
 12 
 13 /*=======================简单的延时函数========================*/
 14 void Delay(unsigned int t)
 15 {
 16   while(t--);
 17 }
 18 
 19 /*======================端口初始化函数========================*/
 20 void Init_Port()
 21 {
 22   P1SEL &= ~0x1b;     //P1_0、P1_1、P1_3和P1_4作为通用I/O端口
 23   P1DIR |= 0x1b;      //P1_0、P1_1、P1_3和P1_4端口输出
 24   
 25   P1SEL &= ~0x04;     //P1_2作为通用I/O端口
 26   P1DIR &= ~0x04;     //P1_2端口输入
 27   P1INP &= ~0x04;     //P1_2设置为上拉/下拉模式
 28   P2INP &= ~0x40;     //P1_2设置为上拉
 29 }
 30 
 31 /*=======================定时器1初始化========================*/
 32 void Init_Timer1()
 33 {
 34   T1CC0L = 0xd4;      
 35   T1CC0H = 0x30;        //16MHz时钟,128分频,定时0.1秒
 36   T1CCTL0 |= 0x04;      //开启通道0的输出比较模式
 37   T1IE = 1;
 38   EA = 1;
 39   T1CTL = 0x0e;         //分频系数是128,模模式
 40 }
 41 
 42 /*====================定时器1服务函数========================*/
 43 #pragma vector = T1_VECTOR
 44 __interrupt void Timer1_int()
 45 {
 46   T1STAT &= ~0x20;    //清除定时器1的溢出中断标志位
 47   if(K_Num != 0 && SW1 != 0)  //按键不松开不计算生命周期    
 48   {
 49     count_t++;        //定时器1溢出一次加1,溢出周期为0.1S
 50   }
 51 }
 52 
 53 /*====================按键扫描处理函数========================*/
 54 void Scan_Keys()
 55 {
 56   if(SW1 == 0)
 57   {
 58     Delay(100);         //去抖动处理
 59     if(SW1 == 0)
 60     {
 61       while(SW1 == 0);  //等待按键松开
 62       count_t = 0;      //重新开始计算按键的生命周期
 63       K_Num++;          //改变按键状态
 64       if(K_Num > 4)     //四连击以上均判为四连击
 65       {
 66         K_Num = 4;
 67       }
 68     }
 69   }
 70   if(count_t > 5)       //按键生命周期结束
 71   {    
 72     switch(K_Num)
 73     {
 74       case 1:           //按键单击
 75         D5 = ~D5;
 76       break;
 77       case 2:           //按键双击
 78         D6 = ~D6;
 79       break;
 80       case 3:           //按键三连击
 81         D3 = ~D3;
 82       break;
 83       case 4:           //按键四连击
 84         D4 = ~D4;
 85       break;
 86     }
 87     K_Num = 0;     //每处理完一次按键,状态清零
 88     count_t = 0;   //计时清零
 89   }
 90 }
 91 
 92 /*=========================主函数=============================*/
 93 void main()
 94 {
 95   Init_Port();
 96   Init_Timer1();
 97   D3 = 0;
 98   D4 = 0;
 99   D5 = 0;
100   D6 = 0;
101   while(1)
102   {
103     Scan_Keys();
104   }
105 }

广东职业技术学院  欧浩源 <小蜜蜂老师>  ohy3686@qq.com】

原文地址:https://www.cnblogs.com/ALittleBee/p/9733944.html