我用STM32写矩阵键盘程序。以前发过几个帖子,一直没搞好。
电路图:
代码:
/*******************************************************************************
* 函数名 : TIM4_IRQHandler
* 描述 : 定时器4中断断服务函数
* 输入 : 无
* 输出 : 无
* 返回 : 无
* 说明 : 无
*******************************************************************************/
void TIM4_IRQHandler(void)
{
static uint8_t key_Pace = 0;
static uint32_t old_KeyVal;
if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{ //设定4ms中断一次
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
//键盘检测可以做成for循环4次
// PE.3,5,4设施成输入 ,PE6输出L
GPIO_SetBits(GPIOE,GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_6 );
delay_us(XD);
new_KeyVal = (~((GPIO_ReadInputData(GPIOE) & 7) + ((GPIO_ReadInputData(GPIOB)&0x0300) >>5))) & 0x1f ;
//PE.3输入,PE5输出L
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_3 | GPIO_Pin_4);
GPIO_ResetBits(GPIOE, GPIO_Pin_5 );
delay_us(XD);
new_KeyVal |= (((~((GPIO_ReadInputData(GPIOE) & 7) + ((GPIO_ReadInputData(GPIOB)&0x0300) >>5))) & 0x1f) << 5);
//PE.4输入,PE4输出L
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_3);
GPIO_ResetBits(GPIOE, GPIO_Pin_4 );
delay_us(XD);
new_KeyVal |= (((~((GPIO_ReadInputData(GPIOE) & 7) + ((GPIO_ReadInputData(GPIOB)&0x0380) >>4))) & 0x3f) << 10);
//PE.5输入,PE3输出L
GPIO_SetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_5);
GPIO_ResetBits(GPIOE, GPIO_Pin_3 );
delay_us(XD);
new_KeyVal |= (((~((GPIO_ReadInputData(GPIOE) & 7) + ((GPIO_ReadInputData(GPIOB)&0x0380) >>4)))& 0x3f ) << 16);
//恢复键盘待机,PE.6,5,4, 3全部输出L
GPIO_ResetBits(GPIOE,GPIO_Pin_6 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_3);
key_Pace ++;
if(key_Pace < 6)
{ //键盘按下去抖, 时间4ms×6 = 24ms ,也可以设置6~8ms中断一次,响应该值调整
if((new_KeyVal == 0) || new_KeyVal != old_KeyVal) //无键操作或者键值不对应
{old_KeyVal = new_KeyVal; key_Pace = 0;} //返回等待键盘状态
}
else if(key_Pace == 6)
{
//键值处理,或启动发送
switch(old_KeyVal)
{ //键盘比较离散或允许组合键采用这个方法
case 0x000001: //键盘1
keyvalue=3;
break;
case 0x000002: //键盘2
keyvalue=2;
break;
case 0x000004: //键盘3
keyvalue=1;
break;
case 0x000008: //键盘4
keyvalue=5;
break;
case 0x000010: //键盘5
keyvalue=4;
break;
case 0x000020: //键盘6
keyvalue=8;
break;
case 0x000040: //键盘7
keyvalue=7;
break;
case 0x000080: //键盘8
keyvalue=6;
break;
case 0x000100: //键盘9
keyvalue=10;
break;
case 0x000200: //键盘10
keyvalue=9;
break;
case 0x000400: //键盘11
keyvalue=13;
break;
case 0x000800: //键盘12
keyvalue=12;
break;
case 0x001000: //键盘13
keyvalue=11;
break;
case 0x002000: //键盘14
keyvalue=16;
break;
case 0x004000: //键盘15
keyvalue=15;
break;
case 0x008000: //键盘16
keyvalue=14;
break;
case 0x010000: //键盘17
keyvalue=19;
break;
case 0x020000: //键盘18
keyvalue=18;
break;
case 0x040000: //键盘19
keyvalue=17;
break;
case 0x080000: //键盘20
keyvalue=22;
break;
case 0x100000: //键盘21
keyvalue=21;
break;
case 0x200000: //键盘22
keyvalue=20;
break;
default: //其它组合键盘
break;
}
// 可以用统筹方法组合好后统一发送数据到通讯口
keynum=keyvalue ;
old_KeyVal = 0;
}
else if(key_Pace < 20)
{ //键盘释放去抖
if(new_KeyVal != 0) key_Pace = 6; //等待键盘释放
}
else key_Pace = 0; //键盘释放
}
}
实际测试,发现按键3,8,12比较难按,不容易检测到,经常按了没反应。
大神看看,哪里有问题?谢谢
|