问题遇到的现象和发生背景
关于嵌入式开发。
问题描述:当我快速点按一个按键,或者快速切换其他按键,程序就会卡死。
我自己尝试修改这个问题,当我在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 装获取到的键值。
我的解答思路和尝试过的方法
将IO口修改成103RCT6拥有的IO口,然后我自己焊一个1X4的模拟矩阵键盘,在这款开发板上运行是不会出问题的。但是一换到ZET6开发板就出问题。
数码管驱动芯片(tm1640)也有类似的问题。我用外部中断触发的形式让数码管显示数值增加或者减少,只要旋转编码器转动过快,数码管就会卡死。对硬件不熟悉,真的很难解决这些问题。
我就想让他完美运行怎么就这么难。