今天的知识难度与昨天相比有所增加,但是还好今天坚持了下来,希望再接再励!今天学习了按键。
(0基础入门二)
1.1 认识原理图
独立按键的原理图如下图所示。对于独立按键,我们需要得知两个量。一,什么是按键的IO口(图中可知IO口为P3);二,独立按键是0次量还是1次量(按键按下去,按键接地,则该按键为0次量)。
1.2 按键读取函数
按键实际上就是开关,那么读取按键实际上就是2件事。1.检测开关有无打开;2.若开关打开,执行任务。让单片机知道我们按下的按键是哪一个按键,只有能够检测到按键按下去后,才能去执行任务。下面为按键读取函数。
/*按键读取函数*/
unsigned char Key_Read()
{
unsigned char temp;
if(P3_4 == 0) temp = 1;//该按键的IO口为P3_4
if(P3_5 == 0) temp = 2;//按下按键则按键接地,按键为0次量
if(P3_6 == 0) temp = 3;//哪个按键接地,则读取到哪一个按键
if(P3_7 == 0) temp = 4;
return temp;
}
再执行任务前,还需要在变量声明区添加一行代码,并且在主函数编写代码区域内(while(1){}中)添加4行代码,这5行代码死记硬背下来即可,代码如下。
/*在变量声明区中添加*/
unsigned char Key_Val;Key_Down;Key_Up;Key_Old;
/*在主函数编写区中添加*/
Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val & (Key_Val ^ Key_Old);//检测下降沿
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);//检测上升沿
Key_Old = Key_Val;//扫描辅助变量
1.3 例题
1.3.1 使用KEYX控制LEDX的亮灭状态
首先需要用按键控制Led的亮灭状态,所以按键读取函数必不可少。其次在按键之后,灯需要亮或者灭,这时候就需要一个选择函数,使用if或者switch函数就可以很好的解决,详细请看代码。
#include <REGX52.H>
#include <intrins.H>
/*延时函数声明*/
void Delay(unsigned int x)
unsigned char i, j;
while(x--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
/*按键读取函数*/
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P3_4 == 0) temp = 1;
if(P3_5 == 0) temp = 2;
if(P3_6 == 0) temp = 3;
if(P3_7 == 0) temp = 4;
return temp;
}
/*变量声明区域*/
unsigned char Led = 0xfe;
unsigned int Time = 1000;
unsigned char Key_Val,Key_Up,Key_Down,Key_Old;//按键扫描变量
/*主函数*/
void main()
{
while(1)
{
Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val & (Key_Val ^ Key_Old);//检测下降沿
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);//检测上升沿
Key_Old = Key_Val;//扫描辅助变量
switch(Key_Down)
{
case 1://按键1控制1灯亮
P1_1 = 0;
break;
case 2://按键2控制1灯灭
P1_1 = 1;
break;
}
}
若用按键来控制流水灯的亮灭状态,就需要用按键控制开始暂停标志位,由开始暂停标志位来控制流水灯的亮灭状态。代码如下。
#include <REGX52.H>
#include <intrins.H>
/*延时函数声明*/
void Delay(unsigned int x)
unsigned char i, j;
while(x--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
/*按键读取函数*/
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P3_4 == 0) temp = 1;
if(P3_5 == 0) temp = 2;
if(P3_6 == 0) temp = 3;
if(P3_7 == 0) temp = 4;
return temp;
}
/*变量声明区域*/
unsigned char Led = 0xfe;
unsigned int Time = 1000;
unsigned char Key_Val,Key_Up,Key_Down,Key_Old;//按键扫描变量
bit Flag = 1;//开始暂停标志位
/*主函数*/
void main()
{
while(1)
{
Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val & (Key_Val ^ Key_Old);//检测下降沿
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);//检测上升沿
Key_Old = Key_Val;//扫描辅助变量
switch(Key_Down)
{
case 1://按键1控制灯亮
Flag = 1;
break;
case 2://按键2控制灯灭
Flag = 0;
break;
}
P1 = Led;//流水灯
if(Flag == 1)
{
Delay(Time);//引用延时函数
Led = _crol_(Led,1);
}
}
}
1.3.2 使用按键控制流水灯的运行速度
此题与上题差异不大,直接将代码发在下面。
#include <REGX52.H>
#include <intrins.H>
void Delay(unsigned int x) //@12.000MHz
{
unsigned char i, j;
while(x--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
//按键读取函数
unsigned char Key_Read()
{
unsigned char temp = 0;
if(P3_4 == 0) temp = 1;
if(P3_5 == 0) temp = 2;
if(P3_6 == 0) temp = 3;
if(P3_7 == 0) temp = 4;
return temp;
}
unsigned char Led = 0xfe;
unsigned int Time = 1000;//其实时间为1000ms
unsigned char Key_Val,Key_Up,Key_Down,Key_Old;//按键扫描变量
bit Flag;//开始暂停标志位
void main()
{
while(1)
{
Key_Val = Key_Read();//读取键码值
Key_Down = Key_Val & (Key_Val ^ Key_Old);//检测下降沿
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);//检测上升沿
Key_Old = Key_Val;//扫描辅助变量
P1 = Led;
if(Flag == 1)
{
Delay(Time);
Led = _crol_(Led,1);
}
switch(Key_Down)
{
case 1:
Flag = 1;
break;
case 2:
Flag = 0;
break;
case 3://时间加快
Time = Time - 100;
break;
case 4://时间减慢
Time = Time + 100;
break;
}
}
}
1.4 编写Led彩灯控制代码
这一道例题的难度比前面的例题难度都要大的多,那么我们废话不多说,充满期待的与它见面吧
通过上面的例题,用S1和S2来控制彩灯系统的启动与暂停是没有太大问题的,但是如何用S3,S4来控制Led的显示模式呢?我们从题中可以得知,一共有四种模式,其中模式1,2为流水灯模式,而模式3,4为不规则的运行模式。再通过仔细观察可得,模式3和模式4有着相同的元素,是反着排序的。有了这些信息,为什么不可以把模式1,2分为一组,模式3,4分为一组。此外还需要考虑到像模式3,4这样不规律的运行模式可以采用数组Led_mode[4]来表示。代码如下。
那么到这里,今天所学的蓝桥杯知识以及记录完毕。学到了很多,也提升了不少。希望明天早早起床,明天就要学数控灯的相关知识啦!