基于Proteus仿真51交通灯毕设.docx
《基于Proteus仿真51交通灯毕设.docx》由会员分享,可在线阅读,更多相关《基于Proteus仿真51交通灯毕设.docx(10页珍藏版)》请在冰豆网上搜索。
基于Proteus仿真51交通灯毕设
基于51单片机的交通灯C语言程序设计
2011-05-0707:
57
十字交叉路口的交通灯控制器,是很常见的课程设计题目。
做而论道以前写过一个,功能十分简单。
最近,综合了一些XX知道中的题目要求,写出了一个稍稍复杂一点设计方案,使用了大家比较喜欢的C语言编写程序。
基本功能如下:
(1)东西、南北方向各设有一个绿、黄、红指示灯,两个显示数码管。
(2)两个方向交替允许通行,基本放行时间为25s,另外有黄灯闪烁5s。
(3)控制人员可以暂停自动的交替,使某个方向可以无限长时间的通行。
(4)暂停期间,控制人员可以调整通行的时间,程序中还设置了调整的上下限。
(5)暂停之后,灯光将按照设置的通行时间自动变换通行方向。
(6)在正常通行期间,可以强制变换通行方向。
强制变换的时候,也是要先显示闪烁的黄灯,然后切换到指定的方向。
程序用PROTEUS仿真成功,并没有进行硬件实验。
仿真截图画面如下。
C语言的控制程序如下:
//------------------------------------------------
#include
#defineucharunsignedchar
#defineuintunsignedint
uchardatabuf[4];
uchardatasec_dx=30;//东西数默认
uchardatasec_nb=30;//南北默认值
uchardataset_timedx=30;
uchardataset_timenb=30;
intn;
uchardatab;//定时器中断次数
sbitk1=P1^6;//定义5组开关
sbitk2=P1^7;
sbitk3=P2^7;
sbitk4=P3^0;
sbitk5=P3^1;
sbitYellow_nb=P2^5;//南北黄灯标志
sbitYellow_dx=P2^2;//东西黄灯标志
sbitGreen_nb=P2^4;
sbitGreen_dx=P2^1;
sbitRed_nb=P2^6;
sbitRed_dx=P2^3;
sbitBuzz=P3^7;
bitBuzzer_Indicate;
bittime=0;//灯状态循环标志
bitset=1;//调时方向切换键标志
ucharcodetable[10]={//共阴极字型码
0x3f,//--0
0x06,//--1?
0x5b,//--2?
0x4f,//--3
0x66,//--4?
0x6d,//--5
0x7d,//--6
0x07,//--7?
0x7f,//--8
0x6f,//--9//0x00//--NULL
};
//函数的声明部分
voiddelay(intms);//延时子程序
voidkey();//按键扫描子程序
voidkey_to1();//键处理子程序
voidkey_to2();
voidkey_to3();
voiddisplay();//显示子程序
voidlogo();//开机LOGO
voidBuzzer();
//主程序
voidmain()
{
TMOD=0X01;
TH0=0XD8;
TL0=0XF0;
EA=1;
ET0=1;
TR0=1;
EX0=1;
EX1=1;
logo();
P2=0Xc3;//开始默认状态,东西绿灯,南北黄灯
sec_nb=sec_dx+5;
while
(1)
{
key();//调用按键扫描程序
display();//调用显示程序
Buzzer();
}
}
//函数的定义部分
voidkey()//按键扫描子程序
{
if(k1!
=1)
{
delay(10);
if(k1!
=1)
{
while(k1!
=1)
{
key_to1();
for(n=0;n<40;n++)
{display();}
}
}
}
if(k2!
=1)
{
delay(10);
if(k2!
=1)
{
while(k2!
=1)
{
key_to2();
for(n=0;n<40;n++)
{display();}
}
}
}
if(k3!
=1)
{
TR0=1;//启动定时器
Buzzer_Indicate=0;
sec_nb=set_timenb;//从中断回复,仍显示设置过的数值
sec_dx=set_timedx;
if(time==0)
{P2=0X99;sec_nb=sec_dx+5;}
else{P2=0xC3;sec_dx=sec_nb+5;}
}
if(k4!
=1)
{
delay(10);
if(k4!
=1)
{
while(k4!
=1);
set=!
set;
}
}
if(k5!
=1)
{
delay(10);
if(k5!
=1)
{
while(k5!
=1)
key_to3();
}
}
}
voiddisplay()//显示子程序
{
buf[1]=sec_dx/10;//第1位东西秒十位
buf[2]=sec_dx%10;//第2位东西秒个位
buf[3]=sec_nb/10;//第3位南北秒十位
buf[0]=sec_nb%10;//第4位南北秒个位
P1=0xff;//初始灯为灭的
P0=0x00;
P1=0xfe;//片选LCD1
P0=table[buf[1]];
delay
(1);
P1=0xff;
P0=0x00;
P1=0xfd;//片选LCD2
P0=table[buf[2]];
delay
(1);
P1=0xff;
P0=0x00;
P1=0Xfb;//片选LCD3
P0=table[buf[3]];
delay
(1);
P1=0xff;
P0=0x00;
P1=0Xf7;
P0=table[buf[0]];//片选LCD4
delay
(1);
}
voidtime0(void)interrupt1using1//定时中断子程序
{
b++;
if(b==19)//定时器中断次数
{b=0;
sec_dx--;
sec_nb--;
if(sec_nb<=5&&time==0)//东西黄灯闪
{Green_nb=0;Yellow_nb=!
Yellow_nb;}
if(sec_dx<=5&&time==1)//南北黄灯闪
{Green_dx=0;Yellow_dx=!
Yellow_dx;}
if(sec_dx==0&&sec_nb==5)
sec_dx=5;
if(sec_nb==0&&sec_dx==5)
sec_nb=5;
if(time==0&&sec_nb==0)
{P2=0x99;time=!
time;sec_nb=set_timenb;sec_dx=set_timenb+5;}
if(time==1&&sec_dx==0)
{P2=0Xc3;time=!
time;sec_dx=set_timedx;sec_nb=set_timedx+5;}
}
}
voidkey_to1()//键盘处理子程序之+
{
TR0=0;//关定时器
if(set==0)
set_timenb++;//南北加1S
else
set_timedx++;//东西加1S
if(set_timenb==100)
set_timenb=1;
if(set_timedx==100)
set_timedx=1;//加到100置1
sec_nb=set_timenb;//设置的数值赋给东西南北
sec_dx=set_timedx;
}
voidkey_to2()//键盘处理子程序之-
{
TR0=0;//关定时器
if(set==0)
set_timenb--;//南北减1S
else
set_timedx--;//东西减1S
if(set_timenb==0)
set_timenb=99;
if(set_timedx==0)
set_timedx=99;//减到1重置99
sec_nb=set_timenb;//设置的数值赋给东西南北
sec_dx=set_timedx;
}
voidkey_to3()//键盘处理之紧急车通行
{
TR0=0;
P2=0Xc9;
sec_dx=00;
sec_nb=00;
Buzzer_Indicate=1;
}
voidint0(void)interrupt0using1//只允许东西通行
{
TR0=0;
P2=0Xc3;
Buzzer_Indicate=0;
sec_dx=00;
sec_nb=00;
}
voidint1(void)interrupt2using1//只允许南北通行
{
TR0=0;
P2=0X99;
Buzzer_Indicate=0;
sec_nb=00;
sec_dx=00;
}
voidlogo()//开机的Logo"----"
{for(n=0;n<50;n++)
{
P0=0x40;
P1=0xfe;
delay
(1);
P1=0xfd;
delay
(1);
P1=0Xfb;
delay
(1);
P1=0Xf7;
delay
(1);
P1=0xff;
}
}
voidBuzzer()
{
if(Buzzer_Indicate==1)
Buzz=!
Buzz;
elseBuzz=0;
}
voiddelay(intms)//延时子程序
{
uintj,k;
for(j=0;jfor(k=0;k<124;k++);
}