交通灯实验报告.docx
《交通灯实验报告.docx》由会员分享,可在线阅读,更多相关《交通灯实验报告.docx(34页珍藏版)》请在冰豆网上搜索。
交通灯实验报告
深圳大学实验报告
课程名称:
单片机与嵌入式系统
实验项目名称:
十字路口交通灯
学院:
电子科学与技术
专业:
电子科学与技术
指导教师:
叶文彬
报告人:
陈新波学号:
2013800105班级:
电子2班
实验报告提交时间:
2015.12.24
一、实验目的
通过Protues仿真软件和Keil软件,绘制交通灯的原理图,并通过Keil软件编写代码,编写十字路口交通灯的工作控制程序。
并下载可执行文件,在Protues中观察仿真结果,实现十字路口交通灯的设计。
二、实验原理
由于加入汽车左转信号灯,故汽车与行人看到的交通信号灯和倒计时均不一样。
南北路口汽车绿灯直行时间为25s,同时南北方向的行人看见绿灯的时间为20s,当20s过后,南北路口汽车看到的绿灯直行信号不变,行人则看到绿灯转为黄灯且黄灯为闪烁状态,倒计时时间为5s。
接着南北路口绿灯直行时间结束,行人过斑马线的时间也结束。
汽车将看到绿灯左转信号5s,而南北方向的行人则将看到红灯,倒计时为35s。
当绿灯左转信号仅剩3s时,倒计时器会闪烁。
在南北路口汽车看到绿灯直行和左转期间,共30s,东西路口行人和汽车则看到红灯,倒计时为30s。
接着东西路口的汽车看到绿灯直行时间为25s,同时东西方向的行人看到绿灯时间为20s。
东西路口的信号灯切换和倒计时的时间均与南北路口一致。
完成一个周期后,循环。
下面为利用Protues绘制的原理图:
(1)80C51最小系统的绘制,并且在4个IO口放上端子,按IO口分别命名,方便使用
(2)四个路口的红灯、绿灯和黄灯,分别只画出一个路口的指示灯,另一半省略。
由于汽车需要看到直行和左转信号,所以利用绿灯摆成箭头的形式来模拟,其中4组数码管,分别用来倒计时南北路口汽车、行人看到的时间和东西路口汽车和行人看到的时间。
其中交通灯利用P0口来控制,数码管则利用动态显示和锁存器,只使用P1口一个IO口就可以了
(3)矩阵键盘扫描后利用中断来控制程序:
其中矩阵键盘使用P2口
其中P3.2口为外部中断信号
的引脚输入,IT0设置为1,边沿触发方式,负跳变有效
(4)剩下的锁存器模块和自定义红绿黄灯时间的显示模块
锁存器模块,其中
接低电平时,芯片内部数据保持器与输出端口连接。
在此则直接接地,保持连接畅通。
LE=0时,P1口与芯片内部数据保持器断开;
LE=1时,P1口与芯片内部数据保持器连通。
上面三个数码管,从左到右分别显示黄灯显示时间,汽车左转信号时间,行人看到绿灯的时间。
由此就可以得到,
汽车看到绿灯直行信号的时间=行人看到绿灯的时间+黄灯的时间
汽车看到红灯的时间=汽车绿灯直行时间+汽车绿灯左转时间
行人看到红灯的时间=汽车看到红灯的时间+汽车左转的时间
(5)流程图
三、实验过程
(1)编写交通灯控制程序
自己编写头文件FUNCTION.H
traffic_light.c,包含需要用到的所有变量和main函数
function.c,包含delay子程序和init初始化程序
key.c,包含键盘扫描处理中断程序
display.c,包含显示交通灯和数码管程序
timer.c,包含利用计时器计时1s的程序
(2)分析头文件FUNCTION.H
#ifndef_FUNCTION.H_//定义如果其他c文件定义了该头文件,则包含以下内容
#defineFUNCTION.H
#include
#defineucharunsignedchar
#defineuintunsignedint
#definegreen20//以下为预处理宏定义
#definepeople_green20//行人看到绿灯时间为20s
#defineblue5//汽车看到绿灯左转时间为5s
#defineyellow5//行人看到黄灯时间为5s
#definecar_greenpeople_green+yellow//汽车看到绿灯直行和左转的时间,同时也是汽车红灯//的时间
#defineredgreen+blue+yellow//行人看到红灯的时间
sbitdu=P3^7;//定义数码管扫描的位选锁存器的LE端
sbitwe=P3^6;//定义交通显示数码管数据输送的锁存器的LE端
sbitdef=P3^3;//定义自己定义交通灯信号显示时间的数据输送的锁存器的LE端
sbitlight_off=P3^0;//定义控制所有交通灯灭的端口
voiddelay(ucharms);//延时子函数
voidinit();//初始化函数
voidtraffic_light();//交通灯函数
voidget_number();//取值送入数码管倒计时的函数
voidxianshi_function();//数码管倒计时到3s后数字闪烁的子函数
voidkey_scan();//键盘扫描子函数
voidkey_function();//键盘按下后发生的作用的子函数
#endif
(3)分析包含main函数的traffic_light.c文件
#include"FUNCTION.H"//包含头文件
ucharcodedu_table[]={
0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//选通显示的数码管
ucharcodewe_table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//输送给数码管显示数据的字模
ucharn,ston_time=red,etow_time=people_green,flag=0,etcarrun=car_green;
ucharsncarrun=red,status=0,key=0,temp;
//ston_time东西路口行人的倒计时,etow_time南北路口行人的倒计时
//sncarrun东西路口汽车的倒计时,etcarrun东西苦口汽车的倒计时
//status选择汽车路口的工作状态,key确认按下的键值执行对应的函数
//temp一个中间变量
ucharxianshi_flag=0,jishi=0,jishi1=0,jishi2=0,jishi3=0,jishi4=0;
//xianshi_flag中断显示函数中的标志位
//jishi,jishi1,jishi2,jishi3,jishi4均是中间变量,无特殊意义
ucharzidingyi=0,symbol=0;//zidingyi选择是否要自己更改交通信号的时间
//symbol显示要更改的是哪个交通灯信号的时间
ucharnum[8];//存放显示倒计时数据的容器
ucharnormal[3]={5,5,20};//正常情况下,交通灯的倒计时时间,分别为黄灯,汽车左转,行//人绿灯时间
ucharbusy[3]={5,10,40};//下同
ucharurgent[3]={5,10,60};//
uchardefine[3]={5,5,20};//
voidmain()
{
init();//初始化,即打开总中断,外部中断0,定时器0,定时器1
while
(1)
{
key_scan();//键盘扫描程序
}
}
/*key_scan()函数执行的功能如下
P2=0xfe;//分别将第四位轮流置低,检测到按键按下后
P2=0xfd;//进入中断程序,再执行key_function()
P2=0xfb;
P2=0xf7;
if(key>0)
{
key_function();
}
*/
(4)分析function.c文件
#include"FUNCTION.H"
voiddelay(ucharms)//延时子程序
{
uchari,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--)
;
}
voidinit()//初始化程序
{
EA=1;//开总开关
TMOD=0x11;//开定时器0和定时器1,设置工作模式
TH0=(65536-50000)/256;//定时器0倒计时50ms
TL0=(65536-50000)%256;
TH1=(65536-2000)/256;//定时器1倒计时2ms
TL1=(65536-2000)%256;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
we=0;//让锁存器内部芯片数据保持器与IO口断开
du=0;//让锁存器内部芯片数据保持器与IO口断开
EX0=1;//开外部中断0,并选择触发模式
IT0=1;
light_off=1;//让交通灯显示
}
(5)分析display.c文件
/*
sbityellow1=P0^0;
sbitred1=P0^1;
sbitgreen1=P0^2;
sbitblue1=P0^3;
sbityellow2=P0^4;
sbitred2=P0^5;
sbitgreen2=P0^6;
sbitblue2=P0^7;
标号为1,则为南北的信号灯,其中blue代表绿灯左转信号
标号为2,则为东西的信号灯,其中blue代表绿灯左转信号
yellow1=1;
red1=0;
green1=1;
yellow2=1;
red2=1;
green2=0;
blue1=1;
blue2=1;
*/
#include"FUNCTION.H"//包含头文件
externucharflag,zidingyi,xianshi_flag;//变量意义在traffic_light.c中解释过了
externucharston_time,jishi1,etow_time,jishi2;
externucharsncarrun,jishi3,etcarrun,jishi4,symbol,jishi;
externucharcodedu_table[8],we_table[16];
externucharsncarrun,define[3],ston_time,etow_time,etcarrun,num[8];
voidtraffic_light()//交通灯显示程序
{
if(flag==0)//flag=0为南北路口红灯,东西路口汽车行人直行
{
P0=0xbd;
}
if(flag==1)//flag=1南北路口红灯,东西路口汽车直行,行人遇黄灯
{
if(TR0==1)//在50ms计时器停止计数时,黄灯停止闪烁
{
P0=0xed;
delay(5);
P0=0xfd;
delay(5);
}
P0=0xed;
delay(5);
}
if(flag==2)//flag=2南北路口红灯,东西路口汽车左转,行人红灯
{
P0=0x7d;
}
if(flag==3)//flag=3为东西路口红灯,南北路口汽车行人直行
{
P0=0xdb;
}
if(flag==4)//flag=1东西路口红灯,南北路口汽车直行,行人遇黄灯
{
if(TR0==1)//在50ms计时器停止计数时,黄灯停止闪烁
{
P0=0xde;
delay(5);
P0=0xdf;
delay(5);
}
P0=0xde;
delay(5);
}
if(flag==5)//flag=5东西路口红灯,南北路口汽车左转,行人红灯
{
P0=0xd7;
}
}
voidget_number()
{
if(zidingyi==0)//不自定义的情况下,将交通信号倒计时存入数组容器中
{
num[0]=ston_time/10;
num[1]=ston_time%10;
num[2]=etow_time/10;
num[3]=etow_time%10;
num[4]=etcarrun/10;
num[5]=etcarrun%10;
num[6]=sncarrun/10;
num[7]=sncarrun%10;
}
else//在自定义信号时间时,将数据存入数组容器中
{
num[0]=define[2]/10;
num[1]=define[2]%10;
num[2]=define[1]/10;
num[3]=define[1]%10;
num[4]=define[0]/10;
num[5]=define[0]%10;
}
}
voidxianshi_function()
{
if(zidingyi==0)//非自定义的情况下
{//南北路口的行人在遇黄灯小于等于3s时,倒计时闪烁
if((ston_time<4)&&(jishi1<100)&&(flag==4))
{
if(xianshi_flag==0)
{
xianshi_flag=2;
}
jishi1++;
if(jishi1==100)
{
jishi1=0;
xianshi_flag=0;
}
}
if((etow_time<4)&&(jishi2<100)&&(flag==1))
{//东西路口的行人在遇黄灯小于等于3s时,倒计时闪烁
if(xianshi_flag==2)
{
xianshi_flag=4;
}
jishi2++;
if(jishi2==100)
{
jishi2=0;
xianshi_flag=2;
}
}
if((etcarrun<4)&&(jishi3<100)&&(flag==2))
{//东西路口的汽车在遇左转信号小于等于3s时,倒计时闪烁
if(xianshi_flag==4)
{
xianshi_flag=6;
}
jishi3++;
if(jishi3==100)
{
jishi3=0;
xianshi_flag=4;
}
}
if((sncarrun<4)&&(jishi4<100)&&(flag==5))
{//南北路口的汽车在遇左转信号小于等于3s时,倒计时闪烁
if(xianshi_flag==6)
{
xianshi_flag=0;
}
jishi4++;
if(jishi4==100)
{
jishi4=0;
xianshi_flag=6;
}
}
}
if(zidingyi==1)//自定义信号时间的情况下
{
if(symbol==1)//选择调节行人看到绿灯的时间,且显示的时间闪烁
{
if(jishi<100)
{
if(xianshi_flag==0)
{
xianshi_flag=2;
}
jishi++;
if(jishi==100)
{
jishi=0;
xianshi_flag=0;
}
}
}
if(symbol==2)//选择调节行人看到黄灯的时间,且显示的时间闪烁
{
if(jishi<100)
{
if(xianshi_flag==2)
{
xianshi_flag=4;
}
jishi++;
if(jishi==100)
{
jishi=0;
xianshi_flag=2;
}
}
}
if(symbol==3)//选择调节汽车看到左转的时间,且显示的时间闪烁
{
if(jishi<100)
{
if(xianshi_flag==4)
{
xianshi_flag=0;
}
jishi++;
if(jishi==100)
{
jishi=0;
xianshi_flag=4;
}
}
}
}
}
voidTIME1()interrupt3
{
TH1=(65536-2000)/256;
TL1=(65536-2000)%256;
get_number();//等到数码管上要显示的数据
if(zidingyi==0)//非自定义的情况下
{
xianshi_function();
def=1;//关闭调节信号时间的数码管
P1=0xff;
def=0;
du=1;//选通显示的数码管
P1=du_table[xianshi_flag];
du=0;
P1=0x00;//消影
we=1;//选择要显示在数码管上的数据
P1=we_table[num[xianshi_flag]];
we=0;
P1=0xff;//消影
delay
(1);//延迟一小段时间
traffic_light();//显示交通灯的状况
xianshi_flag++;//显示标志位加1,到8变为0,防止逸出
if(xianshi_flag==8)
{
xianshi_flag=0;
}
}
else//自定义的情况下,分析同上面
{
xianshi_function();
du=1;
P1=0xff;
du=0;
def=1;
P1=du_table[xianshi_flag];
def=0;
P1=0x00;
we=1;
P1=we_table[num[xianshi_flag]];
we=0;
P1=0xff;
delay
(1);
xianshi_flag++;
if(xianshi_flag==6)
{
xianshi_flag=0;
}
}
}
(6)分析键盘扫描key.c文件
#include"FUNCTION.H"
externucharkey,status,ston_time,etow_time,etcarrun,sncarrun;
externucharzidingyi,symbol,temp;
externucharnormal[3],busy[3],urgent[3],define[3];
voidkey_scan()
{
P2=0xfe;//分别将第四位轮流置低,检测到按键按下后
P2=0xfd;//进入中断程序,再执行key_function()
P2=0xfb;
P2=0xf7;
if(key>0)
{
key_function();
}
}
voidkey_function()
{
if(key==1)//第一个键按下,停止倒计时
{
TR0=~TR0;
key=0;
}
if(key==2)//第二个键按下,全部数码管和信号灯灭
{
TR1=~TR1;
du=1;
P1=0xff;
du=0;
we=1;
P1=0x00;
we=0;
light_off=~light_off;
P0=0xff;
key=0;
}
if(key==5)//第5个键按下,切换到正常模式
{
status=1;
define[0]=normal[0];
define[1]=normal[1];
define[2]=normal[2];
ston_time=define[0]+define[1]+define[2];
etow_time=define[2];
etcarrun=define[0]+define[2];
sncarrun=define[0]+define[1]+define[2];
key=0;
}
if(key==6)//第6个键按下,切换到繁忙模式
{
status=1;
define[0]=busy[0];
define[1]=busy[1];
define[2]=busy[2];
ston_time=define[0]+define[1]+define[2];
etow_time=define[2];
etcarrun=define[0]+define[2];
sncarrun=define[0]+define[1]+define[2];
key=0;
}
if(key==7)//第7个灯按下,切换到特殊模式
{
status=1;
define[0]=urgent[0];
define[1]=urgent[1];
define[2]=urgent[2];
ston_time=define[0]+define[1]+define[2];
etow_time=define[2];
etcarrun=define[0]+define[2];
sncarrun=define[0]+define[1]+define[2];
key=0;
}
if(TR0==0)//必须停止倒计时计数后,按下第8个按键才有效
{
if(key==8)//按下第8个按键,进行自定义信号灯的计时时间
{
zidingyi=1;
if(zidingyi==1)
{
du=1;
P1=0xff;
du=0;
we=1;
P1=0x00;
we=0;
}
key=0;
}
if(key==9)//第9个按键按下,切换回正常计数模式
{
zidingyi=0;
ston_time=define[0]+define[1]+define[2];
etow_time=define[2];
etcarrun=define[0]+define[2];