随着联合调试的发展,按键处理越来越复杂,经常是调好这个功能又影响到另一个功能,最后越来越乱,只好快刀斩乱麻,重新整理思路,重写按键处理程序。
重新整理后,按键需要区分5种情况,分别是点按(也就是按下后迅速释放),短按(也就是按下后稳定后释放),中按(按下约1秒后释放),长按(按下约2秒后释放),超长按(按下约5秒后释放),各种状态按照我的代码对应的keys值见下表,然后根据当前的工作模式执行相应的操作,详见下表:
其中报警设置中的轮换内容主要是两个时间点的设置、报警声音类别选择和声音时长设置。日历设置的轮换则是分别设置年、月、日、时、分。经过这样整理后再书写代码就比较简单了,用判断语句和开关语句先搭好架子,然后再往里面填充内容,程序结构清晰,调试也很快完成了。相应的代码如下:
1、按键获得
- // 轮询按键处理
- keys = 0;
- while(gd_eval_key_state_get(KEY_WAKEUP))
- {
- keys++;
- delay_1ms(50);
- }
- //有键按下
- if(keys > 0)
- key_processing();
2、按键处理程序
- /*************************************************************
- * 按键处理(PA0-WAKEUP)
- *************************************************************/
- void key_processing(void)
- {
- // uint8_t i; //滚屏用的临时记录号
- // LCD_write_ASCII(0,2,(uint8_t *) "Mode= Key= ");
-
- // LCD_write_value(72,2,2,0,1,keys);
- if(keys>40){ //超长按——调整报警设置
- if(mode>7)
- mode = 0; //强制退出
- else{
- mode = 8; //开始进入报警设置
- LCD_line_clear(0);
- LCD_line_clear(1);
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(6,0,(uint8_t *) "报警参数设置");
- LCD_write_string(0,3,(uint8_t *) "时间点");
- LCD_write_ASCII(36,4,(uint8_t *) "0");
- LCD_write_value(56,3,2,0,1,ala0);
- display_alarm_time(ala0);
- }
- }
- else{
- if(keys>20) //长按——查询记录
- if(mode == 7)
- mode = 0; //退出查询状态
- else{
- if(mode<7){
- mode = 7;//进入查询状态
- LCD_line_clear(0);
- LCD_line_clear(1);
- LCD_line_clear(2);
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(6,0,(uint8_t *) "查询报警记录");
- alar = 0;//清除报警记录
- line = addr;//从当前地址开始显示三行记录
- date_read(line);//显示三行记录
- }
- }
- else{
- if(keys>10){ //中按——轮换设置项目
- if(mode<7){
- mode++;
- if(mode==7)
- mode = 0;//结束日历设置
- else{
- LCD_line_clear(0);
- LCD_line_clear(1);
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(6,0,(uint8_t *) "日期时间设置");
- switch(mode){
- case 1://设置年
- LCD_write_string(0,3,(uint8_t *) "设置年");
- LCD_write_value(56,4,4,0,1,year);
- break;
- case 2://设置月
- LCD_write_string(0,3,(uint8_t *) "设置月");
- LCD_write_value(56,4,2,0,1,mon);
- break;
- case 3://设置日
- LCD_write_string(0,3,(uint8_t *) "设置日");
- LCD_write_value(56,4,2,0,1,day);
- break;
- case 4://设置时
- LCD_write_string(0,3,(uint8_t *) "设置时");
- LCD_write_value(56,4,2,0,1,hour);
- break;
- case 5://设置分
- LCD_write_string(0,3,(uint8_t *) "设置分");
- LCD_write_value(56,4,2,0,1,minu);
- break;
- case 6:
- LCD_write_string(0,3,(uint8_t *) "保存设置");
- }
- }
- }
- else{
- if(mode>7){
- mode++;
- if(mode>13)
- mode = 0;//结束报警设置
- else{
- LCD_line_clear(3);
- LCD_line_clear(4);
- switch(mode){
- case 9://设置时间点1
- LCD_write_string(0,3,(uint8_t *) "时间点");
- LCD_write_ASCII(36,4,(uint8_t *) "1");
- LCD_write_value(56,3,2,0,1,ala1);
- display_alarm_time(ala1);
- break;
- //54,4开始显示时分数据
- case 10:
- LCD_write_string(0,3,(uint8_t *) "保存设置");
- break;
- case 11://选择声音种类
- LCD_write_string(0,3,(uint8_t *) "设置声音");
- break;
- case 12://设置警笛时长
- LCD_write_string(0,3,(uint8_t *) "声音长度");
- LCD_write_value(56,4,3,0,1,ala9);
- break;
- case 13:
- LCD_write_string(0,3,(uint8_t *) "保存设置");
- }
- } // 处理:7<mode<12
- }
- }
- } //中长按键处理结束
- else{ //短按或点按
- switch(mode){
- case 1: //调整年
- year++;
- if(keys>5)
- year += 4;
- if(year > 2030)
- year = 2019;
- break;
-
- case 2: //调整月
- mon++;
- if(keys>5)
- mon += 4;
- if(mon > 12)
- mon = 1;
- break;
-
- case 3: //调整日
- day++;
- if(keys>5)
- day += 4;
- if(day > 31)
- day = 1;
- if((day>30) & (mon==4 | mon==6 | mon==9 | mon==11))
- day = 1;
- if((mon==2) & (day>28)){
- if(year%4 != 0){
- day = 1;
- }
- else{
- if(day>29)
- day = 1;
- }
- }
- break;
-
- case 4: //调整时
- hour++;
- if(keys>5)
- hour += 4;
- if(hour > 23)
- mon = 0;
- break;
-
- case 5: //调整分
- minu++;
- if(keys>5)
- minu += 4;
- if(minu > 59)
- minu = 0;
- break;
-
- case 6: //保存日期时间数据
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(0,3,(uint8_t *) "日期已保存");
- DS1302_write_date();
- delay_1ms(2000);
- LCD_line_clear(3);
- LCD_line_clear(4);
- mode = 0;//取消调整模式
- break;
-
- case 7: //查询记录
- if(keys<5)
- if(line<3)
- line = 31;
- else
- line -= 3;
- else
- if(line>28)
- line=0;
- else
- line += 3;
-
- date_read(line);//显示警情记录
-
- break;
-
- case 8: //调整报警时间点0(0~12时之间)
- ala0++;
- if(ala0>48)
- ala0 = 0;
- break;
-
- case 9: //调整报警时间点1(9~24时之间)
- ala1++;
- if(ala1>95)
- ala0 = 36;
- break;
- break;
-
- case 10://保存报警时间点记录
- WriteSet1302(0x8E,0x00); //关闭写保护
- WriteSet1302(0xC4,ala0); //保存报警时间点设置数据
- WriteSet1302(0xC6,ala1);
- WriteSet1302(0x8E,0x80); //关闭写保护
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(0,3,(uint8_t *) "时间点已保存");
- delay_1ms(2000);
- LCD_line_clear(3);
- LCD_line_clear(4);
- // mode = 0;
- break;
-
- case 11://轮换设置报警声音
- ala8++;
- if(ala8>4)
- ala8 = 0;
- LCD_line_clear(3);
- LCD_line_clear(4);
- switch(ala8){
- case 0:LCD_write_string(0,3,(uint8_t *) "正常报警声");break;
- case 1:LCD_write_string(0,3,(uint8_t *) "救护车声");break;
- case 2:LCD_write_string(0,3,(uint8_t *) "消防车声");break;
- case 3:LCD_write_string(0,3,(uint8_t *) "警车声");break;
- case 4:LCD_write_string(0,3,(uint8_t *) "音乐声");
- }
- break;
-
- case 12://设置时长
- ala9++;
- if(keys>5)
- ala9 += 4;
- break;
-
- case 13://保存时长设置数据
- WriteSet1302(0x8E,0x00); //关闭写保护
- WriteSet1302(0xC8,ala8); //保存声音设置数据
- WriteSet1302(0xCA,ala9); //保存警笛时长设置数据
- WriteSet1302(0x8E,0x80); //关闭写保护
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(0,3,(uint8_t *) "时长已保存");
- delay_1ms(2000);
- LCD_line_clear(3);
- LCD_line_clear(4);
- mode = 0;
- break;
- }
- } //短按及点按结束
- } //长按结束
- }
- if(mode==0) //恢复主屏幕
- {
- LCD_line_clear(0); //清两行内容
- LCD_line_clear(1);
- LCD_line_clear(2);
- LCD_line_clear(3);
- LCD_line_clear(4);
- LCD_write_string(6,0,(uint8_t *) "家庭智能监控");
- }
- // LCD_write_value(30,2,2,0,1,mode);
- }