基于51单片机的交通灯设计
(仿真+程序+原理图+PCB+设计报告)
功能介绍
具体功能:
1、采用四方向数码管设计,更加符合真实的交通信号灯设计;
2、左侧按键从上到下依次为:复位、夜间模式、紧急模式、设定时间、时间加、时间减;
3、夜间模式:按下"夜间模式"按键后,四个方向的黄灯闪烁。再次按下则退出;
4、紧急模式:当救护车、救火车等通过时,按下"紧急模式"按键,四个方向全部亮红灯,待紧急车辆通过后,再次按键退出;
5、设定时间时,第一次按下"设定时间"键,设定东西方向的倒计时时间,东西方向的两个数码管亮,再次按下"设定时间"键,则设定南北方向的倒计时时间,同时南北方向的两个数码管亮,再次按下则退出设定状态,开始运行;
演示视频:
基于51单片机的交通灯设计---夜间、紧急、复位、可调时间、四个数码管显示
添加图片注释,不超过 140 字(可选)
程序
cs
#include<reg51.h>
/***微信公众号:木子单片机****/
#include<intrins.h> //包含库文件
sbit smg1=P3^0; //定义南北方向数码管低位
sbit smg2=P3^1; //定义南北方向数码管高位
sbit smg3=P3^2; //定义东西方向数码管低位
sbit smg4=P3^3; //定义东西方向数码管高位
sbit N_green=P2^0; //定义北向绿灯端口
sbit N_red=P2^1; //定义北向红灯端口
sbit N_yellow=P2^2; //定义北向黄灯端口
sbit S_green=P2^7; //定义南向绿灯端口
sbit S_red=P2^6; //定义南向红灯端口
sbit S_yellow=P2^5; //定义南向黄灯端口
sbit W_green=P1^0; //定义西向绿灯端口
sbit W_red=P1^1; //定义西向红灯端口
sbit W_yellow=P1^2; //定义西向黄灯端口
sbit E_green=P1^7; //定义东向绿灯端口
sbit E_red=P1^6; //定义东向红灯端口
sbit E_yellow=P1^5; //定义东向黄灯端口
sbit k0=P3^4; //定义复位按键
sbit k1=P3^5; //定义夜间模式按键
sbit k2=P3^6; //定义紧急模式按键
sbit menu=P3^7; //定义设定时间按键
sbit zj=P1^3; //定义时间加按键
sbit jx=P1^4; //定义时间键按键
int kkk=0,fk=0;
int djs22,js1=0,djs21,flgaa,nbdjs=20,dxdjs=20; //以上为临时变量
int js=0,djs=20,djs1=20; //初始倒计时时间
int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40}; //共阴极数码管段值
/************以下为函数声明*************/
void jtd();
void jtda();
void jtdb();
void djsxs();
void yj();
void jj();
void jtday();
void jtdby();
/*****************************************************/
/* 函数名:delayms */
/* 功能:产生毫秒级延时 */
/*****************************************************/
void delayms(int x)
{
char i;
while(x--)
{
for(i=150;i>0;i--);
}
}
/*****************************************************/
/* 函数名:Timer0_init() */
/* 功能:定时器0初始化 */
/*****************************************************/
void Timer0_init()
{
js=0;
TMOD=0x01; //定义定时器0工作模式
TH0=0x4c; //赋初值高位
TL0=0x00; //赋初值低位
TR0=1; //启动定时器
ET0=1; //开中断
EA=1; //开全局中断
}
/*****************************************************/
/* 函数名:timer0() interrupt 1 using 1 */
/* 功能:定时器0中断服务函数 */
/*****************************************************/
void timer0() interrupt 1 using 1
{
TF0=0;
TH0=0x4c;
TL0=0x00; //重新赋高地位初值
js++;
if(js==22)
{ js=0;
djs--;
djs1--;
kkk++; //以上用于产生1S中断
}
}
/*****************************************************/
/* 函数名:djsxs22() */
/* 功能:4个数码管动态显示 */
/*****************************************************/
void djsxs22()
{ int b1,b2;
b1=djs1/10; //将倒计时时间的高位赋予b1
b2=djs1%10; //将倒计时时间的低位赋予b2
P0=table[b1];
smg1=0;
delayms(3);
smg1=1; //显示b1
P0=table[b2];
smg2=0;
delayms(3);
smg2=1; //显示b2
P0=table[b1];
smg3=0;
delayms(3);
smg3=1; //显示b1
P0=table[b2];
smg4=0;
delayms(3);
smg4=1; //显示b2
}
/*****************************************************/
/* 函数名:djsxs11() */
/* 功能:4个数码管动态显示 */
/*****************************************************/
void djsxs11() //此函数注视同djsxs22()
{ int b1,b2;
b1=djs/10; //将倒计时时间的高位赋予b1
b2=djs%10; //将倒计时时间的低位赋予b2
P0=table[b1];
smg1=0;
delayms(3);
smg1=1; //显示b1
P0=table[b2];
smg2=0;
delayms(3);
smg2=1; //显示b2
P0=table[b1];
smg3=0;
delayms(3);
smg3=1; //显示b1
P0=table[b2];
smg4=0;
delayms(3);
smg4=1; //显示b2
}
/*****************************************************/
/* 函数名:djsxs1() */
/* 功能:用来显示设定东西倒计时的时间 */
/*****************************************************/
void djsxs1()
{ int b1,b2;
b1=djs1/10; //将倒计时时间的高位赋予b1
b2=djs1%10; //将倒计时时间的低位赋予b2
P0=table[b1];
smg3=0;
delayms(3);
smg3=1; //显示b1
P0=table[b2];
smg4=0;
delayms(3); //显示b2
smg4=1;
}
/*****************************************************/
/* 函数名:djsxs() */
/* 功能:用来显示设定南北倒计时的时间 */
/*****************************************************/
void djsxs()
{ int b1,b2;
b1=djs/10; //将倒计时时间的高位赋予b1
b2=djs%10; //将倒计时时间的低位赋予b2
P0=table[b1];
smg1=0;
delayms(3);
smg1=1; //显示b1
P0=table[b2];
smg2=0;
delayms(3);
smg2=1; //显示b2
}
/*****************************************************/
/* 函数名:jj() */
/* 功能:紧急模式,按下紧急模式按键后,四个方向 */
/* 数码管灭,红灯全亮,用于紧急车辆通过使 */
/* 用,比如消防车、救护车等。 */
/*****************************************************/
void jj()
{
N_green=1; //北向绿灯灭
N_red=0; //北向红灯亮
N_yellow=1; //北向黄灯灭
S_green=1; //南向绿灯灭
S_red=0; //南向红灯亮
S_yellow=1; //南向黄灯灭
W_green=1; //西向绿灯灭
W_red=0; //西向红灯亮
W_yellow=1; //西向黄灯灭
E_green=1; //东向绿灯灭
E_red=0; //东向红灯亮
E_yellow=1; //东向黄灯灭
while(1)
{
if(k2==0) //紧急按键按下
{
delayms(3);
if(k2==0)
{ while(!k2); //去除抖动,确认是否紧急按键按下
TR0=1; //启动定时器,以下四句用来判断回到哪个模式的
if(flgaa==0) jtda(); //当flgaa=0时,回到jtda()函数
if(flgaa==1) jtdb(); //当flgaa=1时,回到jtdb()函数
if(flgaa==2) jtday(); //当flgaa=2时,回到jtday()函数
if(flgaa==3) jtdby(); //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里
}
}
}
}
/*****************************************************/
/* 函数名:qm() */
/* 功能:使所有的交通信号灯全部熄灭 */
/*****************************************************/
void qm()
{
N_green=1;
N_red=1;
N_yellow=1;
S_green=1;
S_red=1;
S_yellow=1;
W_green=1;
W_red=1;
W_yellow=1;
E_green=1;
E_red=1;
E_yellow=1;
}
/*****************************************************/
/* 函数名:set_djs1() */
/* 功能:设定南北方向倒计时时间 */
/*****************************************************/
void set_djs1()
{
while(1)
{
djsxs1(); //南北方向数码管显示当前时间
if(zj==0) //增加按键按下
{
delayms(3);
if(zj==0)
{ while(!zj); //去除抖动,确认是否增加按键按下
if(djs1>=99) djs1=99; //倒计时最大设定时间为99秒
else djs1++; //时间小于99秒时加一
nbdjs=djs1; //保存当前设定时间
}
}
if(jx==0) //减少按键按下
{
delayms(3);
if(jx==0)
{ while(!jx); //去除抖动,确认是否减少按键按下
if(djs1<=6) djs1=6; //倒计时最小设定时间为6秒
else djs1--; //时间大于6秒时减一
nbdjs=djs1; //保存当前设定时间
}
}
if(menu==0) //设定时间按键按下
{
delayms(3);
if(menu==0)
{ while(!menu); //去除抖动,确认是否按下
TR0=1; //定时器停止
nbdjs=djs1; //保存当前设定时间
jtda(); //调用函数
}
}
}
}
/*****************************************************/
/* 函数名:set_djs() */
/* 功能:设定东西方向倒计时时间 */
/*****************************************************/
void set_djs()
{
while(1)
{
djsxs(); //东西方向数码管显示当前时间
if(zj==0) //增加按键按下
{
delayms(3);
if(zj==0)
{ while(!zj); //去除抖动,确认是否增加按键按下
if(djs>=99) djs=99; //倒计时最大设定时间为99秒
else djs++; //时间小于99秒时加一
dxdjs=djs; //保存当前设定时间
}
}
if(jx==0) //减少按键按下
{
delayms(3);
if(jx==0)
{ while(!jx); //去除抖动,确认是否减少按键按下
if(djs<=6) djs=6; //倒计时最小设定时间为6秒
else djs--; //时间大于6秒时减一
dxdjs=djs; //保存当前设定时间
}
}
if(menu==0) //设定时间按键按下
{
delayms(3);
if(menu==0)
{ while(!menu); //去除抖动,确认是否按下
TR0=0; //定时器停止
dxdjs=djs; //保存当前设定时间
set_djs1(); //调用南北倒计时时间设定函数
}
}
}
}
/*****************************************************/
/* 函数名:yj() */
/* 功能:夜间模式,按下夜间模式按键后,四个方向 */
/* 数码管灭,黄灯闪烁,使用与夜晚车辆较少 */
/* 时使用。 */
/*****************************************************/
void yj()
{
int i;
qm(); //信号灯全部熄灭
while(1)
{
W_yellow=0; //以下四行表示四个方向的黄灯亮
E_yellow=0;
S_yellow=0;
N_yellow=0;
for(i=0;i<9000;i++) //for语句,在这个作用是循环执行"是否夜间模式按键"按下,起到延时左右
{
if(k1==0) //夜间模式按键按下
{
delayms(3);
if(k1==0)
{ while(!k1); //去除抖动,确认是否按下
TR0=1; //启动定时器,以下四句用来判断回到哪个模式的
if(flgaa==0) jtda(); //当flgaa=0时,回到jtda()函数
if(flgaa==1) jtdb(); //当flgaa=1时,回到jtdb()函数
if(flgaa==2) jtday(); //当flgaa=2时,回到jtday()函数
if(flgaa==3) jtdby(); //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里
}
}
}
W_yellow=1; //以下四行表示四个方向的黄灯亮
E_yellow=1;
S_yellow=1;
N_yellow=1;
for(i=0;i<9000;i++) //for语句,在这个作用是循环执行"是否夜间模式按键"按下,起到延时左右
{
if(k1==0) //夜间模式按键按下
{
delayms(3);
if(k1==0)
{ while(!k1); //去除抖动,确认是否按下
TR0=1; //启动定时器,以下四句用来判断回到哪个模式的
if(flgaa==0) jtda(); //当flgaa=0时,回到jtda()函数
if(flgaa==1) jtdb(); //当flgaa=1时,回到jtdb()函数
if(flgaa==2) jtday(); //当flgaa=2时,回到jtday()函数
if(flgaa==3) jtdby(); //当flgaa=3时,回到jtday()函数 这样的作用是,紧急模式从哪里进入,回到哪里
}
}
}
}
}
/*****************************************************/
/* 函数名:jtdb() */
/* 功能:交通灯东西方向绿灯亮,红灯灭 */
/* 交通灯南北方向红灯亮,绿灯灭 */
/*****************************************************/
void jtdb()
{
qm(); //所有信号灯灭
flgaa=1; //标志位
W_green=0; //西向绿灯亮
E_green=0; //东向绿灯亮
N_red=0; //北向红灯亮
S_red=0; //南向红灯亮
while(1)
{
if(djs1>5) //当倒计时时间大于5秒时,执行
{
if(k0==0) //是否"复位"按键按下
{
delayms(3);
if(k0==0)
{ while(!k0); //去除抖动,确定是否"复位"按键按下
djs=20; //倒计时时间重新赋值
djs1=20; //倒计时时间重新赋值
dxdjs=djs; //将东西方向的倒计时时间保存
nbdjs=djs1; //将南北方向的倒计时时间保存
jtda(); //调用jtda()函数
}
}
if(k2==0) //是否"紧急模式"按键按下
{
delayms(3);
if(k2==0)
{ while(!k2); //去除抖动,确定是否"紧急模式"按键按下
TR0=0; //启动定时器
jj(); //调用紧急模式
}
}
if(k1==0) //是否"夜间模式"按键按下
{
delayms(3);
if(k1==0)
{ while(!k1); //去除抖动,确定是否"夜间模式"按键按下
TR0=0; //启动定时器
yj(); //调用夜间模式
}
}
if(menu==0) //是否"设定倒计时时间"按键按下
{
delayms(3);
if(menu==0)
{ while(!menu); //去除抖动,确定是否"设定倒计时时间"按键按下
TR0=0; //启动定时器
set_djs(); //调用设定倒计时时间函数
}
}
djsxs22(); //数码管时间显示
}
if(djs1<=5) //当倒计时时间小于5秒时,执行
{
jtdby(); //调用函数
}
}
}
/*****************************************************/
/* 函数名:jtdby() */
/* 功能:交通灯东西方向黄灯亮,红灯灭 */
/* 交通灯南北方向红灯亮,绿灯灭 */
/*****************************************************/
void jtdby()
{
qm(); //所有信号灯全灭
flgaa=3; //标志位
W_green=1; //西向绿灯灭
E_green=1; //东向绿灯灭
W_yellow=0; //西向黄灯亮
E_yellow=0; //东向黄灯亮
N_red=0; //北向红灯灭
S_red=0; //南向红灯灭
while(1)
{
if(k0==0) //是否"复位"按键按下
{
delayms(3);
if(k0==0)
{ while(!k0); //去除抖动,确定是否"复位"按键按下
djs=20; //倒计时时间重新赋值
djs1=20; //倒计时时间重新赋值
dxdjs=djs; //将东西方向的倒计时时间保存
nbdjs=djs1; //将南北方向的倒计时时间保存
jtda(); //调用jtda()函数
}
}
if(k2==0) //是否"紧急模式"按键按下
{
delayms(3);
if(k2==0)
{ while(!k2); //去除抖动,确定是否"紧急模式"按键按下
TR0=0; //启动定时器
jj(); //调用紧急模式
}
}
if(k1==0) //是否"夜间模式"按键按下
{
delayms(3);
if(k1==0)
{ while(!k1); //去除抖动,确定是否"夜间模式"按键按下
TR0=0; //启动定时器
yj(); //调用夜间模式
}
}
if(menu==0) //是否"设定倒计时时间"按键按下
{
delayms(3);
if(menu==0)
{ while(!menu); //去除抖动,确定是否"设定倒计时时间"按键按下
TR0=0; //启动定时器
set_djs(); //调用设定倒计时时间函数
}
}
djsxs22(); //数码管时间显示
if(djs1<0) //当倒计时时间小于0秒时,执行
{
djs=dxdjs; //将东西方向的倒计时时间保存
djs1=nbdjs; //将南北方向的倒计时时间保存
jtda(); //调用jtda()函数
}
}
}
/*****************************************************/
/* 函数名:jtda() */
/* 功能:交通灯南北方向绿灯亮,红灯灭 */
/* 交通灯东西方向红灯亮,绿灯灭 */
/*****************************************************/
硬件设计
使用元器件:
单片机:STC89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
数码管:MT03621AR;
发光二极管:红、黄、绿;
晶振:11.0592;排阻:1K*8;
电容:22pF、10uF/16V;
电阻:1K;按键:6*6*5;
接线端子:5.08*2P;
自锁开关:8*8;
导线:若干;
添加图片注释,不超过 140 字(可选)
流程图:
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用proteus7.8和proteus8.9两个版本设计,向下兼容,无需担心!具体如图!
添加图片注释,不超过 140 字(可选)
02原理图
本系统原理图采用Altium Designer19设计,具体如图!
添加图片注释,不超过 140 字(可选)
03程序
本设计使用keil5版本编程设计,资料有软件安装教程,无需担心!具体如图!
添加图片注释,不超过 140 字(可选)
04设计报告
一万三千字设计报告,具体如下!
添加图片注释,不超过 140 字(可选)
05设计资料
资料获取请关注同名公众号,全部资料包括仿真源文件 、程序(含注释)、PCB电路图、AD原理图、任务书、开题报告、设计报告、结构框图、流程图、元件清单、实物图、实物演示视频等。具体内容如下,全网最全! !
资料获取请观看前面演示视频!
点赞分享一起学习成长。
下面是开源51单片机设计资料
大家共同学习进步:
提取码:si8w
点赞分享,一起学习进步!一起成长。