[经验分享] GD32E231 DIY大赛(9)——重写按键处理程序

hujj   2019-5-19 21:34 楼主
    随着联合调试的发展,按键处理越来越复杂,经常是调好这个功能又影响到另一个功能,最后越来越乱,只好快刀斩乱麻,重新整理思路,重写按键处理程序。
    重新整理后,按键需要区分5种情况,分别是点按(也就是按下后迅速释放),短按(也就是按下后稳定后释放),中按(按下约1秒后释放),长按(按下约2秒后释放),超长按(按下约5秒后释放),各种状态按照我的代码对应的keys值见下表,然后根据当前的工作模式执行相应的操作,详见下表:
key_hanld.jpg
    其中报警设置中的轮换内容主要是两个时间点的设置、报警声音类别选择和声音时长设置。日历设置的轮换则是分别设置年、月、日、时、分。经过这样整理后再书写代码就比较简单了,用判断语句和开关语句先搭好架子,然后再往里面填充内容,程序结构清晰,调试也很快完成了。相应的代码如下:
1、按键获得
  1. //        轮询按键处理
  2.                 keys = 0;
  3.                 while(gd_eval_key_state_get(KEY_WAKEUP))
  4.                 {
  5.                     keys++;
  6.                         delay_1ms(50);
  7.                 }

  8.         //有键按下
  9.         if(keys > 0)
  10.                     key_processing();


2、按键处理程序

  1. /*************************************************************
  2. * 按键处理(PA0-WAKEUP)
  3. *************************************************************/
  4. void key_processing(void)
  5. {
  6. //    uint8_t i;             //滚屏用的临时记录号
  7. //    LCD_write_ASCII(0,2,(uint8_t *) "Mode=   Key=  ");
  8.    
  9. //        LCD_write_value(72,2,2,0,1,keys);       
  10.         if(keys>40){            //超长按——调整报警设置
  11.             if(mode>7)
  12.                         mode = 0;       //强制退出
  13.                 else{
  14.                     mode = 8;       //开始进入报警设置
  15.                     LCD_line_clear(0);
  16.                     LCD_line_clear(1);
  17.                         LCD_line_clear(3);
  18.                     LCD_line_clear(4);
  19.                     LCD_write_string(6,0,(uint8_t *) "报警参数设置");
  20.                         LCD_write_string(0,3,(uint8_t *) "时间点");
  21.                         LCD_write_ASCII(36,4,(uint8_t *) "0");
  22.                         LCD_write_value(56,3,2,0,1,ala0);
  23.                         display_alarm_time(ala0);
  24.                 }
  25.         }
  26.         else{
  27.                 if(keys>20)         //长按——查询记录
  28.                         if(mode == 7)
  29.                                 mode = 0;   //退出查询状态
  30.                         else{
  31.                             if(mode<7){
  32.                                         mode = 7;//进入查询状态
  33.                                         LCD_line_clear(0);
  34.                             LCD_line_clear(1);
  35.                                         LCD_line_clear(2);
  36.                                         LCD_line_clear(3);
  37.                             LCD_line_clear(4);
  38.                                     LCD_write_string(6,0,(uint8_t *) "查询报警记录");
  39.                                         alar = 0;//清除报警记录
  40.                                         line = addr;//从当前地址开始显示三行记录
  41.                             date_read(line);//显示三行记录
  42.                                 }
  43.                         }
  44.                 else{
  45.                         if(keys>10){    //中按——轮换设置项目
  46.                                 if(mode<7){
  47.                                         mode++;
  48.                                     if(mode==7)
  49.                                                 mode = 0;//结束日历设置
  50.                                         else{
  51.                                             LCD_line_clear(0);
  52.                                 LCD_line_clear(1);
  53.                                             LCD_line_clear(3);
  54.                                 LCD_line_clear(4);
  55.                                         LCD_write_string(6,0,(uint8_t *) "日期时间设置");
  56.                                                 switch(mode){
  57.                                             case 1://设置年
  58.                                             LCD_write_string(0,3,(uint8_t *) "设置年");
  59.                                                             LCD_write_value(56,4,4,0,1,year);
  60.                                                 break;
  61.                                         case 2://设置月
  62.                                             LCD_write_string(0,3,(uint8_t *) "设置月");
  63.                                                             LCD_write_value(56,4,2,0,1,mon);
  64.                                                 break;
  65.                                         case 3://设置日
  66.                                             LCD_write_string(0,3,(uint8_t *) "设置日");
  67.                                                             LCD_write_value(56,4,2,0,1,day);
  68.                                                 break;
  69.                                     case 4://设置时
  70.                                             LCD_write_string(0,3,(uint8_t *) "设置时");
  71.                                                             LCD_write_value(56,4,2,0,1,hour);
  72.                                                 break;
  73.                                     case 5://设置分
  74.                                         LCD_write_string(0,3,(uint8_t *) "设置分");
  75.                                                             LCD_write_value(56,4,2,0,1,minu);
  76.                                                 break;
  77.                                         case 6:
  78.                                             LCD_write_string(0,3,(uint8_t *) "保存设置");
  79.                                                 }
  80.                                         }
  81.                                 }
  82.                                 else{
  83.                                     if(mode>7){
  84.                                             mode++;
  85.                                                 if(mode>13)
  86.                                                         mode = 0;//结束报警设置
  87.                                                 else{
  88.                                                     LCD_line_clear(3);
  89.                                     LCD_line_clear(4);
  90.                                                         switch(mode){
  91.                                                             case 9://设置时间点1
  92.                                                                         LCD_write_string(0,3,(uint8_t *) "时间点");
  93.                                                                     LCD_write_ASCII(36,4,(uint8_t *) "1");
  94.                                                                     LCD_write_value(56,3,2,0,1,ala1);
  95.                                                                     display_alarm_time(ala1);
  96.                                                                     break;
  97.                                                                 //54,4开始显示时分数据
  98.                                                             case 10:
  99.                                                                         LCD_write_string(0,3,(uint8_t *) "保存设置");
  100.                                                                     break;
  101.                                                                 case 11://选择声音种类
  102.                                                                         LCD_write_string(0,3,(uint8_t *) "设置声音");
  103.                                                                     break;
  104.                                                                 case 12://设置警笛时长
  105.                                                                         LCD_write_string(0,3,(uint8_t *) "声音长度");
  106.                                                                     LCD_write_value(56,4,3,0,1,ala9);
  107.                                                                     break;
  108.                                                                 case 13:
  109.                                                                         LCD_write_string(0,3,(uint8_t *) "保存设置");
  110.                                                         }
  111.                                                 }   //  处理:7<mode<12
  112.                                         }
  113.                                 }

  114.                         }               //中长按键处理结束
  115.                         else{           //短按或点按
  116.                                 switch(mode){
  117.                             case 1: //调整年
  118.                                         year++;
  119.                                             if(keys>5)
  120.                                                     year += 4;
  121.                         if(year > 2030)
  122.                                                 year = 2019;
  123.                                         break;
  124.                                                
  125.                                 case 2: //调整月
  126.                                     mon++;
  127.                                             if(keys>5)
  128.                                                     mon += 4;
  129.                                         if(mon > 12)
  130.                                                 mon = 1;
  131.                                         break;
  132.                                                
  133.                             case 3: //调整日
  134.                                         day++;
  135.                                             if(keys>5)
  136.                                                     day += 4;
  137.                         if(day > 31)
  138.                                                 day = 1;
  139.                                         if((day>30) & (mon==4 | mon==6 | mon==9 | mon==11))
  140.                                                 day = 1;
  141.                                         if((mon==2) & (day>28)){
  142.                                                 if(year%4 != 0){
  143.                                                     day = 1;
  144.                                             }
  145.                                             else{
  146.                                                     if(day>29)
  147.                                                                 day = 1;
  148.                                         }
  149.                                     }
  150.                                         break;
  151.                                                
  152.                                 case 4: //调整时
  153.                                     hour++;
  154.                                             if(keys>5)
  155.                                                     hour += 4;
  156.                                         if(hour > 23)
  157.                                                 mon = 0;
  158.                                         break;
  159.                                                
  160.                                 case 5: //调整分
  161.                                     minu++;
  162.                                             if(keys>5)
  163.                                                     minu += 4;
  164.                                         if(minu > 59)
  165.                                                 minu = 0;
  166.                                                 break;
  167.                                                
  168.                                         case 6: //保存日期时间数据
  169.                                             LCD_line_clear(3);
  170.                                                 LCD_line_clear(4);
  171.                                                 LCD_write_string(0,3,(uint8_t *) "日期已保存");
  172.                                                 DS1302_write_date();
  173.                                                 delay_1ms(2000);
  174.                                                 LCD_line_clear(3);
  175.                                                 LCD_line_clear(4);
  176.                                                 mode = 0;//取消调整模式
  177.                                             break;
  178.                                        
  179.                                         case 7: //查询记录
  180.                                                 if(keys<5)
  181.                                                         if(line<3)
  182.                                                                 line = 31;
  183.                                                         else
  184.                                                             line -= 3;
  185.                                                 else
  186.                                                         if(line>28)
  187.                                                                 line=0;
  188.                                                         else
  189.                                                             line += 3;
  190.                                                
  191.                                                 date_read(line);//显示警情记录
  192.                                        
  193.                                                 break;
  194.                                        
  195.                                         case 8: //调整报警时间点0(0~12时之间)
  196.                                                 ala0++;
  197.                                             if(ala0>48)
  198.                                                         ala0 = 0;
  199.                                             break;
  200.                                        
  201.                                         case 9: //调整报警时间点1(9~24时之间)
  202.                                                 ala1++;
  203.                                             if(ala1>95)
  204.                                                         ala0 = 36;
  205.                                             break;
  206.                                                 break;
  207.                                        
  208.                                         case 10://保存报警时间点记录
  209.                                                 WriteSet1302(0x8E,0x00); //关闭写保护
  210.                             WriteSet1302(0xC4,ala0); //保存报警时间点设置数据        
  211.                             WriteSet1302(0xC6,ala1);
  212.                             WriteSet1302(0x8E,0x80); //关闭写保护
  213.                                             LCD_line_clear(3);
  214.                                                 LCD_line_clear(4);
  215.                                                 LCD_write_string(0,3,(uint8_t *) "时间点已保存");
  216.                                             delay_1ms(2000);
  217.                                             LCD_line_clear(3);
  218.                                             LCD_line_clear(4);
  219. //                                            mode = 0;
  220.                                             break;
  221.                                        
  222.                                         case 11://轮换设置报警声音
  223.                                         ala8++;
  224.                                             if(ala8>4)
  225.                                                     ala8 = 0;
  226.                                 LCD_line_clear(3);
  227.                                                 LCD_line_clear(4);
  228.                                                 switch(ala8){
  229.                                         case 0:LCD_write_string(0,3,(uint8_t *) "正常报警声");break;
  230.                                         case 1:LCD_write_string(0,3,(uint8_t *) "救护车声");break;
  231.                                         case 2:LCD_write_string(0,3,(uint8_t *) "消防车声");break;
  232.                                         case 3:LCD_write_string(0,3,(uint8_t *) "警车声");break;
  233.                                         case 4:LCD_write_string(0,3,(uint8_t *) "音乐声");
  234.                                 }
  235.                                                 break;
  236.                                                
  237.                                         case 12://设置时长
  238.                                                 ala9++;
  239.                                             if(keys>5)
  240.                                                         ala9 += 4;
  241.                                             break;
  242.                                                                
  243.                                         case 13://保存时长设置数据
  244.                                                 WriteSet1302(0x8E,0x00); //关闭写保护
  245.                                             WriteSet1302(0xC8,ala8); //保存声音设置数据
  246.                             WriteSet1302(0xCA,ala9); //保存警笛时长设置数据        
  247.                             WriteSet1302(0x8E,0x80); //关闭写保护
  248.                                             LCD_line_clear(3);
  249.                                                 LCD_line_clear(4);
  250.                                                 LCD_write_string(0,3,(uint8_t *) "时长已保存");
  251.                                             delay_1ms(2000);
  252.                                             LCD_line_clear(3);
  253.                                             LCD_line_clear(4);
  254.                                             mode = 0;
  255.                                             break;
  256.                                 }
  257.                         }               //短按及点按结束
  258.                 }                   //长按结束
  259.         }
  260.         if(mode==0)             //恢复主屏幕
  261.         {
  262.                 LCD_line_clear(0);  //清两行内容
  263.                 LCD_line_clear(1);
  264.                 LCD_line_clear(2);
  265.                 LCD_line_clear(3);
  266.                 LCD_line_clear(4);
  267.                 LCD_write_string(6,0,(uint8_t *) "家庭智能监控");
  268.         }
  269. //        LCD_write_value(30,2,2,0,1,mode);
  270. }





回复评论 (1)

谢谢分享!
点赞  2019-5-20 11:35
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复