十字路口交通灯通行

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

十字路口交通灯的通行指示控制——兰州理工大学
一、设计内容及技术要求:
(一)、任务描述
十字路口中A道,B道各有两组红黄绿三种灯。

A道绿灯亮若干秒,切换为黄灯闪烁若干秒,然后切换为红灯亮若干秒,继而A道由红灯切换为绿灯,但之间不需要黄灯过渡;B道的控制顺序与A道相同,但A道与B道的亮灯需要在颜色上符合实际中互锁的要求。

红黄绿灯亮的时间可以显示。

A道,B道中一道有车而另一道无车时,交通灯控制系统应能立即让有车道放行。

(二)、控制任务和要求
基本任务:
选用AT89S51及相应外围扩展元器件完成相应的功能
进阶任务:
1、有紧急车辆要求通过时,系统应能使A、B道均为红灯。

2、红灯的显示时间可以控制
3、行人闯红灯提示
本设计可以对东西南北时间进行分别设置,带向左转灯,带紧急控制,带行人闯红灯提示。

/*******************************************************
十字路口交通灯控制C语言程序
*******************************************************/
#define uchar unsigned char //定义无符号字符型
#define uint unsigned int //定义无符号整型
#include <reg51.h> //调用reg51.h头文件
#include <intrins.h>
/********************定义数码管端口***********************/ sbit DX_RED=P0^3; //DX_RED红灯
sbit DX_YELLOW=P0^2; //DX_YELLOW黄灯
sbit NB_RED=P0^7; //NB_RED红灯
sbit NB_YELLOW=P0^6; //NB_YELLOW黄灯
sbit LATCH1=P1^0;//定义锁存使能端口段锁存
sbit LATCH2=P1^1;// 位锁存
/***********************功能键**************************/ sbit HONGW AI=P1^7;
sbit STOP=P3^1;
sbit KEY_STOP=P3^2;
sbit KEY_ERR=P3^3;
sbit KEY_ADD=P3^4; //加时
sbit KEY_DEC=P3^5; //减时
sbit KEY_SET=P3^6; //切换
sbit KEY_START=P3^7; //开始
/***********************黄灯闪烁***********************/
bit Flag_NB_YELLOW; //N黄灯标志位
bit Flag_DX_YELLOW; //E黄灯标志位
bit int0_time;//中断强行标志
char T_DX; //东西方向倒计时单元
char T_NB; //南北方向倒计时单元
char DX0;
char NB0;
unsigned char set=0; //东西或南北设置选择
unsigned char set_dx=11;
unsigned char set_nb=11;
uchar STOP1=1;
unsigned char i;
uchar DX=50,NB=40,DXL=9,NBL=9; //程序初始化赋值,正常模式
uchar DX1=40,NB1=30,DXL1=9,NBL1=9; //用于存放修改值的变量
unsigned char code DuanMa[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x08,0x00};// 显示段码值0~9 unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsigned char Data[8]; //存储显示值的全局变量
char code dx516[3] _at_ 0x003b;
/**********************延时子程序************************/
void Delay(uchar a)
{
uchar i;
i=a;
while(i--)
{;}
}
/*****************显示子函数**************************/
void Display()
{
Data[2]=DuanMa[T_DX/10]; //第1位东西秒十位
Data[3]=DuanMa[T_DX%10]; //第2位东西秒个位
Data[6]=DuanMa[T_NB/10]; //第3位南北秒十位
Data[7]=DuanMa[T_NB%10]; //第4位南北秒个位
Data[1]=DuanMa[set_dx];
Data[5]=DuanMa[set_nb];
for(i=0;i<8;i++)
{
P2=0; //清空数据,防止有交替重影
LATCH1=1; //段锁存
LATCH1=0;
P2=WeiMa[i]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
P2=Data[i]; //取显示数据,段码
LATCH1=1; //段锁存
LATCH1=0;
Delay(2); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
}
}
/**********************外部0中断服务程序************************/
void key()
{
KEY_ADD=1; //按键输入端口电平置高
KEY_DEC=1;
KEY_START=1;
if(!KEY_ERR) //有人闯红灯
{
Data[4]=0x76;
Data[0]=0x76;
}
else{
Data[4]=0x00;
Data[0]=0x00;}
if(!STOP) //如果检测到低电平,说明按键按下
{
Delay(10); //延时去抖,一般10-20ms
if(!STOP) //再次确认按键是否按下,没有按下则退出
{
while(!STOP);//如果确认按下按键等待按键释放,没有释放则一直等待{STOP1=!STOP1;
KEY_STOP=STOP1;
if(STOP1==1)TR0=1;
}
}
}
if(KEY_ADD==0&&TR0==0) //如果检测到低电平,说明按键按下
{
Delay(10); //延时去抖,一般10-20ms
if(!KEY_ADD) //再次确认按键是否按下,没有按下则退出
{
while(!KEY_ADD);//如果确认按下按键等待按键释放,没有释放则一直等待{
if(DX<99&&set_dx==10) //加东西
{
DX++;
NB++;
T_DX=DX;
T_NB=DX1;
}
else if(DX1<99&&set_nb==10)//加南北
{NB1++;
DX1++;
T_DX=DX;
T_NB=DX1;
}
}
}
}
if(KEY_DEC==0&&TR0==0) //如果检测到低电平,说明按键按下{ T_DX=DX;
T_NB=DX1;
Display();
Delay(10); //延时去抖,一般10-20ms
if(!KEY_DEC) //再次确认按键是否按下,没有按下则退出
{ T_DX=DX;
T_NB=DX1;
Display();
while(!KEY_DEC);//如果确认按下按键等待按键释放,没有释放则一直等待{
Display();
if(DX>10&&set_dx==10) //减操作
{ NB--;
DX--;
T_DX=DX;
T_NB=DX1;
}
else if(NB1>0&&set_nb==10)
{NB1--;
DX1--;
T_DX=DX;
T_NB=DX1;
}
}
}
}
if(!KEY_SET) //如果检测到低电平,说明按键按下
{
Delay(10); //延时去抖,一般10-20ms
if(!KEY_SET) //再次确认按键是否按下,没有按下则退出
{ DX0=T_DX;
NB0=T_NB;
set=!set;
T_DX=DX;
T_NB=DX1;
while(!KEY_SET) //如果确认按下按键等待按键释放,没有释放则一直等待{ Display();
TR0=0;
if(set==0)
{set_dx=10;
set_nb=11;
}
else
{set_dx=11;
set_nb=10;
}
}
}
}
if(!KEY_START)
{Delay(10); //延时去抖,一般10-20ms
if(!KEY_START) //再次确认按键是否按下,没有按下则退出
{
while(!KEY_START)
{Display();
TR0=1;
T_DX=DX0;
T_NB=NB0;
set_dx=11;
set_nb=11;
}
}
}
}
/**********************T0中断服务程序*******************/ void timer0(void)interrupt 1 using 1
{
static uchar count;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==10)
{
if(Flag_NB_YELLOW==0) //测试南北黄灯标志位
{NB_YELLOW=~NB_YELLOW;}
if(Flag_DX_YELLOW==0) //测试东西黄灯标志位
{DX_YELLOW=~DX_YELLOW;}
}
if(count==20)
{
T_DX--;
T_NB--;
if(Flag_NB_YELLOW==0) //测试南北黄灯标志位
{NB_YELLOW=~NB_YELLOW;}
if(Flag_DX_YELLOW==0) //测试东西黄灯标志位
{DX_YELLOW=~DX_YELLOW;}
count=0;
}
}
void int0(void) interrupt 0 using 1 //全部禁止
{ TR0=0;
P0=0X77;
Data[0]=0x40;
Data[1]=0x40;
Data[2]=0x40;
Data[3]=0x40;
Data[4]=0x40;
Data[5]=0x40;
Data[6]=0x40;
Data[7]=0x40;
}
/*********************主程序开始**********************/
void main(void)
{
IT0=0; //INT0低电平触发
TMOD=0x01; //定时器工作于方式1
TH0=(65536-50000)/256; //定时器赋初值
TL0=(65536-50000)%256;
EA=1; //CPU开中断总允许
ET0=1; //开定时中断
EX0=1; //开外部INTO中断
TR0=1; //启动定时
HONGW AI=0;
while(1)
{
/*******S0状态**********/
Flag_DX_YELLOW=1; //DX关黄灯显示信号
Flag_NB_YELLOW=1;
T_DX=DX;
T_NB=NB;
while(T_NB>=5)
{
P0=0xD7; //NB通行,DX红灯
Display();
key();
}
/*******S1状态**********/
while(T_NB>=0)
{
Flag_NB_YELLOW=0; //NB开黄灯信号位
DX_RED=0; //NB黄灯亮,等待左拐信号,DX红灯
Display();
key();
}
/*******S2状态**********/
Flag_NB_YELLOW=1; //NB关黄灯显示信号
T_NB=NBL;
NB_RED=0;
while(T_NB>=5)
{
P0=0xe7;//NB左拐绿灯亮,DX红灯
Display();
key();
}
/*******S3状态**********/
while(T_NB>=0)
{
Flag_NB_YELLOW=0; //NB开黄灯信号位
DX_RED=0; //NB黄灯亮,等待停止信号,DX红灯
Display();
key();
}
/***********赋值**********/
/*******S4状态**********/
Flag_NB_YELLOW=1; //NB关黄灯显示信号
T_DX=NB1;
T_NB=DX1;
while(T_DX>=5)
{
P0=0x7d; //DX通行,NB红灯
Display();
key();
}
/*******S5状态**********/
while(T_DX>=0)
{
Flag_DX_YELLOW=0;//DX开黄灯信号位
NB_RED=0;//DX黄灯亮,等待左拐信号,NB红灯
Display();
key();
}
/*******S6状态**********/
Flag_DX_YELLOW=1; //DX关黄灯显示信号
T_DX=DXL1;
DX_RED=1;
while(T_DX>=5)
{
P0=0x7e;//DX左拐绿灯亮,NB红灯
Display();
key();
}
/*******S7状态**********/
while(T_DX>=0)
{
Flag_DX_YELLOW=0; //DX开黄灯信号位
NB_RED=0;//DX黄灯亮,等待停止信号,NB红灯
Display();
key();
}
}
}。

相关文档
最新文档