设计要求:1.按照红-绿-黄顺序轮流点亮
2、南北方向、东西方向轮流放行,红灯15s,绿灯12s,黄灯闪烁3秒,同时有数码管显示倒计时3、必须用到定时器、中断
设计思路:
1.利用硬件定时器+硬件计数器实现1s倒计时
2.定义1个标志位作为方向标志,判断标志位确定是东西向红灯还是南北向红灯
3.定义两个时间变量,并用数码管显示。
4.南北向红灯时,判断较大的时间变量是否小于3,确定是否需要东西向黄灯闪烁,判断较大的时间变量是否为0,确定该南北向红灯时间结束,并将方面标志位置1。
东西向红灯时,判断较大的时间变量是否小于3,确定是否需要南北向黄灯闪烁,判断较大的时间变量是否为0,确定该东西向红灯时间结束,并将方面标志位置0。
#include<reg51.h>
#define uint unsigned int
#define uchar unsigned char
#define red (~0x01)
#define yellow (~0x02)
#define green (~0x04)
#define left (~0x08)
#define nbred (~0x10)
#define nbyellow (~0x20)
#define nbgreen (~0x40)
#define nbleft (~0x80)
uint num2;
uchar dx_js,nb_js;
uchar zt;
uchar code dxcz[]={0,12,3 ,15,15-12,};
uchar code nbcz[]={0,15,15-12,12, 3,};
uchar code tab1[]={0,12, 3,12, 3,};
uchar code tab2[]={0,
0xFF&green&nbred,
0xFF&yellow&nbred,
0xFF&red&nbgreen,
0xFF&red&nbyellow,
};
sbit D0=P2^0;
sbit D1=P2^1;
sbit D2=P2^2;
sbit D3=P2^3;
uchar ds[4];
uchar code tab[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,};
//数码管显示
void smxs(){
static uchar a;
if(a>3)a=0;
P2&=0xf0;
P0=tab[ds[a]];
switch(a){
case 0:D0=1;break;
case 1:D1=1;break;
case 2:D2=1;break;
case 3:D3=1;break;
}
a++;
}
void init() //初始化函数
{ TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
EA=1;
ET0=1;
}
void main()//主函数
{
init();
zt=1;
num2=0;
dx_js=dxcz[zt];
nb_js=nbcz[zt];
TR0=1;
while(1){
P1=tab2[zt];
ds[0]=dx_js/10;
ds[1]=dx_js%10;
ds[2]=nb_js/10;
ds[3]=nb_js%10;
}
}
void timer0() interrupt 1//定时器,实现倒计时
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
if(++num2==1000){//1s
num2=0;
dx_js--;//倒计时
nb_js--;
if(dx_js==0||nb_js==0){//到0
zt++;//状态加1
if(zt==5){
zt=1;
}
dx_js=dxcz[zt];//重新开始计时
nb_js=nbcz[zt];
}
}
smxs();
}