单片机交通灯课程设计
单片机交通灯设计(含箭头指示)
大家好,我是Alex,这篇文章是我做课程设计总结后想拿出来跟大家分享。我在完成交通灯的基本显示后,我对任务提出了更高的要求,增加了交通灯箭头显示,由于我对扩展芯片不熟悉,时间紧迫,我采用了增加AT89C51芯片的方法来对LED点阵进行控制。
在编程过程中发现了平时学习遗漏的问题,将所学的知识运用到实践中是非常关键的。编写程序是一个需要试错的过程,尝试不同种方法寻找最优解。有些复杂的程序也是通过不断的完善,由实现简单功能到实现多种功能。编程非常考验耐心,要坚持下来问题才有突破的可能。
希望你看了这篇文章后能有收获。
设计概况
(1)用P1.0、P1.1、P1.2控制东西通道的红、黄、绿灯;用P1.3、P1.4、P1.5控制南北通道的红、黄、绿灯;
(2)开始时,南北红灯亮并保持25秒,同时东西绿灯亮,保持20秒,20秒钟到了之后,东西绿灯闪烁3次(周期为1秒)后熄灭。继而东西黄灯亮并保持2秒,到2秒后,东西黄灯灭,东西红灯亮并保持25秒,同时南北红灯灭,南北绿灯亮20秒,20秒到了之后,南北绿灯闪烁3次(周期为1秒)后熄灭。继而南北黄灯亮并保持2秒,到2秒后,南北黄灯灭,南北红灯亮,同时东西红灯灭,东西绿灯亮。到此完成一个循环。
(3)出现紧急情况时,用中断方式实现南北、东西红灯持续亮10秒。注意保护现场。其中,要求使用P3.2引脚接收紧急控制信号,通过外部中断0实现紧急情况的交通灯控制操作。
实现在两位LED数码管上显示时间。
Proteus仿真模型
这里我使用的Proteus是ISIS7的版本和keil5进行C语言的编程。
序号 | 名称 | 数量 |
---|---|---|
1 | 两位数共阳极数码管 | 4 |
2 | AT89C51芯片 | 3 |
3 | 按键 | 4 |
4 | 电容器 | 9 |
5 | 12MHZ晶振 | 3 |
6 | LED-Green | 4 |
7 | LED-Red | 4 |
8 | LED-Yellow | 4 |
9 | 电阻 | 15 |
10 | 8x8点阵-Green | 4 |
11 | 8接口电阻排 | 1 |
仿真效果截图
效果图
主芯片
东西走向点阵接线
南北走向点阵
东西走向局部
南北走向局部
主芯片代码
#include<reg51.h>
unsigned char count=0;//count计数变量time倒计时初始值
unsigned int time;//time倒计时初始值
unsigned char led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳极数码管段选
void delay(unsigned int i)
{
unsigned int k;
for(k=0;k<i;k++);
}
void time0_5() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
count++;
}
void init0() //定时器初始函数
{
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET1=1;
TR1=1;
}
void disp()
{
delay(50);
P2=0x01; //十位位选
P0=led[time/10];
delay(50);
P0=0xff; //段选关闭
P2=0x02; //个位位选
P0=led[time%10];
delay(50);
}
void init1()//南北红灯20秒,东西绿灯20秒
{
time=20;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x0c;
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=20;
break;
}
}
disp();
}
}
void init2()//东西绿灯闪3次,南北红灯3秒
{
time=3;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x08; //东西绿灯灭,南北红灯亮
if(count==10) //0.5S到
{
P1=0x0c;
}
else if(count==20)
{
P1=0x08;
count=0;
time--;
if(time==0)
{
time=3;
break;
}
}
disp();
}
}
void init3()//东西黄灯,南北红灯2秒
{
time=2;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x0a;
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=2;
break;
}
}
disp();
}
}
void init4()//东西红灯20秒,南北绿灯20秒
{
time=20;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x21;
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=20;
break;
}
}
disp();
}
}
void init5()//南北绿灯闪3次,东西红灯3秒
{
time=3;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x01; //南北绿灯灭,东西红灯亮
if(count==10) //0.5S到
{
P1=0x21;
}
else if(count==20)
{
P1=0x01;
count=0;
time--;
if(time==0)
{
time=3;
break;
}
}
disp();
}
}
void init6()//南北黄灯,东西红灯2秒
{
time=2;
init0(); //初始化
while(1)
{
P0=0xff;
P1=0x11;
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=2;
break;
}
}
disp();
}
}
void emergency() interrupt 0 //紧急情况,禁止通行
{
unsigned char L,m,n,o;
EA=0;
L=P1;
m=TH1;
n=TL1;
o=time;
P1=0x09;
time=10;
while(1)
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
while(!TF1)
{
disp();
}
TF1=0;
count++;
if(count==20)
{
count=0;
time--;
}
if(time==0)
break;
}
EA=0;
P1=L;
TH1=m;
TL1=n;
time=o;
EA=1;
}
void main()
{
TMOD=0x10; //定时器工作方式1
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1; //总中断
PX0=1; //外部中断0位高优先级
EX0=1; //外部中断0
IT0=1; //外部中断0下降沿触发
ET1=1; //T1中断允许
P1=0x00;
while(1)
{
init1();//南北红灯20秒,东西绿灯20秒
init2();//东西绿灯闪3次,南北红灯3秒
init3();//东西黄灯,南北红灯2秒
init4();//东西红灯20秒,南北绿灯20秒
init5();//南北绿灯闪3次,东西红灯3秒
init6();//南北黄灯,东西红灯2秒
}
}
##副芯片代码1
#include<reg51.h>
unsigned char w,i,count=0;
unsigned int time;
void delay(unsigned int i)
{
unsigned int k;
for(k=0;k<i;k++);
}
void time0_5() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
count++;
}
void init0() //定时器初始函数
{
TMOD=0x10;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
EA=1;
ET1=1;
TR1=1;
}
void init1()//东西绿灯,直行右转10s
{
unsigned char led[]={0x7f,0x7b,0x79,0x00,0x79,0x1b,0x3f,0x7f};
init0();
time=10;
while(1)
{
w=0x01;
for(i=0;i<8;i++)
{
P1=w; //行
P2=led[i];//列
delay(20);
w<<=1;
}
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=10;
break;
}
}
}
}
%
此处省略**行
void init3()//关灯函数
{
P1=0x00;
P2=0xff;
init0();
time=30;
while(1)
{
if(count==20)//1S到
{
count=0; //计数清零
time--;
if(time==0)
{
time=30;
break;
}
}
}
}
void emergency() interrupt 0 //紧急情况,禁止通行
{
unsigned char k,L,m,n,o;
EA=0;
k=P1;
L=P2;
m=TH1;
n=TL1;
o=time;
time=10;
while(1)
{
delay(20);
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
while(!TF1)
{
unsigned char led[]={0x7e,0xbd,0xdb,0xe7,0xe7,0xdb,0xbd,0x7e};
w=0x01;
for(i=0;i<8;i++)
{
P1=w; //行
P2=led[i]; //列
delay(20);
w<<=1;
}
}
TF1=0;
count++;
if(count==20)
{
count=0;
time--;
}
if(time==0)
break;
}
EA=0;
P1=L;
TH1=m;
TL1=n;
time=o;
EA=1;
}
void main()
{
%
此处省略**行
%
while(1)
{
init1();//东西直行右转10s
init2();//东西左转10s
init3();//间隔30s
}
}
结束语
希望我的分享对你的学习有帮助。
加油学习人!!!
从简单的程序入手不断尝试,多试几次就可以了,最后祝你学习进步天天开心。