如題,先說明應用場景和問題工作流程如下:在循環中按下按鍵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; //中斷優先級
- }
復制代碼
|