单片机原理及系统课程设计
专 业:电气工程及其自动化
班 级: 电气1102
姓 名: vfffff
学 号: 2011反反复复
指导教师: 汤旻安
兰州交通大学自动化与电气工程学院
20##年 1月17 日
基于AT89C51单片机的十字路口交通灯设计
1 设计目的和方案
1.1设计目的
近年来随着科技的飞速发展,一个以微电子技术、计算机技术和通信技术为先导的信息革命正在蓬勃发展。计算机技术作为三者之一,怎样与实际应用更有效的结合并发挥其作用。单片机作为计算机技术的一个分支,正在不断的应用到实际生活中,同时带动传统控制检测的更新。在实时检测和自动控制的应用系统中,单片机往往是作为一个核心部件使用,针对具体应用对象的特点,配以其它器件来加以完善。现代社会有越来越多的人开始有了自己的私家车,同时,便有了交通拥挤的问题,如何在车流量巨大的十字路口保证车辆畅行,交通灯便起到了巨大的作用。实际上,1858年,英国伦敦就有了最早的然煤气交通灯,至今,交通灯已经普及到世界各地,成为社会生活中不可或缺的装置。
信号灯的出现,使交通得以有效管制,对于疏导交通流量、提高道路通行能力,减少交通事故有明显效果。
1.2设计方案
设计方案如表1所示。
1.4设计任务表1设计方案
东西、南北两干道交于一个十字路口,各干道有一组红、黄、绿三个指示灯,指挥车辆和行人安全通行。红灯亮禁止通行,绿灯亮允许通行。红灯的设计时间为30秒,绿灯及左转绿灯各为25秒。黄灯为闪烁5秒。
1.3时序图
本程序的时序图是基于visio画出的,基本图如图1所示。
图1时序图
2功能
该电子产品实现的功能:本系统除基本交通灯功能以外,还有倒计时等功能,较好的模拟了十字路口出现的状况。
具体功能如下:
(1)当东西方向为红灯,此道车辆禁止通行,东西道行人可通过;南北道为绿灯,
此道车辆通过,行人禁止通行。时间为30秒。
(2)黄灯闪烁5秒,警示车辆和行人红、绿灯的状态即将切换。
(3)当东西方向为绿灯,此道车辆通行;南北方向为红灯,南北道车辆禁止通过,
行人通行。时间为30秒。 东西方向车流大 通行时间长。
(4)这样如上表的时间和红、绿、黄出现的顺序依次出现这样行人和车辆就能安全畅通的通行。
3硬件设施及简介
8051单片机一片,共阴极的七段数码管,两个双向晶闸管若干,电源若干,晶振电路,复位电路一个,LED红黄绿灯各三个。导线若干。
复位电路:给单片机进行复位工作。
数码显示管两个:显示倒计时时间。
4 程序方框图
主程序流程图如图2所示。
图2 程序方框图
5 电路原理及说明
5.1总电路原理图
绘制出所做作品的原理图如图3所示。
图3电路原理图
5.2 电路原理说明
电路工作原理:如附图所示,刚开始,各灯均闪五秒,之后东西绿灯25s黄灯5s,南北方向红灯亮30s,倒计时结束,转向,南北方向绿灯25s,黄灯5s,东西方向红灯30s,依次循环。两个晶体管用来显示倒计时时间,12个不同颜色的LED灯显示各方向的红绿灯情况。使用51单片机作为芯片,一个复位电路。
LED 灯的显示原理:通过同名管脚上所加电平的高低来控制发光二极管是否点亮。七段数码管连接显示不同的数字如 SP,g,f,e,d,c,b,a 。
6系统仿真及实际调试
程序仿真是基于proteus软件的,仿真结果如图4所示
图4仿真结果
7总结
在进行过程中遇到的问题及解决方法:
通过这次课程设计,使我得到了一次用专业知识、专业技能分析和解决问题全面系统的锻炼。使我在单片机的基本原理、单片机应用系统开发过程,以及在常用编程设计思路技巧的掌握方面都能向前迈了一大步,为日后成为合格的应用型人才打下良好的基础。
在进行过程中,遇到很多困难与问题,例如程序不会写,仿真不出结果,结果不正确等问题,但是困难总是有办法解决的,通过查询网络,请教同学等方式,改编出了源程序,请教同学做出来了仿真结果。为以后的课设继续进行打好了基础。
作为一名电气专业的大三学生,我觉得做单片机课程设计是十分有意义的,而且是十分必要的。在已度过的大学时间里,我们大多数接触的是专业课。我们在课堂上掌握的仅仅是专业课的理论知识,如何去锻炼我们的实践能力?如何把我们所学的专业基础课理论知识运用到实践中去呢?我想做类似的课程设计就为我们提供了良好的实践平台。
我认为这个收获应该说是相当大的。觉得课程设计反映的是一个从理论到实际应用的过程,但是更远一点可以联系到以后毕业之后从学校转到踏上社会的一个过程。
参考文献
[1] 余锡存 单片机原理及接口技术[M] 西安:西安电子科技大学出版社,2000.7
附录
程序如下
#include<reg51.h>
#define uchar unsigned char//宏定义uchar
#define uint unsigned int//宏定义uint
sbit RED_DONGXI = P1^0;//南北方向红灯亮
sbit YELLOW_DONGXI = P1^1;//南北方向黄灯亮
sbit RED_NANBEI = P1^3;//东西方向红灯亮
sbit GREEN_DONGXI = P1^2;//南北方向绿灯亮
sbit YELLOW_NANBEI = P1^4;//东西方向黄灯亮
sbit GREEN_NANBEI = P1^5;//东西方向绿灯亮
sbit DXweixuan1 = P1^6;//南北方向数码管位选1
sbit DXweixuan2 = P1^7;//南北方向数码管位选2
sbit NBweixuan1 = P3^0;//东西方向数码管位选1
sbit NBweixuan2 = P3^1;//东西方向数码管位选2
sbit L1=P3^5;
sbit L2=P3^6;
sbit L3=P3^7; //数码管显示位月、日、时、分选控制端
uint aa, bai,shi,ge,bb;
uint shi1,ge1,shi2,ge2,minute=00,hour=07,day=20,month=11;//月日时分初始值设定
uint month1,month2,day1,day2,hour1,hour2,minute1,minute2;//定义变量
/*数码管显示0-9*/
uint code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uint code table1[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
/*子函数声明*/
void delay(uint z);
void delay0(uint z);
void init(uint a);
void display(uint shi1,uint ge1,uint shi2,uint ge2);
void xtimer0();
void init1();
void init2();
void init3();
void init4();
void init5();
void init6();
void display1();
/*********************************************************
主函数
*********************************************************/
void main()
{
P0=0xFF;
P1=0xFF;
P2=0x00;
P3=0xFF;
EA=1; //打开外部中断
EX0=1; //允许外部中断0中断
IT0=0;
EX1=1; //允许外部中断1中断
IT1=0; //INT0为沿触发方式
init1(); //第1个位状态
while(1)
{
init2(); //第2个状态
init3(); //第3个状态
init4(); //第4个状态
init5(); //第5个状态
}
}
void init1()//预备状态东、西、南、北方向均亮红灯3S
{
uint temp;
temp=3; //变量赋初值
TMOD=0x01; //定时器0工作于方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //定时器赋初值
EA=1; //开外部中断
ET0=1; //开定时中断
TR0=1; //开定时器0
while(1)
{
RED_DONGXI=0;
RED_NANBEI=0;
GREEN_DONGXI=1;
GREEN_NANBEI=1;
YELLOW_DONGXI=1;
YELLOW_NANBEI=1;
if(aa==20) //定时20*50MS=1S
{
aa=0; //定时完成一次后清0
temp--; //变量自减
}
shi1=shi2=temp/10; //显示十位
ge1=ge2=temp%10; //显示个位
if(temp==0)
{
temp=5; //变量赋值为5
break;
}
display(ge1,shi1,ge2,shi2); //显示红绿灯显示剩余时间
}
}
void init2() //第二个状态:东西亮红灯30S~5S、南北亮绿灯25~0S;
{
uint temp;
temp=26; //变量赋初值
TMOD=0x01; //定时器0工作于方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //定时器赋初值
EA=1; //开外部中断
ET0=1; //开定时中断
TR0=1; //开定时器0
while(1)
{
RED_DONGXI=1;
RED_NANBEI=0;
GREEN_DONGXI=0;
GREEN_NANBEI=1;
YELLOW_DONGXI=1;
YELLOW_NANBEI=1;
if(aa==20) //定时20*50MS=1S
{
aa=0; //定时完成一次后清0
temp--; //变量自增
shi1=(temp+5)/10; //显示十位
ge1=(temp+5)%10; //显示个位
shi2=temp/10;
ge2=temp%10;
if(temp==0) //定时25S
{
temp=26; //变量清0
break;
}
}
display(ge1,shi1,ge2,shi2);
}
}
void init3() //第三个状态:南北绿灯变为黄灯闪5s、东西方向亮红灯5S
{
uint temp;
temp=6; //变量赋初值
TMOD=0x01; //定时器0工作于方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //定时器赋初值
EA=1; //开外部中断
ET0=1; //开定时中断
TR0=1; //开定时器0
while(1)
{
RED_NANBEI=0;
GREEN_DONGXI=1;
if(aa==20) //定时20*50MS=1S
{
aa=0; //定时完成一次后清0
temp--; //变量自增
YELLOW_DONGXI=~YELLOW_DONGXI;
shi1=temp/10;
shi2=shi1; //显示十位
ge1=temp%10;
ge2=ge1; //显示个位
}
if(temp==0) //定时5S
{
temp=6; //变量赋值
break;
}
display(ge1,shi1,ge2,shi2);
}
}
void init4()//第四个状态:东西亮绿灯25~0S,南北方向亮红灯30~5S;
{
uint temp;
temp=26; //变量赋初值
TMOD=0x01; //定时器0工作于方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //定时器赋初值
EA=1; //开外部中断
ET0=1; //开定时中断
TR0=1; //开定时器0
while(1)
{
RED_DONGXI=0;
RED_NANBEI=1;
YELLOW_DONGXI=1;
GREEN_NANBEI=0;
if(aa==20) //定时20*50MS=1S
{
aa=0; //定时完成一次后清0
temp--; //变量自增
shi1=temp/10;
shi2=(temp+5)/10; //显示十位
ge1=temp%10;
ge2=(temp+5)%10; //显示个位
if(temp==0) //定时25S
{
temp=26; //变量清0
break;
}
}
display(ge1,shi1,ge2,shi2);
}
}
void init5()//第五个状态:东西闪黄灯5~0s、南北红灯5S
{
uint temp;
temp=6; //变量赋初值
TMOD=0x01; //定时器0工作于方式1
TH0=(65535-50000)/256;
TL0=(65535-50000)%256; //定时器赋初值
EA=1; //开外部中断
ET0=1; //开定时中断
TR0=1; //开定时器0
while(1)
{
RED_NANBEI=1;
RED_DONGXI=0;
GREEN_DONGXI=1;
GREEN_NANBEI=1;
if(aa==20) //定时20*50MS=1S
{
aa=0; //定时完成一次后清0
temp--; //变量自增
YELLOW_NANBEI=~YELLOW_NANBEI;
shi1=temp/10;
shi2=shi2; //显示十位
ge1=temp%10;
ge2=ge1; //显示个位
if(temp==0) //定时100S
{
temp=6; //变量清0
break;
}
}
display(ge1,shi1,ge2,shi2);
}
}
void display(uint shi1,uint ge1,uint shi2,uint ge2)
{
DXweixuan1=0;
DXweixuan2=1;
NBweixuan1=1;
NBweixuan2=1;
P0=table[ge1]; //显示十位
delay0(5);
DXweixuan1=1;
DXweixuan2=0;
NBweixuan1=1;
NBweixuan2=1;
P0=table[shi1]; //显示个位
delay0(5);
DXweixuan1=1;
DXweixuan2=1;
NBweixuan1=0;
NBweixuan2=1;
P0=table[ge2]; //显十位
delay0(5);
DXweixuan1=1;
DXweixuan2=1;
NBweixuan1=1;
NBweixuan2=0;
P0=table[shi2]; //显示个位
delay0(5);
}
void xint0() interrupt 0 //外部中断0
{
RED_NANBEI=0;
RED_DONGXI=0;
GREEN_NANBEI=1;
GREEN_DONGXI=1;
YELLOW_NANBEI=1;
YELLOW_DONGXI=1;
P0=0x00;
NBweixuan1=0;
NBweixuan2=0;
DXweixuan1=0;
DXweixuan2=0;
display1();
return ;
}
void xint1() interrupt 2 //外部中断1
{
RED_NANBEI=1;
RED_DONGXI=1;
GREEN_NANBEI=0;
GREEN_DONGXI=0;
YELLOW_NANBEI=1;
YELLOW_DONGXI=1;
P0=0x00;
NBweixuan1=0;
NBweixuan2=0;
DXweixuan1=0;
DXweixuan2=0;
return ;
}
/*定时中断子函数*/
void xtimer0() interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
aa++;
}
/*延时子函数*/
void delay0(uint z)
{uint i,j;
for(i=0;i<z;i++)
for(j=0;j<110;j++);
}
void delay(unsigned int j)
{
unsigned char k;
unsigned int i;
for(;j>0;j--)
{
for(i=1250;i>0;i--)
{
for(k=180;k>0;k--);
}
}
}