Chase465 2022-11-04 09:27 采纳率: 0%
浏览 53

嵌入式开发,快速按下按键,软件无故卡死

问题遇到的现象和发生背景

关于嵌入式开发。
问题描述:当我快速点按一个按键,或者快速切换其他按键,程序就会卡死。

我自己尝试修改这个问题,当我在key.c文件里面的MAtrix_Scan()函数里面多加几个delay, 出现卡死的次数就会变少。然后把主函数主循环获取完键值后延时100ms, 并且软件检测按键按下后松开,现在1还会偶尔出现软件卡死的情况,是学生对硬件不是很熟悉,希望能有有学之士()总结一下是啥原因,不管原因正不正确,我都会去尝试一下。虽然是学生,拖下去会被老板骂。

用代码块功能插入代码,请勿粘贴截图

下面 这是矩阵键盘扫描所在的.c文件,因为是keil工程,中文注释会变乱码。

#include "./key/key.h"  
#include "./delay/delay.h"

void Key_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF,ENABLE);
    
    //¾ØÕó¼üÅÌÁÐ
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;             //ÉÏÀ­¸Ä³ÉÏÂÀ­
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOF,&GPIO_InitStructure);
    
    //¾ØÕó¼üÅÌÐÐ
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;         //ÍÆÍìÊä³ö
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_Init(GPIOE,&GPIO_InitStructure);
    
    //encoder
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;    //¸¡¿Õ
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13;
    GPIO_Init(GPIOE,&GPIO_InitStructure);
}

uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{            
    /*¼ì²âÊÇ·ñÓа´¼ü°´Ï */
    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON )  
    {     
        delay_ms(120);
        if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON) 
        return     KEY_ON;     
    }
    else
        return KEY_OFF;
}

int Matrix_Key_Scan(void)    
{
    u8 Read_Byte = 0x00;
    int key_val = -1;
    GPIO_SetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);            //ÐÐÖÃÒ»     ÐÞ¸Ä,Ó²¼þÖÐÓжþ¼«¹Ü,Ö»ÄÜÐÐÓøߵçƽ,È»ºóÁÐɨÃè¸ßµçƽ
    GPIO_ResetBits(GPIOF,GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);      //ÁÐÖÃÁã
    //delay_us(10);
    delay_ms(40);
    Read_Byte = (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]
    //if(Read_Byte==0x0f)      //µ±¶ÁÈ¡µ½µÄÁÐÊÇ1111,¼´Ã»ÓÐÈκΰ´¼ü±»°´ÏÂ,¿ªÊ¼É¨Ãè
    //{                        //ɾ³ýÕâ¾ä,ÔËÐйý³ÌÖпª¹Ø±»°´ÏÂÎÞ·¨¼°Ê±¶ÁÈ¡¼üÖµ,µ¼ÖÂÕâ¾äÅжϴíÎó,ÎÞ·¨·µ»ØÓÐЧµÄ¼üÖµ
        //delay_ms(40);
        //GPIO_SetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);        //À­¸ßÐÐÏß
        //delay_us(10);
        //Read_Byte= (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]
        
        if(Read_Byte!=0x00)     //´ËʱÁв»ÊÇ0000,±íÃ÷Óа´¼ü±»°´ÏÂ
        {
            
            //ɨÃèµÚÒ»ÐÐ
            GPIO_ResetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);            //ÐÐÈ«²¿ÖÃÁã
            GPIO_ResetBits(GPIOF,GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);      //ÁÐÈ«²¿ÖÃÁã
            delay_ms(10);
            GPIO_SetBits(GPIOE,GPIO_Pin_9);       //½«µÚÒ»ÐÐÖÃÒ»
            delay_ms(10);
            if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //F[14:11]²»È«Îª0
            {
                delay_ms(20);   //Ïû¶¶
                if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //Ïû¶¶Ö®ºóÔٴζÁÈ¡F[14:11],Èô²»È«Îª0
                {
                    Read_Byte = (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]
                    delay_ms(10);
                    switch(Read_Byte)
                    {
                        case 0x01:  key_val=1;   break;         //µÚÒ»ÁÐΪ0,µÚÒ»¸ö°´¼ü±»°´ÏÂ
                        case 0x02:  key_val=2;   break;
                        case 0x04:  key_val=3;   break;
                        case 0x08:  key_val=4;   break;
                        default:    key_val=-1;  break;
                    }
                    delay_ms(10);
                    return key_val;    //ÓмüÖµÖ±½Ó·µ»Ø,¼Ó¿ìÔËÐÐËÙ¶È
                }
            }
            
            //ɨÃèµÚ¶þÐÐ
            GPIO_ResetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);            //ÐÐÈ«²¿ÖÃÁã
            GPIO_ResetBits(GPIOF,GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);      //ÁÐÈ«²¿ÖÃÁã
            delay_ms(10);
            GPIO_SetBits(GPIOE,GPIO_Pin_10);       //½«µÚ¶þÐÐÖÃ1
            delay_ms(10);
            if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //F[14:11]²»È«Îª0
            {
                delay_ms(20);   //Ïû¶¶
                if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //Ïû¶¶Ö®ºóÔٴζÁÈ¡F[14:11],Èô²»È«Îª0
                {
                    Read_Byte = (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]
                    delay_ms(10);
                    switch(Read_Byte)
                    {
                        case 0x01:  key_val=5;   break;         //µÚÒ»ÁÐΪ0,µÚÒ»¸ö°´¼ü±»°´ÏÂ
                        case 0x02:  key_val=6;   break;
                        case 0x04:  key_val=7;   break;
                        case 0x08:  key_val=8;   break;
                        default:    key_val=-1;  break;
                    }
                    delay_ms(10);
                    return key_val;    //ÓмüÖµÖ±½Ó·µ»Ø,¼Ó¿ìÔËÐÐËÙ¶È
                }
            }    
            
            //ɨÃèµÚÈýÐÐ
            GPIO_ResetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);            //ÐÐÈ«²¿ÖÃ0
            GPIO_ResetBits(GPIOF,GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);      //ÁÐÈ«²¿ÖÃ0
            delay_ms(10);
            GPIO_SetBits(GPIOE,GPIO_Pin_11);       //½«µÚÈýÐÐÖÃ1
            delay_ms(10);
            if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //F[14:11]²»È«0
            {
                delay_ms(20);   //Ïû¶¶
                if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //Ïû¶¶Ö®ºóÔٴζÁÈ¡F[14:11],Èô²»È«Îª0
                {
                    delay_ms(10);
                    Read_Byte = (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]        
                    switch(Read_Byte)
                    {
                        case 0x01:  key_val=9;    break;         //µÚÒ»ÁÐΪ0,µÚÒ»¸ö°´¼ü±»°´ÏÂ
                        case 0x02:  key_val=10;   break;
                        case 0x04:  key_val=11;   break;
                        case 0x08:  key_val=12;   break;
                        default:    key_val=-1;   break;
                    }
                    delay_ms(10);
                    return key_val;    //ÓмüÖµÖ±½Ó·µ»Ø,¼Ó¿ìÔËÐÐËÙ¶È
                }
            }
            
            //ɨÃèµÚËÄÐÐ
            GPIO_ResetBits(GPIOE,GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);            //ÐÐÈ«²¿ÖÃ0
            GPIO_ResetBits(GPIOF,GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14);      //ÁÐÈ«²¿ÖÃ0
            delay_ms(10);
            GPIO_SetBits(GPIOE,GPIO_Pin_12);       //½«µÚËÄÐÐÖÃ1
            delay_ms(10);
            if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //F[14:11]²»È«Îª0
            {
                delay_ms(20);   //Ïû¶¶
                if(((GPIO_ReadInputData(GPIOF)>>11)&0X0f)!=0x00)   //Ïû¶¶Ö®ºóÔٴζÁÈ¡F[14:11],Èô²»È«Îª0
                {
                    delay_ms(10);
                    Read_Byte = (GPIO_ReadInputData(GPIOF)>>11)&0X0f;    //¶ÁÈ¡F[14:11]
                    switch(Read_Byte)
                    {
                        case 0x01:  key_val=13;   break;         //µÚÒ»ÁÐΪ0,µÚÒ»¸ö°´¼ü±»°´ÏÂ
                        case 0x02:  key_val=14;   break;
                        case 0x04:  key_val=15;   break;
                        case 0x08:  key_val=16;   break;
                        default:    key_val=-1;   break;
                    }
                    delay_ms(10);
                    return key_val;    //ÓмüÖµÖ±½Ó·µ»Ø,¼Ó¿ìÔËÐÐËÙ¶È
                }
            }
            
        } //end if(Read_Byte!=0x0f)     //´ËʱÁв»ÊÇ1111,±íÃ÷Óа´¼ü±»°´ÏÂ
    //} //end if(Read_Byte==0x0f)      //µ±¶ÁÈ¡µ½µÄÁÐÊÇ1111,¼´Ã»ÓÐÈκΰ´¼ü±»°´ÏÂ,¿ªÊ¼É¨Ãè
    
    return key_val;   //×îºó·µ»Ø
}

这下面是主函数扫描键值部分。

while(1)
    {    
        //printf("0");
        Key_Val_Read=Matrix_Key_Scan();
        //printf("1");
        delay_ms(100);
        if(Key_Val_Read!=-1)
        {
            Key_Val_Pre=Key_Val_Read;
        }
        if(Key_Val_Read==-1||Key_Val_Read==K_UP||Key_Val_Read==K_DOWN)  //¿ªÊ¼É¨Ãè°´¼üÊÇ·ñËÉ¿ª
        {
            if(Key_Val_Pre==K_110v) 
            {
                printf("k110v has been pressed\n");
                
            }
            
            else if (Key_Val_Pre==K_VSet)
            {
                printf("kvset has been pressed\n");
                i=(int)Num/10%10;   //test
                printf("%d ",i);
                i=(int)Num%10;
                printf("%d ",i);
                i=(int)(Num*10)%100%10;
                printf("%d ",i);
                i=(uint32_t)(Num*100)%1000%100%10;
                printf("%d ",i);
                i=(uint32_t)(Num*1000)%10000%1000%100%10;
                printf("%d ",i);
            }
            
            else if (Key_Val_Pre==K_HL)
            {
                printf("khl has been pressed\n");
                //Display_Float2(DS1,1.520);
                printf("end\n");
            }
            
            else if (Key_Val_Pre==K_M1)
            {
                printf("km1 has been pressed\n");
                //Display_Float2(DS1,2.2450);
                printf("end\n");
            }
            
            else if (Key_Val_Pre==K_220v)
            {
                printf("k220v has been pressed\n");
                //Display_Float2(DS2,32.867);
                printf("end\n");
            }
            
            else if (Key_Val_Pre==K_FSet)
            {
                printf("kfset has been pressed\n");
                //Display_Float2(DS2,98.135);
                printf("end\n");
            }
}}//...部分代码

使用int Key_Val_Read 装获取到的键值。

我的解答思路和尝试过的方法
  1. 将IO口修改成103RCT6拥有的IO口,然后我自己焊一个1X4的模拟矩阵键盘,在这款开发板上运行是不会出问题的。但是一换到ZET6开发板就出问题。

  2. 数码管驱动芯片(tm1640)也有类似的问题。我用外部中断触发的形式让数码管显示数值增加或者减少,只要旋转编码器转动过快,数码管就会卡死。对硬件不熟悉,真的很难解决这些问题。

我就想让他完美运行怎么就这么难。

  • 写回答

2条回答 默认 最新

  • pagiee 2022-11-04 10:58
    关注

    看了 一下 代码, 我的判断如下:
    1、 首先主函数 是调用 那个键盘的函数 然后 演示100ms 之后的基本都是输出操作,而作者说过偶尔成功,说明 能跑到这里 基本都有输出
    2、其次,你没有设置 GPIO_ReadInputData(GPIOF) 这个函数 失败时候的警告处理 基本 都是if 而没有else,可想而知 如果 这个io口 没接通 就一直没有正常的数据传进来,你的这个readdate 肯定在一直等待到 判断为高 才会出来
    3、 我不知道 你有没有初始化好 io口 建议 拿示波器 或者逻辑分析仪 采一下输出io 口的波形
    总结:你要采的io 需要输出11位 而且 还要与0x000f 成立 才执行 你需要确认 你这个io 口 获取的是什么东西

    评论

报告相同问题?

问题事件

  • 创建了问题 11月4日

悬赏问题

  • ¥15 pcl运行在qt msvc2019环境运行效率低于visual studio 2019
  • ¥15 MAUI,Zxing扫码,华为手机没反应。可提高悬赏
  • ¥15 求帮看看那里的问题ssh项目报错
  • ¥15 python运行报错 ModuleNotFoundError: No module named 'torch'
  • ¥100 华为手机私有App后台保活
  • ¥15 sqlserver中加密的密码字段查询问题
  • ¥20 有谁能看看我coe文件到底哪儿有问题吗?
  • ¥20 我的这个coe文件到底哪儿出问题了
  • ¥15 matlab使用自定义函数时一直报错输入参数过多
  • ¥15 设计一个温度闭环控制系统