[PIC®/AVR®/dsPIC®产品] 按键长时间会不工作是怎么回事?

[复制链接]
 楼主| zfh01211123 发表于 2018-6-7 16:41 | 显示全部楼层 |阅读模式
PIC单片按键程序,KeyDriver()放在主函数里,工作长时间大约5天左右,按键不工作,大神们帮忙看看是我按键程序有问题吗?我用的是状态机写法。帮忙看看,谢谢啦!我的QQ396650143
  1. void KeyDriver(void)
  2. {
  3.    static  u8 i=0;
  4.    
  5.    if(flag_40ms)
  6.    {     
  7.        flag_40ms=0;
  8.        Set_KeyReturnValue = Set_ReadKeyStatus();
  9.        Query_KeyReturnValue = Query_ReadKeyStatus();
  10.        Both_KeyReturnValue = Both_ReadKeyStatus();
  11.     }
  12.    switch(Query_KeyReturnValue)
  13.     {
  14.         case 0:break;
  15.         case 1:
  16.             Query_KeyReturnValue = 0;
  17.             
  18.             if(WarnPriority == 0)//按键声响
  19.                 BzWarnTime(180);
  20.             if(setIndex == 0)//SET按键未按下时,轮询显示
  21.             {
  22.                 if(++cnt_location>tire_num)
  23.                 {
  24.                     cnt_location = 1;//位置
  25.                 }
  26.             }
  27.             if(setIndex == 1)//低压阈值设置
  28.             {
  29.                 ThresholdParam.low_press_value++;
  30.                 if(ThresholdParam.low_press_value > 70)//考斯特低压50-70bar,海狮20-35
  31.                 {
  32.                     ThresholdParam.low_press_value = 50;//测试1-2bar
  33.                 }
  34.                 FlashWriteByte(THRESOLD_ADDR_BASE + 1,ThresholdParam.low_press_value);
  35.             }
  36.             if(setIndex == 2)//高压阈值设置
  37.             {
  38.                 ThresholdParam.high_press_value++;
  39.                 if(ThresholdParam.high_press_value > 120)//考斯特高压100-120bar,海狮40-60
  40.                 {
  41.                     ThresholdParam.high_press_value = 100;//测试3-4bar,考斯特110
  42.                 }
  43.                 FlashWriteByte(THRESOLD_ADDR_BASE + 0,ThresholdParam.high_press_value);
  44.             }
  45.             if(setIndex == 3)
  46.             {
  47.                 ++i;
  48.                 i%=4;
  49.                 tire_num=tire_num_x[i];
  50.                 FlashWriteByte(THRESOLD_ADDR_BASE + 3,tire_num);
  51.                
  52.             }
  53.             if(setIndex > 3)//轮胎换位----待调试
  54.             {
  55.                 if(++sensorNum2 > tire_num)
  56.                 {
  57.                     sensorNum2 = 1;
  58.                      
  59.                 }
  60.             }
  61.             break;

  62.         case 2:
  63.             Query_KeyReturnValue = 0;
  64.          
  65.             if(WarnPriority == 0)//按键声响
  66.                 BzWarnTime(1000);
  67.             break;
  68.         default:break;
  69.     }
  70.     switch(Set_KeyReturnValue)
  71.     {
  72.         case 0:break;
  73.         case 1:
  74.             Set_KeyReturnValue = 0;
  75.            
  76.             if(WarnPriority == 0)//按键声响
  77.                 BzWarnTime(180);
  78.             if(setIndex)
  79.             {
  80.                 setIndex++;
  81.                 if(setIndex > 3+tire_num)
  82.                 {
  83.                     setIndex = 0;
  84.                     WheelLocationChange(sensorNum1,sensorNum2);
  85.                 }
  86.                 if(setIndex > 3)
  87.                 {
  88.                     if(setIndex == 4)
  89.                     {
  90.                         cnt_location = 1;//胎位显示
  91.                         sensorNum1 = SearchIDSerial(cnt_location);//传感器号
  92.                         sensorNum2 = sensorNum1;
  93.                     }
  94.                     else
  95.                     {   
  96.                         cnt_location++;
  97.                     }
  98.                     if(sensorNum2 != sensorNum1)
  99.                     {
  100.                         WheelLocationChange(sensorNum1,sensorNum2);
  101.                     }
  102.                     sensorNum1 = SearchIDSerial(cnt_location);
  103.                     sensorNum2 = sensorNum1;   
  104.                 }
  105.             }     
  106.             
  107.             break;
  108.         case 2:
  109.             Set_KeyReturnValue = 0;
  110.             
  111.             if(WarnPriority == 0)//按键声响
  112.                 BzWarnTime(1000);
  113.             if(setIndex == 0)
  114.             {
  115.                 setIndex = 1;//进入低压设置
  116.                 ThresholdParam.high_press_value = FlashReadByte(THRESOLD_ADDR_BASE + 0);//高压阈值
  117.                 ThresholdParam.low_press_value = FlashReadByte(THRESOLD_ADDR_BASE + 1);//低压阈值
  118.             }
  119.             break;
  120.         default:break;
  121.    
  122.     }        
  123.     switch(Both_KeyReturnValue)
  124.     {
  125.         case 0:break;
  126.         case 1:
  127.             Both_KeyReturnValue = 0;
  128.          
  129.             if(WarnPriority == 0)//按键声响
  130.                 BzWarnTime(180);
  131.             break;
  132.         case 2:
  133.             Both_KeyReturnValue = 0;
  134.          
  135.             if(WarnPriority == 0)//按键声响
  136.                 BzWarnTime(1000);
  137.             SysReset();
  138.             break;
  139.         default:break;
  140.     }

  141. }


  142. /*中断处理函数*/
  143. void interrupt isrfuction(void)
  144. {
  145.     static int16u Sys_Counter = 0,count=0,cnt1=0;
  146.     int8u i ;
  147.     Watchdog_Reset();
  148.    
  149.     if(TMR0IF && TMR0IE)
  150.     {     
  151.         TMR0IF = 0;
  152.         TMR0 = 100;//156 即定时时间为20ms
  153.         
  154.         //Set_KeyReturnValue = Set_ReadKeyStatus();
  155.         //Query_KeyReturnValue = Query_ReadKeyStatus();
  156.         //Both_KeyReturnValue = Both_ReadKeyStatus();
  157.         if(BZen)
  158.         {
  159.             if(++warncnt >= WaringTime)
  160.             {
  161.                 warncnt = 0;
  162.                 BZen = 0;
  163.                 WarnPriority = 0;
  164.             }
  165.          
  166.             if( 0x00 == warncnt%25)
  167.             {
  168.               Bz_Flag ^= 0x01;
  169.             }
  170.         }
  171.         if (++Sys_Counter >= 60000) //每20分钟重置.计数器
  172.         {
  173.             Sys_Counter = 0x0000;
  174.         }
  175.         
  176.         if(0x00 == Sys_Counter%2)//40ms
  177.         {
  178.             flag_40ms=1;
  179.         }
  180.         
  181.         if(setIndex > 2)
  182.         {
  183.             if(0x00 == Sys_Counter % 25)
  184.             {
  185.                 LcdSharkflag = !LcdSharkflag;
  186.             }
  187.         }
  188.         if(0x00 == Sys_Counter%400)//8s
  189.         {
  190.             if(setIndex == 0)
  191.             {
  192.                 if(++cnt_location>tire_num)//按键选择胎位数
  193.                 {
  194.                     cnt_location = 1;
  195.                 }
  196.             }
  197.         }
  198.         if (0x00==Sys_Counter%3000)
  199.                 {//每1min
  200.                         SETBIT(Time_Flag1,TF1_1min_bit);//置位1分钟标志
  201.                 }
  202.         if (0x00==Sys_Counter%6000)
  203.         {
  204.             SETBIT(Time_Flag1,TF1_2min_bit);
  205.         }
  206.                 if(0X00 == Sys_Counter % 15000)                //15000
  207.                 {//(5m)
  208.                         for(i = 0;i <tire_num;i++)//将Tire_num_x改为tire_num
  209.                         {
  210.                                 if((LockInf[i].Flag_reveive_first == 1)&&(LockInf[i].LockStatus != 0x55))//有接收到数据后开始判断
  211.                                 {
  212.                     Start_Time_Num[i]++;
  213.                                         if(Start_Time_Num[i] >=3)//30分钟6,测试1
  214.                                         {
  215.                                                 if(First_30min_Flag[i])//第二次,30分钟后
  216.                                                 {
  217.                                                         SETBIT(LockInf[i].sys_time_learn,Second_30min_Bit);//第二个周期结束
  218.                                                         Start_Time_Num[i]=0;
  219.                                                 }
  220.                                                 else//第一次
  221.                                                 {
  222.                                                         SETBIT(LockInf[i].sys_time_learn,First_30min_Bit);//第一个周期结束
  223.                                                         Start_Time_Num[i]=0;
  224.                                                 }
  225.                                         }
  226.                                         if(TESTBIT(LockInf[i].sys_time_learn,First_30min_Bit))//第一个周期结束
  227.                                         {
  228.                                                 First_30min_Flag[i]=1;//30分钟置一
  229.                                         }
  230.                                         else
  231.                                         {
  232.                                                 First_30min_Flag[i]=0;
  233.                                         }
  234.                                 }
  235.                         }
  236.                 }
  237.     }   
  238.     if( IOCBF0 && IOCIE )

  239.      if( INTF && INTE )
  240.     {
  241.         INTF=0;
  242.         TDA523x_int=1;
  243.     }
  244.    
  245. }

  246. u8 Set_ReadKeyStatus(void)
  247. {
  248.         static KeyStatus SetState = Set_NoKeyDownStatus;
  249.         static u16 TimeCount = 0;
  250.         u8 KeyReturnSet = 0; //返回值状态一定不能为静态变量,确保每次进入中断时清零
  251.         switch(SetState)
  252.         {
  253.                 /*没有按键按下*/
  254.                 case Set_NoKeyDownStatus:
  255.                         if(!KEYSET && KEYQUERY)        //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
  256.                         {
  257.                 SetState = Set_KeySureDownStatus ;
  258.                         }
  259.                         break;
  260.                 /*按键确认(按键消抖)*/
  261.                 case Set_KeySureDownStatus:
  262.                         if(!KEYSET && KEYQUERY)
  263.                         {
  264.                 //KeyReturnSet = 1;
  265.                 SetState = Set_OnceKeyDownStatus ;
  266.                 TimeCount = 0;
  267.                         }
  268.                         else
  269.                         {
  270.                 SetState = Set_NoKeyDownStatus ;
  271.                         }
  272.                         break;
  273.                 /*等待按键释放*/
  274.                 case Set_OnceKeyDownStatus:
  275.                         if(KEYSET && KEYQUERY)//按键弹起
  276.                         {
  277.                 KeyReturnSet = 1;
  278.                 SetState = Set_NoKeyDownStatus ;
  279.                 //TimeCount = 0;
  280.                         }
  281.                         else //5.28改
  282.             {
  283.                 if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
  284.                {
  285.                    SetState = Set_LongKeyDownStatus;
  286.                    KeyReturnSet = 2;
  287.                    TimeCount = 0;
  288.                 }
  289.             }
  290.             break;
  291.                 case Set_LongKeyDownStatus:
  292.                         if(KEYSET && KEYQUERY)
  293.                         {
  294.                                 SetState = Set_NoKeyDownStatus ;
  295.                         }
  296.                         break;
  297.                 default:break;
  298.         }
  299.         return KeyReturnSet;       
  300. }
  301. /*此程序放置于中断程序中(中断时间20ms)*/
  302. u8 Query_ReadKeyStatus(void)
  303. {
  304.         static KeyStatus QueryState = Query_NoKeyDownStatus;
  305.         static u16 TimeCount = 0;
  306.         u8 KeyReturnQuery = 0;//返回值状态一定不能为静态变量,确保每次进入中断时清零
  307.         switch(QueryState)
  308.         {
  309.                 /*没有按键按下*/
  310.                 case Query_NoKeyDownStatus:
  311.                         if(!KEYQUERY && KEYSET)         //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
  312.                         {
  313.                                         QueryState = Query_KeySureDownStatus ;
  314.                         }
  315.                         break;
  316.                 /*按键确认(按键消抖)*/
  317.                 case Query_KeySureDownStatus:
  318.                         if(!KEYQUERY && KEYSET)
  319.                         {
  320.                                         QueryState = Query_OnceKeyDownStatus ;
  321.                                         TimeCount = 0;
  322.                         }
  323.                         else
  324.                         {
  325.                                         QueryState = Query_NoKeyDownStatus ;
  326.                         }
  327.                         break;
  328.                 /*等待按键释放*/
  329.                 case Query_OnceKeyDownStatus:
  330.                         if(KEYQUERY && KEYSET)//按键弹起
  331.                         {
  332.                                         KeyReturnQuery = 1;
  333.                                         QueryState = Query_NoKeyDownStatus ;
  334.                                         //TimeCount = 0;
  335.                         }
  336.                         else
  337.             {
  338.                 if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
  339.                            {
  340.                     QueryState = Query_LongKeyDownStatus;
  341.                     KeyReturnQuery = 2;
  342.                     TimeCount = 0;
  343.                 }
  344.                         }
  345.             break;
  346.                 case Query_LongKeyDownStatus:
  347.                         if(KEYQUERY && KEYSET)
  348.                         {
  349.                                 QueryState = Query_NoKeyDownStatus ;
  350.                         }
  351.                         break;
  352.                 default:break;
  353.         }
  354.         return KeyReturnQuery;       
  355. }
  356. u8 Both_ReadKeyStatus(void)
  357. {
  358.         static KeyStatus BothState = Both_NoKeyDownStatus;
  359.         static u16 TimeCount = 0;
  360.         u8 KeyReturnBoth = 0;//返回值状态一定不能为静态变量,确保每次进入中断时清零
  361.         switch(BothState)
  362.         {
  363.                 /*没有按键按下*/
  364.                 case Both_NoKeyDownStatus:
  365.                         if((!KEYQUERY)&&(!KEYSET))         //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
  366.                         {
  367.                                         BothState = Both_KeySureDownStatus ;
  368.                         }
  369.                         break;
  370.                 /*按键确认(按键消抖)*/
  371.                 case Both_KeySureDownStatus:
  372.                         if((!KEYQUERY)&&(!KEYSET))
  373.                         {
  374.                                         BothState = Both_OnceKeyDownStatus ;
  375.                                         TimeCount = 0;
  376.                         }
  377.                         else
  378.                         {
  379.                                         BothState = Both_NoKeyDownStatus ;
  380.                         }
  381.                         break;
  382.                 /*等待按键释放*/
  383.                 case Both_OnceKeyDownStatus:
  384.                         if(KEYQUERY || KEYSET)//按键弹起
  385.                         {
  386.                                         KeyReturnBoth = 1;
  387.                                         BothState = Both_NoKeyDownStatus ;
  388.                                         //TimeCount = 0;
  389.                         }
  390.                         else
  391.             {
  392.                 if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
  393.                            {
  394.                     BothState = Both_LongKeyDownStatus;
  395.                     KeyReturnBoth = 2;
  396.                     TimeCount = 0;
  397.                 }
  398.                         }
  399.             break;
  400.                 case Both_LongKeyDownStatus:
  401.                         if(KEYQUERY || KEYSET)
  402.                         {
  403.                                 BothState = Both_NoKeyDownStatus ;
  404.                         }
  405.                         break;
  406.                 default:break;
  407.         }
  408.         return KeyReturnBoth;       
  409. }
 楼主| zfh01211123 发表于 2018-6-7 16:47 | 显示全部楼层
有哪位大神是用MPLAB X IDE V3.6 使用PCKit3.5怎么软件仿真查看程序
yy005566 发表于 2018-6-8 09:55 来自手机 | 显示全部楼层
zfh01211123 发表于 2018-6-7 16:47
有哪位大神是用MPLAB X IDE V3.6 使用PCKit3.5怎么软件仿真查看程序

我用过,你的意思是,kit3.5调试?还是仿真?

评论

调试程序怎么操作,仿真怎么用?  发表于 2018-6-8 11:23
 楼主| zfh01211123 发表于 2018-6-8 11:26 | 显示全部楼层
yy005566 发表于 2018-6-8 09:55
我用过,你的意思是,kit3.5调试?还是仿真?

调试程序怎么操作,仿真怎么用?
Cjy_JDxy 发表于 2018-6-8 11:29 | 显示全部楼层
你的按键程序好复杂吆
 楼主| zfh01211123 发表于 2018-6-8 13:12 | 显示全部楼层
Cjy_JDxy 发表于 2018-6-8 11:29
你的按键程序好复杂吆

你有更简单的吗?借我参考参考,谢谢!
Cjy_JDxy 发表于 2018-6-8 13:32 | 显示全部楼层
zfh01211123 发表于 2018-6-8 13:12
你有更简单的吗?借我参考参考,谢谢!

我的不是状态机,用延时,没你那个好
yy005566 发表于 2018-6-8 14:48 来自手机 | 显示全部楼层
zfh01211123 发表于 2018-6-8 11:26
调试程序怎么操作,仿真怎么用?

调试程序有实体,用kit3.5设断点的形式;没有实体用protues联调,
 楼主| zfh01211123 发表于 2018-6-8 16:45 | 显示全部楼层
yy005566 发表于 2018-6-8 14:48
调试程序有实体,用kit3.5设断点的形式;没有实体用protues联调,

断点设置不了,一设置就断开了,你知道是怎么回事?
 楼主| zfh01211123 发表于 2018-6-8 16:51 | 显示全部楼层
yy005566 发表于 2018-6-8 14:48
调试程序有实体,用kit3.5设断点的形式;没有实体用protues联调,

调试时没法看到调试指针到哪里,是怎么回事?
Cjy_JDxy 发表于 2018-6-8 17:14 | 显示全部楼层
断电,重插。看你的KIT3能不能正常工作。
yy005566 发表于 2018-6-8 17:49 来自手机 | 显示全部楼层
zfh01211123 发表于 2018-6-8 16:51
调试时没法看到调试指针到哪里,是怎么回事?


断点,从上到下的设置,先确定段,再逐句排除,到底哪里出了问题,一般是可以设置断点的,(当你程序没设断点而手动暂停,而没有看到pc,这时候是进入了程序计算中,这是我遇到过的,比如a*=10;这句)
 楼主| zfh01211123 发表于 2018-6-11 09:32 | 显示全部楼层
Cjy_JDxy 发表于 2018-6-8 17:14
断电,重插。看你的KIT3能不能正常工作。

KIT3.5是能正常工作的
 楼主| zfh01211123 发表于 2018-6-11 13:09 | 显示全部楼层
yy005566 发表于 2018-6-8 17:49
断点,从上到下的设置,先确定段,再逐句排除,到底哪里出了问题,一般是可以设置断点的,(当你程序没设 ...

恩,断点一设置,在调试是就自动断开了
yy005566 发表于 2018-6-11 22:34 来自手机 | 显示全部楼层
zfh01211123 发表于 2018-6-11 13:09
恩,断点一设置,在调试是就自动断开了

这是某条代码造成了器件复位,把所有复位配置位都disable试试看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

13

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

1

主题

13

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部