之前用STM32做过按键矩阵,没加任何上拉下拉的5个OUT_PIN和5个IN_PIN的那种,最近使用51单片机STC11F04E再次制作5*6的按键矩阵,因为IO口不够所以特地使用了IO拓展IC-----CH423S。因为官方没有提供按键矩阵的例程,所以我走的点弯路,希望这篇帖子能帮助诸位。
CH423除去电源和地以及2个i2c控制脚外共有16个通用输出脚可以推挽输出和开漏输出,8个双向输出IO口可以输入也可以输出。
在使用STM32做按键扫描时我一般是让5个OUT_PIN轮流输出高电平,然后读取5个IN_PIN脚的电平。如下:
for(i = 0;i<5;i++)
{
out_pin_1(i);//第i号引脚输出高电平,其他引脚输出低电平
for(j = 0;j<5;j++)
{
if(in_pin(j))//判断第J号引脚是否检测到高电平
{
delay_ms(10);//延时消抖
if(in_pin(j))//再次判定
{
key_num = i*6+j;//按键赋值
while(in_pin(j)){;}//等待按键弹起
break;//见此到按键,按键又弹起来了,当然退出了,我又不做组合按键
}else{;}//第一次见此到按键值10ms后检测不到,判定为误触,无效
}
}
}
以上是STM32的按键扫描,这里如果in_pin引脚悬空读出来的值是0,如果被按下的话值就是!0(非零)。
我用相同的思路在CH423上发现错的离谱,在CH423里面悬空脚读取时他的电平是1,也就是说CH423里面除非IO口和GND像连接,否则他读取出来的值就是1,因此想要用CH423S做按键矩阵,在按键扫描时只能检测低电平。
unsigned int CHECK_KEY(void)
{
unsigned char key_num1,key_num2,i;
for(i = 0;i < 5;i++)
{
CH423_WriteByte(0x4400|((0Xfe << i)+1));//设置低8位开漏输出命令
delay_ms(5);
key_num1 = CH423_ReadByte(); // 读取数据
if(key_num1 != 0xff)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
key_num2 = CH423_ReadByte();
if(key_num1 == key_num2){
while(CH423_ReadByte() != 0xff){_nop_();_nop_();_nop_();_nop_();_nop_();}
return (key_num1 | (0x01 << (i+8)));
}
else key_num1 = 0;
}
}
return 0;
}
|