[PIC®/AVR®/dsPIC®产品]

按键长时间会不工作是怎么回事?

[复制链接]
1891|15
手机看帖
扫描二维码
随时随地手机跟帖
zfh01211123|  楼主 | 2018-6-7 16:41 | 显示全部楼层 |阅读模式
PIC单片按键程序,KeyDriver()放在主函数里,工作长时间大约5天左右,按键不工作,大神们帮忙看看是我按键程序有问题吗?我用的是状态机写法。帮忙看看,谢谢啦!我的QQ396650143
void KeyDriver(void)
{
   static  u8 i=0;
   
   if(flag_40ms)
   {     
       flag_40ms=0;
       Set_KeyReturnValue = Set_ReadKeyStatus();
       Query_KeyReturnValue = Query_ReadKeyStatus();
       Both_KeyReturnValue = Both_ReadKeyStatus();
    }
   switch(Query_KeyReturnValue)
    {
        case 0:break;
        case 1:
            Query_KeyReturnValue = 0;
            
            if(WarnPriority == 0)//按键声响
                BzWarnTime(180);
            if(setIndex == 0)//SET按键未按下时,轮询显示
            {
                if(++cnt_location>tire_num)
                {
                    cnt_location = 1;//位置
                }
            }
            if(setIndex == 1)//低压阈值设置
            {
                ThresholdParam.low_press_value++;
                if(ThresholdParam.low_press_value > 70)//考斯特低压50-70bar,海狮20-35
                {
                    ThresholdParam.low_press_value = 50;//测试1-2bar
                }
                FlashWriteByte(THRESOLD_ADDR_BASE + 1,ThresholdParam.low_press_value);
            }
            if(setIndex == 2)//高压阈值设置
            {
                ThresholdParam.high_press_value++;
                if(ThresholdParam.high_press_value > 120)//考斯特高压100-120bar,海狮40-60
                {
                    ThresholdParam.high_press_value = 100;//测试3-4bar,考斯特110
                }
                FlashWriteByte(THRESOLD_ADDR_BASE + 0,ThresholdParam.high_press_value);
            }
            if(setIndex == 3)
            {
                ++i;
                i%=4;
                tire_num=tire_num_x[i];
                FlashWriteByte(THRESOLD_ADDR_BASE + 3,tire_num);
               
            }
            if(setIndex > 3)//轮胎换位----待调试
            {
                if(++sensorNum2 > tire_num)
                {
                    sensorNum2 = 1;
                     
                }
            }
            break;

        case 2:
            Query_KeyReturnValue = 0;
         
            if(WarnPriority == 0)//按键声响
                BzWarnTime(1000);
            break;
        default:break;
    }
    switch(Set_KeyReturnValue)
    {
        case 0:break;
        case 1:
            Set_KeyReturnValue = 0;
           
            if(WarnPriority == 0)//按键声响
                BzWarnTime(180);
            if(setIndex)
            {
                setIndex++;
                if(setIndex > 3+tire_num)
                {
                    setIndex = 0;
                    WheelLocationChange(sensorNum1,sensorNum2);
                }
                if(setIndex > 3)
                {
                    if(setIndex == 4)
                    {
                        cnt_location = 1;//胎位显示
                        sensorNum1 = SearchIDSerial(cnt_location);//传感器号
                        sensorNum2 = sensorNum1;
                    }
                    else
                    {   
                        cnt_location++;
                    }
                    if(sensorNum2 != sensorNum1)
                    {
                        WheelLocationChange(sensorNum1,sensorNum2);
                    }
                    sensorNum1 = SearchIDSerial(cnt_location);
                    sensorNum2 = sensorNum1;   
                }
            }     
            
            break;
        case 2:
            Set_KeyReturnValue = 0;
            
            if(WarnPriority == 0)//按键声响
                BzWarnTime(1000);
            if(setIndex == 0)
            {
                setIndex = 1;//进入低压设置
                ThresholdParam.high_press_value = FlashReadByte(THRESOLD_ADDR_BASE + 0);//高压阈值
                ThresholdParam.low_press_value = FlashReadByte(THRESOLD_ADDR_BASE + 1);//低压阈值
            }
            break;
        default:break;
   
    }        
    switch(Both_KeyReturnValue)
    {
        case 0:break;
        case 1:
            Both_KeyReturnValue = 0;
         
            if(WarnPriority == 0)//按键声响
                BzWarnTime(180);
            break;
        case 2:
            Both_KeyReturnValue = 0;
         
            if(WarnPriority == 0)//按键声响
                BzWarnTime(1000);
            SysReset();
            break;
        default:break;
    }

}


/*中断处理函数*/
void interrupt isrfuction(void)
{
    static int16u Sys_Counter = 0,count=0,cnt1=0;
    int8u i ;
    Watchdog_Reset();
   
    if(TMR0IF && TMR0IE)
    {     
        TMR0IF = 0;
        TMR0 = 100;//156 即定时时间为20ms
        
        //Set_KeyReturnValue = Set_ReadKeyStatus();
        //Query_KeyReturnValue = Query_ReadKeyStatus();
        //Both_KeyReturnValue = Both_ReadKeyStatus();
        if(BZen)
        {
            if(++warncnt >= WaringTime)
            {
                warncnt = 0;
                BZen = 0;
                WarnPriority = 0;
            }
         
            if( 0x00 == warncnt%25)
            {
              Bz_Flag ^= 0x01;
            }
        }
        if (++Sys_Counter >= 60000) //每20分钟重置.计数器
        {
            Sys_Counter = 0x0000;
        }
        
        if(0x00 == Sys_Counter%2)//40ms
        {
            flag_40ms=1;
        }
        
        if(setIndex > 2)
        {
            if(0x00 == Sys_Counter % 25)
            {
                LcdSharkflag = !LcdSharkflag;
            }
        }
        if(0x00 == Sys_Counter%400)//8s
        {
            if(setIndex == 0)
            {
                if(++cnt_location>tire_num)//按键选择胎位数
                {
                    cnt_location = 1;
                }
            }
        }
        if (0x00==Sys_Counter%3000)
                {//每1min
                        SETBIT(Time_Flag1,TF1_1min_bit);//置位1分钟标志
                }
        if (0x00==Sys_Counter%6000)
        {
            SETBIT(Time_Flag1,TF1_2min_bit);
        }
                if(0X00 == Sys_Counter % 15000)                //15000
                {//(5m)
                        for(i = 0;i <tire_num;i++)//将Tire_num_x改为tire_num
                        {
                                if((LockInf[i].Flag_reveive_first == 1)&&(LockInf[i].LockStatus != 0x55))//有接收到数据后开始判断
                                {
                    Start_Time_Num[i]++;
                                        if(Start_Time_Num[i] >=3)//30分钟6,测试1
                                        {
                                                if(First_30min_Flag[i])//第二次,30分钟后
                                                {
                                                        SETBIT(LockInf[i].sys_time_learn,Second_30min_Bit);//第二个周期结束
                                                        Start_Time_Num[i]=0;
                                                }
                                                else//第一次
                                                {
                                                        SETBIT(LockInf[i].sys_time_learn,First_30min_Bit);//第一个周期结束
                                                        Start_Time_Num[i]=0;
                                                }
                                        }
                                        if(TESTBIT(LockInf[i].sys_time_learn,First_30min_Bit))//第一个周期结束
                                        {
                                                First_30min_Flag[i]=1;//30分钟置一
                                        }
                                        else
                                        {
                                                First_30min_Flag[i]=0;
                                        }
                                }
                        }
                }
    }   
    if( IOCBF0 && IOCIE )

     if( INTF && INTE )
    {
        INTF=0;
        TDA523x_int=1;
    }
   
}

u8 Set_ReadKeyStatus(void)
{
        static KeyStatus SetState = Set_NoKeyDownStatus;
        static u16 TimeCount = 0;
        u8 KeyReturnSet = 0; //返回值状态一定不能为静态变量,确保每次进入中断时清零
        switch(SetState)
        {
                /*没有按键按下*/
                case Set_NoKeyDownStatus:
                        if(!KEYSET && KEYQUERY)        //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
                        {
                SetState = Set_KeySureDownStatus ;
                        }
                        break;
                /*按键确认(按键消抖)*/
                case Set_KeySureDownStatus:
                        if(!KEYSET && KEYQUERY)
                        {
                //KeyReturnSet = 1;
                SetState = Set_OnceKeyDownStatus ;
                TimeCount = 0;
                        }
                        else
                        {
                SetState = Set_NoKeyDownStatus ;
                        }
                        break;
                /*等待按键释放*/
                case Set_OnceKeyDownStatus:
                        if(KEYSET && KEYQUERY)//按键弹起
                        {
                KeyReturnSet = 1;
                SetState = Set_NoKeyDownStatus ;
                //TimeCount = 0;
                        }
                        else //5.28改
            {
                if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
               {
                   SetState = Set_LongKeyDownStatus;
                   KeyReturnSet = 2;
                   TimeCount = 0;
                }
            }
            break;
                case Set_LongKeyDownStatus:
                        if(KEYSET && KEYQUERY)
                        {
                                SetState = Set_NoKeyDownStatus ;
                        }
                        break;
                default:break;
        }
        return KeyReturnSet;       
}
/*此程序放置于中断程序中(中断时间20ms)*/
u8 Query_ReadKeyStatus(void)
{
        static KeyStatus QueryState = Query_NoKeyDownStatus;
        static u16 TimeCount = 0;
        u8 KeyReturnQuery = 0;//返回值状态一定不能为静态变量,确保每次进入中断时清零
        switch(QueryState)
        {
                /*没有按键按下*/
                case Query_NoKeyDownStatus:
                        if(!KEYQUERY && KEYSET)         //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
                        {
                                        QueryState = Query_KeySureDownStatus ;
                        }
                        break;
                /*按键确认(按键消抖)*/
                case Query_KeySureDownStatus:
                        if(!KEYQUERY && KEYSET)
                        {
                                        QueryState = Query_OnceKeyDownStatus ;
                                        TimeCount = 0;
                        }
                        else
                        {
                                        QueryState = Query_NoKeyDownStatus ;
                        }
                        break;
                /*等待按键释放*/
                case Query_OnceKeyDownStatus:
                        if(KEYQUERY && KEYSET)//按键弹起
                        {
                                        KeyReturnQuery = 1;
                                        QueryState = Query_NoKeyDownStatus ;
                                        //TimeCount = 0;
                        }
                        else
            {
                if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
                           {
                    QueryState = Query_LongKeyDownStatus;
                    KeyReturnQuery = 2;
                    TimeCount = 0;
                }
                        }
            break;
                case Query_LongKeyDownStatus:
                        if(KEYQUERY && KEYSET)
                        {
                                QueryState = Query_NoKeyDownStatus ;
                        }
                        break;
                default:break;
        }
        return KeyReturnQuery;       
}
u8 Both_ReadKeyStatus(void)
{
        static KeyStatus BothState = Both_NoKeyDownStatus;
        static u16 TimeCount = 0;
        u8 KeyReturnBoth = 0;//返回值状态一定不能为静态变量,确保每次进入中断时清零
        switch(BothState)
        {
                /*没有按键按下*/
                case Both_NoKeyDownStatus:
                        if((!KEYQUERY)&&(!KEYSET))         //如果按键被按下时,等待进入确认状态。KeyDown = 0 代表按键按下,=1代表按键弹起
                        {
                                        BothState = Both_KeySureDownStatus ;
                        }
                        break;
                /*按键确认(按键消抖)*/
                case Both_KeySureDownStatus:
                        if((!KEYQUERY)&&(!KEYSET))
                        {
                                        BothState = Both_OnceKeyDownStatus ;
                                        TimeCount = 0;
                        }
                        else
                        {
                                        BothState = Both_NoKeyDownStatus ;
                        }
                        break;
                /*等待按键释放*/
                case Both_OnceKeyDownStatus:
                        if(KEYQUERY || KEYSET)//按键弹起
                        {
                                        KeyReturnBoth = 1;
                                        BothState = Both_NoKeyDownStatus ;
                                        //TimeCount = 0;
                        }
                        else
            {
                if(++TimeCount >= (LONGSETKEYTIME/INTERRUPTTIME))//计满Xs后进入长按状态
                           {
                    BothState = Both_LongKeyDownStatus;
                    KeyReturnBoth = 2;
                    TimeCount = 0;
                }
                        }
            break;
                case Both_LongKeyDownStatus:
                        if(KEYQUERY || KEYSET)
                        {
                                BothState = Both_NoKeyDownStatus ;
                        }
                        break;
                default:break;
        }
        return KeyReturnBoth;       
}
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调试?还是仿真?

使用特权

评论回复
评论
zfh01211123 2018-6-8 11:23 回复TA
调试程序怎么操作,仿真怎么用? 
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

粉丝