将一个由两个单位八段数码管显示的红绿灯程序改成一个四位八段数码管来显示。

想把一个由两个单位八段数码管显示的红绿灯程序改成一个四位八段数码管来显示。

原先的电路图如下

img

我想改成这个电路来显示

img

/红绿灯代码/
#include<reg52.h>
char code table[]={
0xc0,
0xf9,
0xa4,
0xb0,
0x99,
0x92,
0x82,
0xf8,
0x80,
0x90,
0x88,
0x83,
0xc6,
0xa1,
0x86,
0x8e
}; //把数组放入ROM中

sbit green=P1^0; //由P1^0接口控制绿灯亮灭。
sbit yellow=P1^1; //由P1^1接口控制黄灯亮灭。
sbit red=P1^2; //由P1^2接口控制红灯亮灭。

char tmp=0,sec=123; //本次设计中绿灯亮60s,黄灯亮3s,红灯亮60s。红黄绿灯都是通过倒计时来结束当前状态,时间周期一共是123s。

main()
{
//定时器的初始化
TMOD=0x01; //定时器方式一的设置
TR0=1; //time run
ET0=1; //定时器的使能
EA=1; //总中断打开
TH0=(65536-50000)/256; //50ms定时一次,高8位
TL0=(65536-50000)%256; //50ms定时一次,低8位
P3=0; //一开始,把所有的P3口都置0,相当于把所有的三极管都关闭

while(1)
{
if(sec==0) //说明一个周期已经运行完了,进入下一个周期
{
sec=123;
}

if(sec>63) //绿灯时间点,数码管显示的数字60-1,123>=sec>=64
{
green=0; //绿灯亮
yellow=1; //黄灯灭
red=1; //红灯灭
P2=table[(sec-63)/10];
P3=table[(sec-63)% 10];
}
else if(sec>60) //此时sec满足63>=sec>=61,绿灯开始灭,黄灯开始亮。

{
green=1; //绿灯灭
yellow=0; //黄灯亮
red=1; //红灯灭
P2=table[(sec-60)/10]; //显示的数字3到1
P3=table[(sec-60)% 10]; //显示的数字3到1
}

else

{
green=1; //绿灯灭
yellow=1; //黄灯灭
red=0; //红灯亮
P2=table[sec/10]; //显示的数字60到1
P3=table[sec%10]; //显示的数字60到1
}
}
}
void time0()interrupt 1 //这个interrupt是中断标志号1,在这里一定要与中断类型对应上,每50ms进入一次中断函数。
//CPU接收到了中断的请求后,会自动执行这个函数,但是不能在main函数中调用。
//定时器与延时相比,延时是需要调用的,相比之下处理效率比较慢,而定时就像后台自动执行,效率比较高。

{
TH0=(65536-50000)/256; //50ms定时一次,高8位
TL0=(65536-50000)%256; //50ms定时一次,低8位
//这里如果不重置TH0和TL0,那下一轮的中断就会变成65.536ms,导致系统出错

tmp++; //每隔50ms加一,加到多少就变成1s,20次

if(tmp==20) //这逻辑成立,代表是1s到
{
tmp=0; //计算下一轮的1s,让tmp置0
sec--; //每隔一秒要减一
}
}

这不是一样,P0.0,p0.1,p.02,p0.3是应该是控制每位亮灭,只要刷新快一点就是同时亮了,p2.0-2.7控制数字