我的一个产品使用了STM32VCT6,其中使用了4X4按键,电路如下:
产品使用了三个多月以后,发现按键不能使用,而且设备处于死机状态。经过检查,发现按键扫描的输入端口PC3一直为低电平,排除PC3接地以及按键常闭的可能。因为我在测试的时候,把按键去掉,程序中也没有加按键扫描程序,其他程序都工作正常。此时用万用表测试PC0-PC3,只有PC3为0.38V,PC0-PC2为高电平。所以我判定PC3坏了。目前是,好几个板子都出现了这种情况,我实在找不出什么原因。我把按键扫描代码也贴出来,请各位帮忙,多谢了。
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*允许总线时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
/* PC0,1,2,3矩阵式按键(行)上拉输入*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* PC4,5,6,7矩阵式按键(列)推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
u8 KeyNumber;
u8 KeyPressFlag;
void KEY_Scan(void)
{
u8 k;
u16 keytemp;
//u16 ScanNum=0xFFEF;
GPIOC->IDR = (GPIOC->IDR &~0x000F); //把PC口输入寄存器的0--3位清零
GPIOC->ODR = (GPIOC->ODR &~0x00F0); //把PC口的输出寄存器的4--7位清零
keytemp=GPIOC->IDR; // 读入PC口的状态
keytemp&=0x000F; // 保留PC口的0--3位
if(keytemp==0x000F) // 如果没有矩阵式按键按下则直接去判断独立式按键
goto NEXT;
delay_ms(20); //延时去抖
keytemp=GPIOC->IDR; // 再次读入PC口的状态
keytemp&=0x000F; // 保留PC口的0--3位
if(keytemp==0x000F) // 如果没有按键按下则直接去判断独立式按键
goto NEXT;
for(k=0;k<4;k++)
{
switch(k)
{
case 0:
GPIOC->ODR =0xFFEF;
break;
case 1:
GPIOC->ODR =0xFFDF;
break;
case 2:
GPIOC->ODR =0xFFBF;
break;
case 3:
GPIOC->ODR =0xFF7F;
break;
default:
break;
}
delay_ms(1);
keytemp=GPIOC->IDR; // 读入PC口的状态
keytemp=~keytemp;
keytemp&=0x000F; // 保留PC口的0--3位
switch(keytemp)
{
case 0x01:
KeyNumber=1+k;
KeyPressFlag=1;
break;
case 0x02:
KeyNumber=5+k;
KeyPressFlag=1;
break;
case 0x04:
KeyNumber=9+k;
KeyPressFlag=1;
break;
case 0x08:
KeyNumber=13+k;
KeyPressFlag=1;
break;
default:
break;
}
}
/*等待按键弹起来*/
if((ScreenDeepCounts==1)&&(KeyNumber==6)) //如果是KEY6按下,判断是否超过3S,其他按键不需要判断
TIM_Cmd(TIM4, ENABLE);
AGAIN:
GPIOC->ODR = (GPIOC->ODR &~0x00F0);
delay_ms(10);
keytemp=GPIOC->IDR;
keytemp&=0x000F;
if(keytemp!=0x000f)
{
if(time4cnts>6)
{
//timecnts=0;
return;
}
goto AGAIN;
}
if(KeyNumber==6)
{
time4cnts=0;
TIM_Cmd(TIM4, DISABLE);
}
NEXT:
return;
}
|