我用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比较难按,不容易检测到,经常按了没反应。
大神看看,哪里有问题?谢谢
|