昨天说的是LED的使用,多加练习大家就会对38译码器和锁存器有一个深入的了解。有所了解之后再学习蜂鸣器、数码管、继电器等外设的时候就轻松的多了。因为都是换汤不换药,这些外部设备使用的和LED相同的锁存和译码的方法。今天就先给大家讲解数码管的使用。
如果想要驱动数码管就要同时使用两个74HC573分别控制段选和位选。
从上图中我们可以看出U7控制的是段选,U8控制的是位选。所以程序的话就是依次使能段选
后送入段选信息再使能位选送入位选信息。(切记一定要把显示程序放在中断服务函数中,如果放在主函数中可能会乱码)
下面的是中断函数:
void timer0_init(void)
{
TMOD = 0x01;
TH0 = (65536 - 2000)/256;
TL0 = (65536 - 2000)%256;
EA = 1;
TR0 = 1;
ET0 = 1;
}
void timer0_isr(void) interrupt 1
{
TH0 = (65536 - 2000)/256;
TL0 = (65536 - 2000)%256;
// cp1++;
// if(cp1 >=250) //记时半秒中断一次
// {
// cp1 = 0;
// cp2++;
// }
// if(cp2 >= 1)
// {
// cp2 = 0;
//
// }
void display();
}
下面就是数码管的控制程序:
usnigend char code seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void display()
{
switch(i)
{
case 0: P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x01;WR = 1;break;
case 1: P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x02;WR = 1;break;
case 2:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x04;WR = 1;break;
case 3:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x08;WR = 1;break;
case 4:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x10;WR = 1;break;
case 5:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x20;WR = 1;break;
case 6:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x40;WR = 1;break;
case 7:P25 = 1;P26 = 1;P27 = 1;
WR = 0;P0 = seven_seg[];WR = 1;
WR = 0;P0 = 0x80;WR = 1;break;
}
i++;
if(i>=8) i = 0;
}
只需要在seven_seg[ ]中输入你想显示的0—9的数字就会在数码管上显示出来。0x01是左边第一个数码管,0x80
是最右边的数码管,以此类推。当然也可以使用位操作的方式,位操作也是我比较推荐大家去使用的一种方式。不太推荐
大家对单一的端口进行进行操作,因为单一的端口操作虽然思路会比较清晰,但是比较浪费时间。在比赛的时候时间短暂
所以比较推荐大家使用节省时间,而且思路清晰的方法。位操作一般情况下不会对其他的端口产生影响。
void display()
{
switch(i)
{
case 0:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x01;WR = 1;P2 &= 0x1f;break;
case 1:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x02;WR = 1;P2 &= 0x1f;break;
case 2:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x04;WR = 1;P2 &= 0x1f;break;
case 3:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x08;WR = 1;P2 &= 0x1f;break;
case 4:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x10;WR = 1;P2 &= 0x1f;break;
case 5:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x20;WR = 1;P2 &= 0x1f;break;
case 6:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x40;WR = 1;P2 &= 0x1f;break;
case 7:P2 = (P2&0x1f)|0xe0;WR = 0;P0 = seven_seg[];WR = 1;P2&0x1f;
P2 = (P2&0x1f)|0xc0;WR = 0;P0 = 0x80;WR = 1;P2 &= 0x1f;break;
}
i++;
if(i >= 8) i = 0;
}
讲完了数码管的显示,紧接着我们趁热打铁讲述蜂鸣器的使用:
从上面的两个图我们可以看出蜂鸣器是通过74HC573之后,又经过了一个ULN2003的芯片以后连接到了OUT7
引脚上。ULN2003是一个我们常见的驱动芯片,熟悉单片机的朋友可能经常使用ULN2003来做电机的驱动芯片。
百度百科对ULN2003的解释是:ULN2003是高耐压、大电流复合晶体管阵列,由七个硅NPN 复合晶体管组成,每一对达林
顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器
来处理的数据。
由上图我们可以看出ULN2003仅仅是起到了一个电平转换的作用,因此我们在程序上不需要特别多的去关注ULN200
3的功能。
下面就是ULN2003的通用控制的程序,在只需要键入想要的x的值就可以控制ULN2003了。
void ULN2003(unsigned char x)
{
P2 = (P2&0x1f)|0xa0;
WR = 0;
P0 = x;
WR = 1;
P2 &= 0x1f;
P0 = 0x00;
}