第一,肯定是要画图嘛:这里用的是微软的Publisher。
说下我们的构思及要求:
1、当“按键1”按下后,“1”蓝色LED灯依次点亮,保持点亮状态。
2、当“按键2”按下后,“ 2” 蓝色LED灯依次点亮,完了,“1” 蓝色LED灯灭掉。
4、“ 3”红色LED点亮1秒后,灭。
5、“4”黄色LED依然点亮。
6、“ 5”八段管计数加1。
7、“ 6” 红色LED点亮3秒后,灭。
8、“ 7”绿色、蓝色LED灯依次点亮。
9、“8”屏幕显示。
当这图画好后,接下来就是焊硬件,由图纸到实物。
背面的接线图:
正面:
其实,那时候我心里没底的,超过40个LED,哪怕是个别并联后,还是超过89C51单片机的32个IO口,更何况八段管已经占用P0口,这样算下来,LED能用的就只有P1、2、3四个,24个灯位了。
其实,最开始我也想到要用寄存器来扩展IO口,尤其是八段管,但苦于功力不足,74HC164寄存器驱动八段管的程序没有调试成功,于是不得不降低要求,直接用P0口来。
非常抱歉,由于当时时间关系,所以实际上演示板的电路图我是没有画的(直到现在也没有画出来),而是直接焊电路板的。
八段管与单片机的连接电路图大概如下:
程序如下:
//--------------定义八段管显示------------------
chartab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x02,0xf8,0x00,0x10};
int n=0;
P0=0xc0; // 初始显示0
while(1)
{
if(k1==0) //判断按键按下
{
delay(30);
if(k1==0)
++n; //N加1
if(n==10) //如果N等于10,N为0
n=0;
P0=tab[n]; //将段码送P0口
}
}
八段管的问题解决了,接下来就是LED灯,一共47个LED灯,由于“4”、“7”部分LED灯是可以并联显示,所以,我还是要解决38个LED的显示。另外还需要2个按键、1个信号触发“8”显示屏,于是就变成22个IO口和38个LED灯。这样不得不用到寄存器了。华强北跑了一趟,买到的是74HC164。
74HC164与单片机、LED的连接电路图大概如下:
有了寄存器,只需要2个IO口就可以扩展连接8个LED,整个电路中,我一共用了3个74HC164,终于解放了紧张的IO口。
上电……调试,这里LED灯连接方式是共阳极,那么就需要74HC164依然输出低电平,二进制就是“0111 1111”换算成16进制为“0x7f”。
程序如下:
//--------------第一个74LS164函数-----------------
void In_164(uchar dat) //送数据进74LS164
{
uchar i;
for(i=0;i<8;i++)
{
dat=dat>>1; //移位8位
DS1=CY; //溢出位给数据端
SCLK1=0; //时钟脉冲
_nop_();
_nop_();
SCLK1=1;
_nop_();
_nop_();
SCLK1=0;
}
}
void LS3(void)
{
uchar temp=0x7f;
uchar i;
{
for(i=0;i<8;i++)
{
In_164(temp);
Delay_1ms(90); //延时1s
temp=(temp<<1)|(temp>>7); //循环移位
}
}
}
又有新的问题出现,由于74HC164平时是输出低电平的,故,只要一上电,LED全部点亮,执行程序后是依次灭灯。哎,几经周折,终于找到解决方法----直接在执行程序前先输出一串高电平……没想到我还是那么的聪明……嘻嘻
//-------------- 74LS164输出高电平-----------------
void LS1(void)
{
uchar temp=0xff;
uchar i;
{
for(i=0;i<8;i++)
{
In_164(temp);
Delay_1ms(20); //延时1s
temp=(temp<<1)|(temp>>7); //循环移位
}
}
}
至此,收工,主程序如下:
//--------------主函数-----------------
void main()
{
intn=0;
P0=0xc0; // 初始显示0
{LS1();}
{LS3();}
{LS5();}
while(1)
{
if(k1==0) //如果第一个按键按下
{
delay(30); //延时去抖
if(k1==0) //再判断是否按下
{
la1 = 0; //蓝色LED0点亮
delay(90); //调用延时程序
la2 = 0;
delay(90);
la3 = 0;
while(k1==0); //等待按键松开
}
}
if(k2==0) //如果第二个按键按下
{
delay(30); //延时去抖
if(k2==0) //再判断是否按下
{
la4 = 0;
delay(90);
la4 = 1; //蓝色LED4灭
la5 =0;
delay(90);
la5 = 1;
la6 =0;
delay(90);
la6 = 1;
la7 =0;
delay(90); /
la7 = 1;
la8 =0;
delay(90);
la8 = 1;
la1 = 1;
la2 = 1;
la3 = 1; //蓝色LED全部灭
ho1 =0; //红色LED点亮
delay(2000);
ho1 = 1;
hu1 = 0;
delay(90); //调用延时程序
hu1 = 1;
hu2 = 0;
delay(90);
hu2 = 1;
hu3 = 0;
delay(90);
hu3 = 1;
hu4 = 0;
delay(90);
hu4 = 1;
hu5 = 0;
delay(90);
hu5 = 1;
{LS2();LS1();}
++n; //N加1
if(n==10) //如果N等于10,N为0
n=0;
P0=tab[n]; //将段码送P0口
ho2=0; //置P0口为低电平
delay(2000); //调用延时程序
ho2 = 1;
{LS4();LS3();LS6();LS5();}
da1 =0;
delay(100);
da1 = 1;
}
while(k2==0); //等待按键松开
}
}
}
赠送一张“核心电路板”: