单片机设计交通信号灯实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
单片机C语言程序设计专题实习专周报告
班级:
学号:
姓名:
指导老师:
专周成绩:
一、硬件设计
1.设计要求:○1A、B两通道都有车,两道正向放行35s,然
后左向行驶放行15s。
[当A道放行时(绿),B道禁止(红),反
之亦然,放行时间中包含有闪烁时间]○2绿灯→红灯转换必须经
5s的警视状态○3设置紧急情况处理器,当紧急情况发生时,两道
都亮红灯,让紧急车辆通过,完备再回到当前的状态○4具有数码
管显示倒计时功能。
2.图样:
北
东
南
3.硬件选择:选用8052单片机一片,红、黄、绿LED交通
显示灯各4个,导线若干,7SEG数码显示管。
单片机模块:主控芯片采用AT89C52单片机, AT89C52是AT89C5X
系列单片机的典型产品,我们以这一代表性的机型进行系统的讲
解。
AT89C52单片机包含中央处理器、程序存储器(ROM)、数据存
储器(RAM)、定时/计数器、并行接口、串行接口和中断系统等几
大单元及数据总线、地址总线和控制总线等三大总线。
AT89C52共有4组8位I/O口(P0、P1、P2或P3),用于对外部数据的传输,其内置最高频率达12MHz的时钟电路,用于产生整个单片机运行的脉冲时序。
管脚图如下图所示。
倒计时显示模块:由于黄灯5秒闪烁时间不单另计时,四个路口的倒计时是同步的。
故倒计时采用两个七段数码显示管。
紧急模式模块:交通路口出现紧急状况在所难免,如特大事件发生,救护车等急行车通过等,我们都必须尽量允许其畅通无阻,毕竟在这种情况下是分秒必争的,时时刻刻关系着公共财产安全,个人生死攸关等。
由此在交通控制中增设禁停按键,就可达到此目的。
二、软件设计
1.设计思路:本系统以单片机为核心,由状态灯,LED显示,按键等组成。
其中P0用于送显两片LED数码管,P1、P2、P3用于控制红绿黄发光二极管,采用自带晶振时钟电路,REST引脚接
上复位电路,P3.1接紧急模式设置键,P3.2、P3.3、P3.4用于调解预置交通灯时间。
系统上电或手动复位之后,系统等待模式选择设置键按下,模式分两种:红绿灯时间自动和紧急模式。
系统默认运行时间自动,若此时3.1键按下,则设置为紧急模式,再次按3.1,回到自动时间红绿灯模式。
接下来,系统必须先显示状态灯及LED数码管,将状态码值送显P1、P2、P3口,将要显示的时间值的个位和十位分别送显P0口,在此同时以50ms为周期,用软件方法计时1秒,到达1s就要将时间值减1,刷新LED数码管。
时间到达一个状态所要全部时间,则要进行下一状态判断及衔接,并装入次状态的相应状态码值以及时间值。
三、程序流程图
四、程序及说明
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar night_flag=0; //紧急标志位
uchar time_cl=0; //定义时间控制标志位取0
uchar flag=0; //方向通行标志位
uchar B_N_D_flag=1; //定义北南通灯行标志位
uchar X_D_D_flag=1; //定义西东通灯行标志位
uchar i,j; //定义变量i
uchar t=3; //数码管动态扫描延时时间基数
uchar num=0; //时间基数初始化为0
//uchar num_night=0; //紧急模式时间基数为0
uchar time=35; //time初始化定为35秒
int bei,nan,xi,dong; //定义北南西东
uchar code Data[]={0x18,0x7B,0x89,0x49,0x6A,0x4C,0x0C,0x79,0x08,0x48,0 xEF};
//定义数组数码管 0 1 2 3 4 5 6 7 8 9 -
/***************定义红黄绿灯**************/
sbit M=P0^3;
sbit B_R=P1^2; //北面红灯
sbit B_Y=P1^1; //北面黄灯
sbit B_G=P1^0; //北面绿灯
sbit N_R=P2^0; //南面红灯
sbit N_Y=P2^1; //南面黄灯
sbit N_G=P2^2; //南面绿灯
sbit X_R=P2^5;//西面红灯
sbit X_Y=P2^6; //西面黄灯
sbit X_G=P2^7; //西面绿灯
sbit D_R=P3^7; //东面红灯
sbit D_Y=P3^6; //东面黄灯
sbit D_G=P3^5; //东面绿灯
sbit s1=P3^4;//时间减
sbit s2=P3^3;//时间加
sbit s3=P3^1;//紧急模式控制切换口
sbit s4=P3^2;//进入时间可以设置状态的切换口/***************定义数码管*****************/ #define SMG_XS P0 //数码管数据显示#define SMG_KZ P2 //数码管控制显示sbit smg1=P2^4;//定义数码管1控制口
sbit smg2=P2^3;//定义数码管2控制口
void delay(uint time);// 定义延时程序
void disp_init();//显示初始化
void disp(bei,nan,xi,dong);
void Time0_init() //定时器0初始化函数
{
TMOD=0x01; //定时器0为方式1
TL0=(65536-50000)%256;
TH0=(65536-50000)/256; //12M晶振定时时间50ms ET0=1; //开定时器0中断
EA=1; //开总中断
TR0=1; //启动定时器0
}
void night_mode() //紧急模式
{
B_R=1;
B_R=~B_R; //北红灯取反
B_G=1;
N_R=1;
N_R=~N_R; //南红灯取反
N_G=1;
X_R=1;
X_R=~X_R; //西红灯取反
D_R=1;
D_R=~D_R; //东红灯取反
D_G=1;
}
void B_N_G() //北南通(绿灯) 西东(红灯) {
B_G=0; //北绿灯亮
N_G=0; //南绿灯亮
B_R=1;
B_Y=1;
N_R=1;
N_Y=1;
X_R=0; //西红灯亮
D_R=0; //东红灯亮
X_Y=1;
X_G=1;
D_Y=1;
D_G=1;
}
void X_D_G() //西东通(绿灯) 北南(红灯) {
N_G=1;
B_R=0; //北红灯亮
B_Y=1;
N_R=0; //南红灯亮
N_Y=1;
X_R=1;
D_R=1;
X_Y=1;
X_G=0; //西绿灯亮
D_Y=1;
D_G=0; //东绿灯亮
}
void B_N_tong() //北南通行
{
if(B_N_D_flag==1) //当北南通灯行标志位为1 {
B_N_G(); //北南通(绿灯) 西东(红灯)
B_N_D_flag=0; //北南通灯行标志位置0 }
while(num==20) //当1s时间到
{
num=0; //num清0
bei--; //北时间减1
nan--; //南时间减1
xi--; //西时间减1
dong--; //东时间减1
M=1;
if(bei<=6&&bei>=0||nan<=6&&nan>=0) //当北和南时间在0到6秒之间
{
if(bei<=6&&bei>5||nan<=6&&nan>5) //进一步判断北和南时间是否在5到6秒之间
{
B_G=~B_G; //北绿灯取反
N_G=~N_G; //南绿灯取反
}
if(bei<=5&&nan<=5) //进一步判断北和南时间是否在5秒以内
{
B_G=1; //北绿灯不亮
N_G=1; //南绿灯不亮
B_Y=0; //北黄灯亮
N_Y=0; //南黄灯亮
}
}
else //否则(即北和南时间不在0到6秒之间)
{
B_G=0; //北绿灯亮
N_G=0; //南绿灯亮
B_Y=1; //北黄灯不亮
N_Y=1; //南黄灯不亮}
}
}
void X_D_tong() //西东通行
{
if(X_D_D_flag==1) //当西东通灯行标志位为1
{
X_D_G(); //西东通(绿灯) 北南(红灯)
X_D_D_flag=0; //西东通灯行标志位置0
}
while(num==20) //当1s时间到
{
M=0;
num=0; //num清0
bei--; //北时间减1
nan--; //南时间减1
xi--; //西时间减1
dong--; //东时间减1
M=1;
if(xi<=6&&xi>=0||dong<=6&&xi>=0) //当西和东时间在0到6秒之间
{
if(xi<=6&&xi>5||dong<=6&&dong>5) //进一步判断西和东时间是否在5到6秒之间
{
X_G=~X_G; //西绿灯取反
D_G=~D_G; //东绿灯取反
}
if(xi<=5&&dong<=5) //进一步判断西和东时间是否在5秒以内
{
X_G=1; //西绿灯不亮
D_G=1; //东绿灯不亮
X_Y=0; //西黄灯亮
D_Y=0; //东黄灯亮
}
}
else //否则(即西和东时间不在0到6秒之间)
{
X_G=0; //西绿灯亮
D_G=0; //东绿灯亮
X_Y=1; //西黄灯不亮
D_Y=1;//东黄灯不亮
}
}
}
void Time0() interrupt 1 //定时器0中断服务函数
{
TH0=(65536-50000)/256; //重新载装初值,设置50ms中断一次
TL0=(65536-50000)%256;
num++; //时间基数加1
}
void main() //主函数入口
{
bei=nan=xi=dong=time; //把time值赋给北南西东
disp_init(); //显示初始化
Time0_init(); //定时器0初始化函数
while(1) //无限循环
if(s3==0) //当P3.7按下(开/关紧急模式)
{
delay(5); //延时去抖
s3=1; //关闭数码管显示
if(s3==0)
{
night_flag=~night_flag; //紧急标志位取反(开/关紧急模式),1表示开,0表示关
if(night_flag==1) //如果紧急模式开
{
TR0=0; //关闭定时器0
num=0; //时间基数清0
TL0=(65536-50000)%256;
TH0=(65536-50000)/256; //12M晶振定时时间50ms
TR0=1; //开启定时器0
SMG_KZ=0xff; //关闭数码管显示
}
else //否则night_flag=0表示紧急模式关(红绿灯正常运行)
void disp_init() //显示初始化
{
for(i=0;i<3;i++)
{
SMG_XS=Data[10]; //数码管显示"--"
smg1=0;
smg2=0;//允许数码管显示
B_R=0; //北面红灯
B_Y=0; //北面黄灯
B_G=0; //北面绿灯
N_R=0; //南面红灯
N_Y=0; //南面黄灯
N_G=0; //南面绿灯
X_R=0;//西面红灯
X_Y=0; //西面黄灯 X_G=0; //西面绿灯 D_R=0; //东面红灯 D_Y=0; //东面黄灯 D_G=0; //东面绿灯delay(300); //延时
B_R=1; //北面红灯 B_Y=1; //北面黄灯 B_G=1; //北面绿灯 N_R=1; //南面红灯 N_Y=1; //南面黄灯 N_G=1; //南面绿灯 X_R=1;//西面红灯
X_Y=1; //西面黄灯 X_G=1; //西面绿灯 D_R=1; //东面红灯 D_Y=1; //东面黄灯 D_G=1; //东面绿灯delay(300); //延时}
}
void delay(uint time)
{
uint x,y;
for(x=time;x>0;x--)
for(y=110;y>0;y--);
}
五、调试
1.Proteus软件仿真:在此次设计中,用Proteus对硬件部分进行模式。
在Proteus中输入原理图后,在单片机中载入汇编程序生成的hex文件,运行仿真,结果如下:
2.调试过程:调试时老师询问了时钟电路,以及最小系统等问题,并随机选择了程序中的句子叫我及其他组员做答辩。
最后验收附带要求我们添加时钟跟随LED,于是我们在159行时钟满一秒添加了E=1,在随后的下一秒关闭额外的LED灯即E=0。
在Proteus实际仿真中我们的E放置的是显色明显的黄色LED。
六、心得体会
通过这次交通灯的课程设计,使我得到了一次用专业知识、专业技能分析和解决现实问题的能力。
使我在单片机的基本原理、单片机应用学习过程中,以及在常用编程设计思路技巧的掌握方面都能向前迈了一大步,为日后成为一名合格的应用型人才打下良好的基础。
综合课程设计让我把以前学习到的知识得到巩固和进一步的提高认识,对已有知识有了更深层次的理解和认识。
在此,由于自身能力有限,在课程设计中碰到了很多的问题,我通过查阅相关书籍、资料以及和周围同学交流得到解决。
通过合作,我们的合作意识得到加强。
合作能力得到提高。
上大学后,很多同学都没有过深入的交流,在设计的过程中,我们用了分工与合作的方式,每个人互责一定的部分,同时在一定的阶段共同讨论,以解决分工中个人不能解决的问题,在交流中大家积极发言,和提出意见,同时我们还向别的同学请教。
在此过程中,每个人都想自己的方案得到实现,积极向同学说明自己的想法。
能过比较选出最好的方案。
在这过程也提高了我们的表过能力。