目录
一、控制独立按键
1、独立按键原理图
独立按键是一类电子开关,按下时断路变为通导,松开时又由通导变为断路。
2、具体操作独立按键及消抖处理
K1对应的是P3_1,K2对应的是P3_0,K3对应的是P3_2,K4对应的是P3_3。
由于按键是机械弹性开关,在闭合时会出现抖动,为了防止按键被误读,要进行消抖。消抖主要有硬件消抖和软件消抖两种方式。这里主要介绍软件消抖,以独立按键操作LED显示·二进制为例,通过Delay函数和while循环来实现消抖。
Delay函数:
void Delay(unsigned int xms) //@12.000MHz
{
while(xms)
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
if(P3_1==0)
{
Delay(20);//按下时延时
while(P3_1==0);//确保松开时LED状态才开始发生变化
Delay(20);//松开时延时
P2--;
二、控制LED
1、LED原理图
发光二极管的核心是二极管的空穴和电子在电压的作用下从电极流向PN结。当空穴和电子相遇而产生复合,电子会跌落到较低能阶,同时以光的形式释放能量。
当外界有正向电压偏置时,外界电场和自建电场相互抑消作用使载流子的扩散电流增加引起了正向电流。当外界有反向电压偏置时,外界电场和自建电场进一步增强,形成反向饱和电流。【【硬件】LED灯发光原理总结 - CSDN App】
2、具体操作LED以及如何通过独立按键操作LED
每个LED的正极都接了VCC,并通过电阻进行限流。此时LED负极若接上低电平(0),可形成正向电流,LED亮;若接上高电平(1)则反之。P2代表八个LED,而LED的D1~D8分别对应P2_0~P2_7。
通过P2实现LED流水灯:
while(1)
{ P2=0xFE;//1111 1110
Delay1ms(100);
P2=0xFD;//1111 1101
Delay1ms(100);
P2=0xFB;//1111 1011
Delay1ms(100);
P2=0xF7;//1111 0111
Delay1ms(100);
P2=0xEF;//1110 1111
Delay1ms(100);
P2=0xDF;//1101 1111
Delay1ms(100);
P2=0xBF;//1011 1111
Delay1ms(100);
P2=0x7F;//0111 1111
Delay1ms(100);
}
也可通过独立按键对LED进行操作,控制LED亮灭,显示二进制,LED移位。
主要分为两个步骤。首先用if语句对P3状态进行判断,再对P2赋值进行操作,以下以独立按键控制LED实现移位为例。
unsigned char Lednum=0x00;
while(1)
{
unsigned char x;
if(P3_1==0)
{
Delay(20);
while(P3_1==0);
Delay(20);
x=0x01<<Lednum%8;
P2=~x;
Lednum++;
}
}
三、控制数码管
1、数码管原理图
数码管是一种由多个发光二极管封装在一起组成“8”字型的显示器。通过引脚定义,可将数码管分为一位的数码管和四位一体的数码管。
下图为共阴极的一位数码管,8个LED的阴极连接在一起,形成公共端,每个位置的LED名称不同,且各自连接在就近的引脚上,因此通过控制引脚电平可以点亮不同位置的LED从而显示特定字符。
例如,对于共阴极数码管,如果想要显示“U”,则要点亮B、C、D、E、F处的LED灯,则6、4、2、1、9处引脚要给高电平(1),而7、9、10、5处引脚要给低电平(0)。
而我们学习的单片机中的数码管属于四位一体的数码管。同样地,每八个LED组成一个数码管,LED的阴极连接在一起,每个数码管的公共端单独引出;而四个数码管的非公共端连接在一起。点亮数码管需要控制位选和段选,位选即要点亮哪个位置的数码管,段选则是具体点亮哪个位置的LED,形成相应的字符。
而数码管的公共端接在了138译码器的输出端上。输入端A、B、C中C是高位,B其次,A是低位。要选中某个数码管显示字符,只要给138译码器输入端一个数据,该数据由二进制转化为十进制,对应Y1~Y7八个LED。
例如要选择LED1,对应的是Y0,只要给输入端数据000;要选择LED8,对应的是Y7,给输入端数据111即可。
2、具体操作静态数管显示
可以建立一个函数和一个数组,在需要某个数码管显示特定字符时调用会更加方便。
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};//段选
int Nixie(unsigned char Location,Number)
{
switch(Location)//位选
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number];
}
3、具体操作动态数码管显示
由于非公共端连接在一起,因此四位一体的数码管不可能同一时刻显多个字符。但因为人眼视觉暂留,可以通过不断地扫描使数码管看上去是几个字符同时显示。每个数码管亮后延时一秒,再将P0清零,再扫描下一个数码管,在循环中反复执行这几步,即可达到几个数码管同时亮不同字符的效果。
#include <REGX52.H>
void Delay(unsigned int xms) //@12.000MHz
{
while(xms){
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
xms--;
}
}
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};
int Nixie(unsigned char Location,Number)
{
switch(Location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[Number];
Delay(1);
P0=0x00;
}
void main()
{
while(1)
{
Nixie(1,1);
Nixie(2,2);
Nixie(3,3);
}
}
4、具体操作实现独立按键控制数码管
要实现独立按键控制数码管,也主要是两个步骤:先对独立按键状态进行判断,再利用函数对P0赋值操作数码管。同时要注意以下几个方面:
1、如何保证在按下独立按键之后,数码管能一直保持同时亮几个不同的字符?
数码管保持同时亮几个字符需要不断扫描,如果是按控制LED的方式控制数码管,会导致数码管只在按键按下之后只闪一下的情况。 此时可以建立一个扫描函数,每循环一次都扫描独立按键是否按下,在按键按下时函数返回特定的值keynum,再对keynum判断改变变量mode,通过判断mode的值改变P0的状态,只要mode不变,P0状态一直不变,从而实现持续扫描数码管。
unsigned int saomiao()
{
int key;
key=0;
if(P3_1==0) {Delay(20);key=1;}
return key;
}
void main()
{
while(1)
{
int keynum;
int lastkeynum;
int mode;
keynum=saomiao();
if(lastkeynum==0&&keynum==1) mode=1;
if(mode==1)
{
Nixie(1,10);
}
lastkeynum=keynum;//防抖
}
}
2、如何实现定时改变数码管的状态?
如果此时使用Delay函数,会导致数码管无法不断扫描,只能定时在一个数码管出现一种字符。 通过建立一个变量i计循环次数,再结合每轮循环所进行的时间可以粗略估计时间。(注意:i>=某个值)
void main()
{
int i;
int j;
j=0
i=0;
while(1)
{
if(i>=230)
{
Nixie(1,10);
Nixie(2,2);
Nixie(7,j/10);
Nixie(8,j%10);
j++;
}
i++;
}
}