如题,先说明应用场景和问题工作流程如下:在循环中按下按键3,进入模式切换函数,在通过按键1和按键2选择自动或手动然后不断循环,判断按键3是否按下,如无则进入之前选定的模式函数中。
自动模式里包含很多阈值判断,这个没有问题。问题出在手动模式中,
手动模式中包含了按键键值判断,启动手动模式后按键的反应并不灵敏,有时需要按两三下才能正常工作,有时又一下就能工作
同时进入手动模式后,外面按键3判断模式切换反应也迟钝了,而在自动模式(自动模式不包含手动的按键判断)中,模式切换反应很灵敏
在测试中,将手动模式中的按键判断删去后,按键3判断模式反应也灵敏了。当然按键1、2此时是无反应的
下面贴出单片机代码,求有大佬来看一眼指点迷津,感谢!
/***********************************************************************
感谢大佬的解惑,一眼就看出我代码问题所在
按我的理解(不知道对不对哈):主要是Key()调用次数过多,变量使用过多,导致无法在按键按下时及时更新键值
解决方法是将ManControl()中的Key()调用删去,改为使用主循环中的Mode_KeyNum变量进行判断即可,
这样就解决了按键按下有时有反应,有时没有反应的问题了!
*************************************************************************/
定时器扫描的独立按键Key函数
- #include <STC12C5A60S2.H>
- unsigned char Key_KeyNumber=0;
- unsigned char Key_GetState()
- {
- unsigned char Keynum = 0;
-
- if(P40==0){Keynum=1;}
- if(P41==0){Keynum=2;}
- if(P44==0){Keynum=3;}
-
- return Keynum;
- }
- void Key_Loop(void)
- {
- static unsigned char NowState,LastState;
- LastState = NowState;
- NowState = Key_GetState();
-
- if(LastState==1 && NowState==0){Key_KeyNumber = 1;}
- if(LastState==2 && NowState==0){Key_KeyNumber = 2;}
- if(LastState==3 && NowState==0){Key_KeyNumber = 3;}
- }
- unsigned char Key(void)
- {
- unsigned char Temp=0;
- Temp = Key_KeyNumber;
- Key_KeyNumber = 0;
- return Temp;
- }
复制代码
自动模式的函数
- void AutoControl(void)
- {
- TampData = Temp_RawData();
- HumiData = Humi_RawData();
- CO2DataBuffer = CO2_RawData();
- TVOCDataBuffer = TVOC_RawData();
- TempArray = Temp_Data();
- HumiArray = Humi_Data();
- LCD12864_ShowString(0,0,"排气"); //显示正常状态界面
- LCD12864_ShowString(0,4,"加湿");
- LCD12864_ShowString(1,0,"室内温度:");
- LCD12864_ShowString(2,0,"室内湿度:");
- LCD12864_ShowString(1,7,"℃");
- LCD12864_ShowString(2,7,"%");
- LCD12864_ShowString(3,0,"室内空气质量:");
- LCD12864_ShowString(1,5,&TempArray[0]); //温湿度显示
- LCD12864_ShowString(2,5,&HumiArray[0]);
-
- if(TampData>=240 && TampData<300 && HumiData>500 && HumiData<800) //夏季室内温湿度判断
- {
- LCD12864_ShowString(0,6,":Off"); //加湿关
- Humidifier=1;
- HumiStatus[0]=0x30;
- }
- else if(TampData>240 && TampData<300 && HumiData<400)
- {
- LCD12864_ShowString(0,6,":On"); //加湿开
- Humidifier=0;
- HumiStatus[0]=0x31;
- }
- else
- {
- LCD12864_ShowString(0,6,":Off");
- Humidifier=1;
- HumiStatus[0]=0x30;
- }
- if(TampData>160 && TampData<240 && HumiData>300 && HumiData<600) //冬季室内温湿度判断
- {
- LCD12864_ShowString(0,6,":Off"); //加湿关
- Humidifier=1;
- HumiStatus[0]=0x30;
- }
- else if(TampData>160 && TampData<240 && HumiData<300)
- {
- LCD12864_ShowString(0,6,":On"); //加湿开
- Humidifier=0;
- HumiStatus[0]=0x31;
- }
- else
- {
- LCD12864_ShowString(0,6,":Off");
- Humidifier=1;
- HumiStatus[0]=0x30;
- }
- if(CO2DataBuffer < 650 && TVOCDataBuffer < 200) //空气质量判断
- {
- LCD12864_ShowString(3,7,"优");
- LCD12864_ShowString(0,2,":Off");
- ExhaustFan=1;
- FanStatus[0]=0x30;
- }
- else if(CO2DataBuffer >= 650 && CO2DataBuffer <1000 && TVOCDataBuffer >=200 && TVOCDataBuffer < 400)
- {
- LCD12864_ShowString(3,7,"良");
- }
- else
- {
- LCD12864_ShowString(3,7,"差");
- LCD12864_ShowString(0,2,":On ");
- ExhaustFan=0;
- FanStatus[0]=0x31;
- }
- }
复制代码
手动模式的函数
- void ManControl(void)
- {
- TempArray1 = Temp_Data();
- HumiArray1 = Humi_Data();
- CO2DataBuffer1 = CO2_RawData();
- TVOCDataBuffer1 = TVOC_RawData();
-
-
- LCD12864_ShowString(0,0,"排气"); //显示正常状态界面
- LCD12864_ShowString(0,4,"加湿");
- LCD12864_ShowString(1,0,"室内温度:");
- LCD12864_ShowString(2,0,"室内湿度:");
- LCD12864_ShowString(1,7,"℃");
- LCD12864_ShowString(2,7,"%");
- LCD12864_ShowString(3,0,"室内空气质量:");
- LCD12864_ShowString(1,5,&TempArray1[0]); //温湿度显示
- LCD12864_ShowString(2,5,&HumiArray1[0]);
-
- KeyNum = Key();
- switch(KeyNum)
- {
- case 1: ExhaustFan =! ExhaustFan;
- KeyNum=0;break;
- case 2: Humidifier =! Humidifier;
- KeyNum=0;break;
- }
-
- if(ExhaustFan==0)
- {
- LCD12864_ShowString(0,2,":On ");
- FanStatus[0]=0x31;
- }
- else
- {
- LCD12864_ShowString(0,2,":Off");
- FanStatus[0]=0x30;
- }
-
- if(Humidifier==0)
- {
- LCD12864_ShowString(0,6,":On ");
- HumiStatus[0]=0x31;
- }
- else
- {
- LCD12864_ShowString(0,6,":Off");
- HumiStatus[0]=0x30;
- }
-
- if(CO2DataBuffer1 < 650 && TVOCDataBuffer1 < 200) //空气质量判断
- {
- LCD12864_ShowString(3,7,"优");
- }
- else if(CO2DataBuffer1 >= 650 && CO2DataBuffer1 <1000 && TVOCDataBuffer1 >=200 && TVOCDataBuffer1 < 400)
- {
- LCD12864_ShowString(3,7,"良");
- }
- else
- {
- LCD12864_ShowString(3,7,"差");
- }
- }
复制代码
不断循环的主函数
- Mode_KeyNum = Key();
- if(Mode_KeyNum==3)
- {
- unsigned char SelectMode_Count=5;
- Mode_KeyNum=0;
- LCD12864_WriteCommand(0x01);
- while(SelectMode_Count!=0)
- {
- if(Timer0_Flag==1)
- {
- SelectMode_Count--;
- Timer0_Flag=0;
- }
- LCD12864_ShowString(1,0,"请选择模式:");
- LCD12864_ShowUnsignedInt(3,0,SelectMode_Count,3);
-
- SelectMode_KeyNum = Key();
- switch(SelectMode_KeyNum)
- {
- case 1: SelectMode_Flag=1;LCD12864_ShowString(2,0,"手动模式");DeviceModeStatus[0]=0x31;break;
- case 2: SelectMode_Flag=0;LCD12864_ShowString(2,0,"自动模式");DeviceModeStatus[0]=0x30;break;
- default:;
- }
- }
- LCD12864_WriteCommand(0x01);
- }
-
- if(MQ9==1 && MQ2==1 && SelectMode_Flag==0)
- {
- AutoControl();
- }
- else if(MQ9==1 && MQ2==1 && SelectMode_Flag==1)
- {
- ManControl();
- }
复制代码
定时器函数(此处仅贴出了和按键扫描相关的部分)
- void Timer0_Routine(void) interrupt 1
- {
- static unsigned int Key_TimerCount,MQ_TimerCount;
- if(MQ_TimerCount>=100)
- {
- MQ_TimerCount=0;
- Timer0_Flag = !Timer0_Flag;
- }
- if(Key_TimerCount>=2)
- {
- Key_TimerCount=0;
- Key_Loop();
- }
- }
- void Timer0_Init(void) //定时器0 10毫秒中断初始化函数@11.0592MHz
- {
- AUXR &= 0x7F; //定时器时钟12T模
- TMOD &= 0xF0; //设置定时器模式
- TL0 = 0x00; //设置定时初始值
- TH0 = 0xDC; //设置定时初始值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
-
-
- EA = 1; //总中断允许
- ET0 = 1; //中断独立开关
- IPH = 0x02;
- PT0=1; //中断优先级
- }
复制代码
|