前言:
相信看到此篇的小伙伴都已经是备战15,16乃至更高届蓝桥杯的小伙伴了。从14届开始,比赛使用的板子已经由国信长天的v10->国信长天v20。不论实物长什么样,更新比赛用板更新到多少代,不论比赛现场提供多少新的资料,淘汰了多少旧的资料,比赛一直不变的会提供单片机板子的原理图和各个芯片手册,在接下的文章中,我也将会结合芯片手册和原理图和大家讲解一下,我对这颗IAP15F2K61S2的理解和上层逻辑的编程
一、按键原理
在原理图中独立按键是这样的:
step:在使用独立按键的时候,需要使用跳线帽将CON3的3,2接在一起,如果使用矩阵键盘的时候,则将CON3的1,2端接在一起。
按键内部如图,当我们未按下按键的时候,金属弹片与底部引脚处于分离状态,底部任意两个对角引脚不导通,但我们按下按键后,金属弹片起到一个中间介质的作用,使得底部任意两个对角引脚导通,两个对角引脚电位相同。
了解了按键的工作原理,回到原理图中:之前提到,在使用独立按键的时候,需要将CON3的2,3端用跳线帽连接,则CON3的2端电平=GND=0V=按键的左引脚的电平。按键的右引脚连接单片机的引脚。当按键未按下,单片机的引脚端为高电平5V,当按键按下后,单片机引脚端电位被拉低到0V。在单片机引脚上的波形形成一个下降沿(电信号由1->0)。
未按下按键时电位:
按键按下后电位:
由上可知,只要我们读取单片机的指定引脚电平由高电平降到低电平后,则可以判断按键被按下,等到指定引脚电平由低电平升到高电平后,则判断按键被松开。
A:为什么在按键未按下的时候单片机的引脚是高电平呢?
Q:由于单片机的设置,在芯片的所有引脚外部都会接一个上拉电阻。上拉电阻是在某信号线上,通过电阻与一个固定的高电平VCC相接,使其电压在空闲状态保持在VCC电平(高电平)。
对于按键还有一个需要知道的:消抖
当我们按下按键的过程中,金属薄片的形变和我们按下的力都非线性,会因各种因素的影响产生不可预测的抖动,这个时候我们就要进行消抖处理。
消抖方式:(1)硬件消抖 (2)软件消抖
硬件消抖:电容消抖
软件消抖:延时函数
综上可知:在蓝桥杯单片机竞赛中,如果我们要检测一个按键是否被按下,可以通过监测按键对应单片的引脚电平状态来获得(如果按键按下,单片机引脚状态会变为低电平,如果按键未按下,单片机引脚的状态为高电平)。我们将根据单片机引脚变化状况完成编程。
二:代码编写
方案一:
#include "stc15f2k60s2.h"
sbit HC_A = P2^5;
sbit HC_B = P2^6;
sbit HC_C = P2^7;
void delay(unsigned int t)
{
while(t--);
}
int key()
{
if(P32 == 0) //检查有低电平
{
delay(200); //消抖
while(P32 == 0); //等待释放按键
delay(200); //消抖
return 1;
}
return 0;
}
void main()
{
unsigned char key_number;
unsigned char i;
HC_A = 0;
HC_B = 0;
HC_C = 1;
P0 = 0xff;
while(1)
{
key_number = key(); //调用key按键函数
if(key_number == 1)
{
/*---------------led代码,详细看上篇文章---------------*/
for(i=0;i<9;i++)
{
P0=(0xff<<i);
delay(50000);
}
for(i=0;i<8;i++)
{
P0=~(0X7F>>i);
delay(50000);
}
/*---------------led代码,详细看上篇文章---------------*/
}
else P0 = 0xff;
}
}
运用基础的if来判断是否产生低电平,用while等待按键的释放。
方法二:
#include "stc15f2k60s2.h"
sbit HC_A = P2^5;
sbit HC_B = P2^6;
sbit HC_C = P2^7;
unsigned char step = 0;
unsigned char key_number;
void delay(unsigned int t)
{
while(t--);
}
void key()
{
switch(step)
{
case 0 :
if(P32 == 0)
{
delay(200);
step = 1;
}
break;
case 1 :
if(P32==1)
{
delay(200);
step = 0;
key_number = 1;
}
else key_number = 0;
break;
}
}
void main()
{
unsigned char i;
HC_A = 0;
HC_B = 0;
HC_C = 1;
P0 = 0xff;
while(1)
{
key(); //调用key按键函数
if(key_number == 1)
{
/*---------------led代码,详细看上篇文章---------------*/
for(i=0;i<9;i++)
{
P0=(0xff<<i);
delay(50000);
}
for(i=0;i<8;i++)
{
P0=~(0X7F>>i);
delay(50000);
}
/*---------------led代码,详细看上篇文章---------------*/
key_number = 0;
}
else P0 = 0xff;
}
}
第二种方法用的时switch,替代了while。switch这种写法的好处将会在后面矩阵键盘的时候体现出来。
在此简述以下,如果遇到了需要长按的要求,可以在switch里面进行增加一个time++的函数,只要写一个time的函数就可以实现长按功能,但这个会有一点就是不够精准的问题。当然也可以设置一个滴答定时器和一个标志位来完成对长按的编写。