四.独立按键和矩阵键盘
独立按键和矩阵键盘
原理图:

由原理图可以知道,独立按键和矩阵键盘有些线是接在一起的。
我们看到板子实物,会看到可更改的跳线帽。当2,3跳线帽接在一起时,启用的是独立按键。
独立按键
接下来我们简化独立按键原理图:

从上到下依次是S7、S6、S5、S4,所有按键可以同时输入与输出(区别于stm32)。
输入读取
按键按下为低电平,程序选择表达为:
1 | if(s7 == 0) |
当按键没有按下时,为高电平。(此处涉及到单片机IO口的结构和电路分析基础,此处不做过多研究。PS:我也研究不明白。)
另外,单片机按键会出现抖动,这是由于单片机按键的机械原因,其按键具有弹性,断开与闭合时均会因为弹性作用,不会马上稳定的接通,最大抖动时常为(5-10ms)+(5-10ms)。
此外,单片机的输入高电平为5v,输出为0v,但输出的高低电平均为一个范围。

用示波器检测,我们即可发现其抖动的状态。
如果我们要消除抖动,在判断为按键按下时候加一个10ms的延时函数即可。
程序设计
定义端口;
1 | sbit S7 = P3^0; |
定义函数:
1 | void keyscan()//按键扫描函数 |
主函数:
1 | void main() |
记得改跳线帽哦。
练习:
1.按下S7亮灯,松开熄灭
void keyscan()//按键扫描函数
{
hc573(4);//开LED锁存器通道
if (S7 == 0);
{
P0 = 0xfe;//亮第一个灯
while(S7==0);//不松手的话就会一直卡在循环里,即一直亮第一个灯。
P0 = 0xff;
}
}
2.按下S7,L1亮,再按下S7,L1灭
这里我们使用一个计分板:state
当state为0,led亮,
1 | uchar state;//keil5初始值默认为0 |
3.第一次按S7,L1亮,第二次按,L1以500ms闪烁,第三次熄灭。
整体思路不变,依然是用state,不过这次需要三个数,我们可以这样改:
1 | void keyscan()//按键扫描函数 |
或者:
1 | void keyscan()//按键扫描函数 |
两个改法核心思路都是:
第一次state值为0,执行亮L1操作,第二次按下state值为执行闪烁操作,第三次state为2,执行熄灭,第四次自动把state值改为0,再重新进入循环。
led部分:
1 | void led() |
然后我们写入单片机,我们发现,第三次无法实现。
这里,我们需要定时器中断
解释原因:
我们的程序执行过程是这样的:
1.keyscan
2.led
P0 = 0xff;
delay_ms(500);
P0 = 0xfe;
delay_ms(500); //这个过程是每次执行完才去检测按键函数。
所以说,在这每次循环完闪烁之后,只有极短的时间去检测按键,但这个时间不足以让人的手去按下按键。
这样,我们的函数state==1就会一直循环下去。除非某次它刚好执行完,你刚好按下按键并且被它检测到,才会停止循环,执行state==2.
那怎么样才能加大我们被检测到的概率呢?
别忘了,delay_ms(500)函数是1ms的函数循环500次,只要我们把按键检测塞到这个循环里去,那我们被检测的概率将大大提高。
延时函数:
1 | void Delay_ms(uint xms) //@12MHz |
不过,我们仅仅是在按键时候检测,所以不破坏原本延时函数,复制后改个名整个新的函数。
1 | void Delay_msl(uint xms) |
记得把keyscan放在新的延时函数之前。否则编译会出错。





