找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 674|回复: 3
打印 上一主题 下一主题
收起左侧

[已解决]STC12C5A60S2单片机扫描独立按键反应不灵敏 附代码

[复制链接]
跳转到指定楼层
楼主
ID:1041313 发表于 2022-10-28 15:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
如题,先说明应用场景和问题工作流程如下:在循环中按下按键3,进入模式切换函数,在通过按键1和按键2选择自动或手动然后不断循环,判断按键3是否按下,如无则进入之前选定的模式函数中。

自动模式里包含很多阈值判断,这个没有问题。问题出在手动模式中,
手动模式中包含了按键键值判断,启动手动模式后按键的反应并不灵敏,有时需要按两三下才能正常工作,有时又一下就能工作

同时进入手动模式后,外面按键3判断模式切换反应也迟钝了,而在自动模式(自动模式不包含手动的按键判断)中,模式切换反应很灵敏

在测试中,将手动模式中的按键判断删去后,按键3判断模式反应也灵敏了。当然按键1、2此时是无反应的

下面贴出单片机代码,求有大佬来看一眼指点迷津,感谢!

/***********************************************************************
感谢大佬的解惑,一眼就看出我代码问题所在

按我的理解(不知道对不对哈):主要是Key()调用次数过多,变量使用过多,导致无法在按键按下时及时更新键值

解决方法是将ManControl()中的Key()调用删去,改为使用主循环中的Mode_KeyNum变量进行判断即可,
这样就解决了按键按下有时有反应,有时没有反应的问题了!

*************************************************************************/

定时器扫描的独立按键Key函数
  1. #include <STC12C5A60S2.H>


  2. unsigned char Key_KeyNumber=0;

  3. unsigned char Key_GetState()
  4. {
  5.         unsigned char Keynum = 0;
  6.         
  7.         if(P40==0){Keynum=1;}
  8.         if(P41==0){Keynum=2;}
  9.         if(P44==0){Keynum=3;}
  10.         
  11.         return Keynum;
  12. }

  13. void Key_Loop(void)
  14. {
  15.         static unsigned char NowState,LastState;
  16.         LastState = NowState;
  17.         NowState = Key_GetState();
  18.         
  19.         if(LastState==1 && NowState==0){Key_KeyNumber = 1;}
  20.         if(LastState==2 && NowState==0){Key_KeyNumber = 2;}
  21.         if(LastState==3 && NowState==0){Key_KeyNumber = 3;}
  22. }

  23. unsigned char Key(void)
  24. {
  25.         unsigned char Temp=0;
  26.         Temp = Key_KeyNumber;
  27.         Key_KeyNumber = 0;
  28.         return Temp;
  29. }
复制代码


自动模式的函数
  1. void AutoControl(void)
  2. {
  3.         TampData = Temp_RawData();
  4.         HumiData = Humi_RawData();
  5.         CO2DataBuffer  = CO2_RawData();
  6.         TVOCDataBuffer = TVOC_RawData();
  7.         TempArray = Temp_Data();
  8.         HumiArray = Humi_Data();

  9.         LCD12864_ShowString(0,0,"排气");                //显示正常状态界面
  10.         LCD12864_ShowString(0,4,"加湿");
  11.         LCD12864_ShowString(1,0,"室内温度:");
  12.         LCD12864_ShowString(2,0,"室内湿度:");
  13.         LCD12864_ShowString(1,7,"℃");
  14.         LCD12864_ShowString(2,7,"%");
  15.         LCD12864_ShowString(3,0,"室内空气质量:");
  16.         LCD12864_ShowString(1,5,&TempArray[0]);        //温湿度显示
  17.         LCD12864_ShowString(2,5,&HumiArray[0]);
  18.         
  19.         if(TampData>=240 && TampData<300 && HumiData>500 && HumiData<800)                //夏季室内温湿度判断
  20.         {
  21.                 LCD12864_ShowString(0,6,":Off");                //加湿关
  22.                 Humidifier=1;
  23.                 HumiStatus[0]=0x30;
  24.         }
  25.         else if(TampData>240 && TampData<300 && HumiData<400)
  26.         {
  27.                 LCD12864_ShowString(0,6,":On");                        //加湿开
  28.                 Humidifier=0;
  29.                 HumiStatus[0]=0x31;
  30.         }
  31.         else
  32.         {
  33.                 LCD12864_ShowString(0,6,":Off");
  34.                 Humidifier=1;
  35.                 HumiStatus[0]=0x30;
  36.         }

  37.         if(TampData>160 && TampData<240 && HumiData>300 && HumiData<600)                //冬季室内温湿度判断
  38.         {
  39.                 LCD12864_ShowString(0,6,":Off");                //加湿关
  40.                 Humidifier=1;
  41.                 HumiStatus[0]=0x30;
  42.         }
  43.         else if(TampData>160 && TampData<240 && HumiData<300)
  44.         {
  45.                 LCD12864_ShowString(0,6,":On");                        //加湿开
  46.                 Humidifier=0;
  47.                 HumiStatus[0]=0x31;
  48.         }
  49.         else
  50.         {
  51.                 LCD12864_ShowString(0,6,":Off");
  52.                 Humidifier=1;
  53.                 HumiStatus[0]=0x30;
  54.         }

  55.         if(CO2DataBuffer < 650 && TVOCDataBuffer < 200)                //空气质量判断
  56.         {
  57.                 LCD12864_ShowString(3,7,"优");
  58.                 LCD12864_ShowString(0,2,":Off");
  59.                 ExhaustFan=1;
  60.                 FanStatus[0]=0x30;
  61.         }
  62.         else if(CO2DataBuffer >= 650 && CO2DataBuffer <1000 && TVOCDataBuffer >=200 && TVOCDataBuffer < 400)
  63.         {
  64.                 LCD12864_ShowString(3,7,"良");
  65.         }
  66.         else
  67.         {
  68.                 LCD12864_ShowString(3,7,"差");
  69.                 LCD12864_ShowString(0,2,":On ");
  70.                 ExhaustFan=0;
  71.                 FanStatus[0]=0x31;
  72.         }
  73. }
复制代码

手动模式的函数
  1. void ManControl(void)
  2. {
  3.         TempArray1 = Temp_Data();
  4.         HumiArray1 = Humi_Data();
  5.         CO2DataBuffer1  = CO2_RawData();
  6.         TVOCDataBuffer1 = TVOC_RawData();
  7.       

  8.       
  9.         LCD12864_ShowString(0,0,"排气");                //显示正常状态界面
  10.         LCD12864_ShowString(0,4,"加湿");
  11.         LCD12864_ShowString(1,0,"室内温度:");
  12.         LCD12864_ShowString(2,0,"室内湿度:");
  13.         LCD12864_ShowString(1,7,"℃");
  14.         LCD12864_ShowString(2,7,"%");
  15.         LCD12864_ShowString(3,0,"室内空气质量:");
  16.         LCD12864_ShowString(1,5,&TempArray1[0]);        //温湿度显示
  17.         LCD12864_ShowString(2,5,&HumiArray1[0]);
  18.       
  19.         KeyNum = Key();
  20.         switch(KeyNum)
  21.         {
  22.                 case 1: ExhaustFan =! ExhaustFan;
  23.                                 KeyNum=0;break;
  24.                 case 2: Humidifier =! Humidifier;
  25.                                 KeyNum=0;break;
  26.         }
  27.       
  28.         if(ExhaustFan==0)
  29.         {
  30.                 LCD12864_ShowString(0,2,":On ");
  31.                 FanStatus[0]=0x31;
  32.         }
  33.         else
  34.         {
  35.                 LCD12864_ShowString(0,2,":Off");
  36.                 FanStatus[0]=0x30;
  37.         }
  38.       
  39.         if(Humidifier==0)
  40.         {
  41.                 LCD12864_ShowString(0,6,":On ");
  42.                 HumiStatus[0]=0x31;
  43.         }
  44.         else
  45.         {
  46.                 LCD12864_ShowString(0,6,":Off");
  47.                 HumiStatus[0]=0x30;
  48.         }

  49.       
  50.         if(CO2DataBuffer1 < 650 && TVOCDataBuffer1 < 200)                //空气质量判断
  51.         {
  52.                 LCD12864_ShowString(3,7,"优");
  53.         }
  54.         else if(CO2DataBuffer1 >= 650 && CO2DataBuffer1 <1000 && TVOCDataBuffer1 >=200 && TVOCDataBuffer1 < 400)
  55.         {
  56.                 LCD12864_ShowString(3,7,"良");
  57.         }
  58.         else
  59.         {
  60.                 LCD12864_ShowString(3,7,"差");
  61.         }
  62. }
复制代码




不断循环的主函数

  1. Mode_KeyNum = Key();
  2.                         if(Mode_KeyNum==3)
  3.                         {
  4.                                 unsigned char SelectMode_Count=5;
  5.                                 Mode_KeyNum=0;
  6.                                 LCD12864_WriteCommand(0x01);
  7.                                 while(SelectMode_Count!=0)
  8.                                 {
  9.                                         if(Timer0_Flag==1)
  10.                                         {
  11.                                                 SelectMode_Count--;
  12.                                                 Timer0_Flag=0;
  13.                                         }
  14.                                         LCD12864_ShowString(1,0,"请选择模式:");
  15.                                         LCD12864_ShowUnsignedInt(3,0,SelectMode_Count,3);
  16.                                        
  17.                                         SelectMode_KeyNum = Key();
  18.                                         switch(SelectMode_KeyNum)
  19.                                         {
  20.                                                 case 1: SelectMode_Flag=1;LCD12864_ShowString(2,0,"手动模式");DeviceModeStatus[0]=0x31;break;
  21.                                                 case 2: SelectMode_Flag=0;LCD12864_ShowString(2,0,"自动模式");DeviceModeStatus[0]=0x30;break;
  22.                                                 default:;
  23.                                         }
  24.                                 }
  25.                                 LCD12864_WriteCommand(0x01);
  26.                         }
  27.                        
  28.                         if(MQ9==1 && MQ2==1 && SelectMode_Flag==0)
  29.                         {
  30.                                 AutoControl();
  31.                         }
  32.                         else if(MQ9==1 && MQ2==1 && SelectMode_Flag==1)
  33.                         {
  34.                                 ManControl();
  35.                         }
复制代码




定时器函数(此处仅贴出了和按键扫描相关的部分)

  1. void Timer0_Routine(void) interrupt 1
  2. {
  3.         static unsigned int Key_TimerCount,MQ_TimerCount;
  4. if(MQ_TimerCount>=100)
  5. {
  6.         MQ_TimerCount=0;
  7.         Timer0_Flag = !Timer0_Flag;
  8. }
  9.         if(Key_TimerCount>=2)
  10.         {
  11.                 Key_TimerCount=0;
  12.                 Key_Loop();
  13.         }
  14. }

  15. void Timer0_Init(void)        //定时器0 10毫秒中断初始化函数@11.0592MHz
  16. {
  17.         AUXR &= 0x7F;                //定时器时钟12T模
  18.         TMOD &= 0xF0;                //设置定时器模式
  19.         TL0 = 0x00;                //设置定时初始值
  20.         TH0 = 0xDC;                //设置定时初始值
  21.         TF0 = 0;                //清除TF0标志
  22.         TR0 = 1;                //定时器0开始计时
  23.       
  24.       
  25.         EA = 1;                                //总中断允许
  26.         ET0 = 1;                        //中断独立开关
  27.         IPH = 0x02;
  28.         PT0=1;                                //中断优先级
  29. }
复制代码








分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1041313 发表于 2022-10-28 19:32 | 只看该作者
没有大佬帮忙看看吗代码小白一个,知道肯定有很多不合理的错误写代码习惯,求大佬多来指点
回复

使用道具 举报

板凳
ID:161164 发表于 2022-10-28 21:29 | 只看该作者
Key()函数在运行手动模式时会运行三次
只有在主函数18行之后,ManControl()函数20行之前
有按键按下并且定时中断运行更新Key_KeyNumber
才能生效
想也想到多么困难
感觉key()函数有点多余
直接用Key_KeyNumber不好吗?
回复

使用道具 举报

地板
ID:1041313 发表于 2022-10-28 23:07 | 只看该作者
lkc8210 发表于 2022-10-28 21:29
Key()函数在运行手动模式时会运行三次
只有在主函数18行之后,ManControl()函数20行之前
有按键按下并且 ...

原来是这样!醍醐灌顶!谢谢大佬!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表