|
現(xiàn)代交通燈的設(shè)計(jì)
目錄
第一章 任務(wù)要求
1.1摘要
1.2設(shè)計(jì)要求
第二章 硬件設(shè)計(jì)
2.1主控制器選擇
2.2時(shí)鐘及復(fù)位電路
2.3數(shù)碼管顯示模塊
2.4指示燈模塊
2.5按鍵模塊
2.4按鍵模塊
第三章 軟件設(shè)計(jì)
3.1軟件設(shè)計(jì)需求及設(shè)計(jì)思路
3.2主函數(shù)設(shè)計(jì)
第四章 調(diào)試過程
4.1 仿真電路圖
4.2 仿真結(jié)果
4.2.1主干道交通燈倒計(jì)時(shí)
4.2.2倒計(jì)時(shí)結(jié)束時(shí)黃燈閃爍
4.2.3增加紅綠燈時(shí)長
4.2.4緊急情況車輛禁行
第五章 總結(jié)
第六章 參考文獻(xiàn)
附錄1總體電路圖
附錄2程序
第一章 任務(wù)要求
1.1摘要
近年來隨著科技的飛速發(fā)展,單片機(jī)的應(yīng)用正在不斷深入,同時(shí)帶動(dòng)傳統(tǒng)控制檢測技術(shù)日益更新。在實(shí)時(shí)檢測和自動(dòng)控制的單片機(jī)應(yīng)用系統(tǒng)中,單片機(jī)往往作為一個(gè)核心部件來使用,僅單片機(jī)方面知識(shí)是不夠的,還應(yīng)根據(jù)具體硬件結(jié)構(gòu)軟硬件結(jié)合,加以完善。
十字路口車輛穿梭,行人熙攘,車行車道,人行人道,有條不紊。那么靠什么來實(shí)現(xiàn)這井然秩序呢?靠的就是交通信號燈的自動(dòng)指揮系統(tǒng)。交通信號燈控制方式很多。本系統(tǒng)采用AT89C51單片機(jī)以及單片機(jī)最小系統(tǒng)和三極管驅(qū)動(dòng)電路以及外圍的按鍵和數(shù)碼管顯示等部件,設(shè)計(jì)一個(gè)基于單片機(jī)的交通燈設(shè)計(jì)。設(shè)計(jì)通過兩位一體共陰極數(shù)碼管顯示,并能通過按鍵對定時(shí)進(jìn)行設(shè)置。本系統(tǒng)實(shí)用性強(qiáng)、操作簡單、擴(kuò)展功能強(qiáng)。設(shè)計(jì)通過AT89C51單片機(jī)以及單片機(jī)最小系統(tǒng)和三極管驅(qū)動(dòng)數(shù)碼管(數(shù)碼管更亮,白天看的很清楚)以及外圍的按鍵和數(shù)碼管顯示等部件,數(shù)碼管倒計(jì)時(shí)顯示時(shí)間。
1.2設(shè)計(jì)要求
1、設(shè)計(jì)一款帶左轉(zhuǎn)、直行、右轉(zhuǎn)三種通行綠燈;
2、帶緊急按鈕功能, 當(dāng)緊急按鈕按下時(shí)。所有方向均亮起紅燈;
3、夜間運(yùn)行模式按鈕。按下時(shí),所有方向黃燈閃爍;
4、可更在線修改紅綠燈等待間隔時(shí)間;
5、實(shí)現(xiàn)顯示倒計(jì)時(shí)功能;
6、其他功能、創(chuàng)新部分。
第二章 硬件設(shè)計(jì)
2.1主控制器選擇
單片機(jī)(Microcontrollers)是一種集成電路芯片,是采用超大規(guī)模集成電路技術(shù)把具有數(shù)據(jù)處理能力的中央處理器CPU、隨機(jī)存儲(chǔ)器RAM、只讀存儲(chǔ)器ROM、多種I/O口和中斷系統(tǒng)、定時(shí)器/計(jì)數(shù)器等功能(可能還包括顯示驅(qū)動(dòng)電路、脈寬調(diào)制電路、模擬多路轉(zhuǎn)換器、A/D轉(zhuǎn)換器等電路)集成到一塊硅片上構(gòu)成的一個(gè)小而完善的微型計(jì)算機(jī)系統(tǒng),在工業(yè)控制領(lǐng)域廣泛應(yīng)用。從上世紀(jì)80年代,由當(dāng)時(shí)的4位、8位單片機(jī),發(fā)展到現(xiàn)在的300M的高速單片機(jī)。本文的單片機(jī)特指51單片機(jī),具體芯片型號是AT89C51。需注意STC89C51,STC89C52,AT89C52都是51單片機(jī)的一種具體芯片型號。
AT89C51是AT89C5X系列單片機(jī)的典型產(chǎn)品,它采用ATMEL的高密非易失存儲(chǔ)技術(shù)制造并和工業(yè)標(biāo)準(zhǔn)MCS—51指令集和引腳結(jié)構(gòu)兼容。通過在單塊芯片上組合通用的CPL1和快閃存儲(chǔ)器,ATMEL公司生產(chǎn)的AT89C51是一強(qiáng)勁的微型計(jì)算機(jī),它對許多嵌入式控制的應(yīng)用,提供了一種高度靈活和成本低的解決辦法。芯片AT89C51是ATMEL公司生產(chǎn)的帶2K字節(jié)快閃存儲(chǔ)器的8位單片機(jī)。
? 該單片機(jī)還具有體積小,價(jià)格低等特點(diǎn)。AT89C51單片機(jī)包含中央處理器、程序存儲(chǔ)器(ROM)、數(shù)據(jù)存儲(chǔ)器(RAM)、定時(shí)/計(jì)數(shù)器、并行接口、串行接口和中斷系統(tǒng)等幾大單元及數(shù)據(jù)總線、地址總線和控制總線等三大總線。
2.2時(shí)鐘及復(fù)位電路
AT89C51內(nèi)置最高頻率達(dá)12MHz的時(shí)鐘電路,用于產(chǎn)生整個(gè)單片機(jī)運(yùn)行的脈沖時(shí)序,但AT89C51單片機(jī)需外置振蕩電容。
本設(shè)計(jì)中,使單片機(jī)運(yùn)行在最小系統(tǒng)。
時(shí)鐘電路由兩個(gè)30pF的微調(diào)電容和一個(gè)晶振組成。AT89C51內(nèi)部有一個(gè)用于構(gòu)成振蕩器的高增益反相放大器,它的輸入端為芯片引腳XTAL1,輸出端為引腳XTAL2。這兩個(gè)引腳接石英晶體振蕩器和微調(diào)電容,構(gòu)成一個(gè)穩(wěn)定的自激振蕩器。本系統(tǒng)采用12Hz的振蕩器,機(jī)器周期為1us。復(fù)位操作有上電自動(dòng)復(fù)位、按鍵電平復(fù)位和外部脈沖復(fù)位三種方式,如圖2.1所示。
2.1時(shí)鐘及復(fù)位電路圖
2.3數(shù)碼管顯示模塊
如圖2.2所示。
2.2數(shù)碼管顯示圖
2.4指示燈模塊
設(shè)計(jì)電路中每個(gè)路口的控制信號燈應(yīng)有三個(gè),即紅燈、黃燈、綠燈各一個(gè)。因此,本電路的設(shè)計(jì)中應(yīng)用到紅燈、黃燈、綠燈個(gè)四個(gè)。同一方向的兩個(gè)路口的同一顏色指示燈是同時(shí)亮滅,為簡化電路,可讓這兩個(gè)燈接同一引腳。這樣可用P1口控制所有的指示燈,如圖2.3所示。
2.3指示燈圖
2.5按鍵模塊
如圖2.4所示。
2.4按鍵圖
第三章 軟件設(shè)計(jì)
3.1軟件設(shè)計(jì)需求及設(shè)計(jì)思路
根據(jù)本文設(shè)計(jì)需求,在硬件電路設(shè)計(jì)的基礎(chǔ)上,需要通過軟件編程實(shí)現(xiàn)的具體功能:
(1)驅(qū)動(dòng)各個(gè)模塊工作,實(shí)現(xiàn)數(shù)碼管的顯示及LED燈的點(diǎn)亮;
(2)按鍵設(shè)置功能。實(shí)現(xiàn)自動(dòng)模式倒計(jì)時(shí)增加、自動(dòng)模式倒計(jì)時(shí)減少等功能;
(3)倒計(jì)時(shí)功能實(shí)現(xiàn)。實(shí)現(xiàn)主干道方向通行30秒;
(4)LED紅綠燈的切換。實(shí)現(xiàn)紅燈和綠燈相互轉(zhuǎn)換經(jīng)過黃燈,并且黃燈閃爍。
具體設(shè)計(jì)流程如圖3.1所示。
3.1設(shè)計(jì)流程圖
3.2主函數(shù)設(shè)計(jì)
主函數(shù)的主要功能是初始化數(shù)碼管顯示和定時(shí)系統(tǒng)、驅(qū)動(dòng)各個(gè)模塊工作、通過調(diào)用函數(shù)調(diào)用各個(gè)模塊開始執(zhí)行相應(yīng)功能,如圖3.2所示。
3.2主函數(shù)設(shè)計(jì)圖
第四章 調(diào)試過程
4.1 仿真電路圖
本系統(tǒng)用protues設(shè)計(jì)的仿真原理圖如圖4.1所示。
4.1 仿真電路圖
4.2 仿真結(jié)果4.2.1主干道交通燈倒計(jì)時(shí)
如圖4.2所示。
4.2主干道交通燈倒計(jì)時(shí)圖
4.2.2倒計(jì)時(shí)結(jié)束時(shí)黃燈閃爍
如圖4.3所示。
4.3倒計(jì)時(shí)結(jié)束時(shí)黃燈閃爍圖
4.2.3增加紅綠燈時(shí)長
如圖4.4、4.5所示。
4.4增加紅綠燈時(shí)長圖
4.5增加紅綠燈時(shí)長圖
4.2.4緊急情況車輛禁行
如圖4.6所示。
4.6緊急情況車輛禁行圖
第五章 總結(jié)
剛開始選設(shè)計(jì)項(xiàng)目時(shí),我原本以為應(yīng)該不麻煩的。 因?yàn)槲疫x擇的是交通燈的控制。感覺大體是運(yùn)用定時(shí)器及中斷的原理來做。這類問題以前在單片機(jī)實(shí)驗(yàn)中做過類似的實(shí)驗(yàn),所以大體感覺應(yīng)該是很簡單的。
拿到項(xiàng)目后。我看了看后,感覺思路清晰了。用單片機(jī)中定時(shí)器和中斷的知識(shí)即可。所以我決定先完成程序設(shè)計(jì)部分,在編程過程中,我感覺以前學(xué)過的一些單片機(jī)編程的某些語法不熟悉,所以還花了一些時(shí)間復(fù)習(xí)以前的內(nèi)容。本次設(shè)計(jì)不必以前的實(shí)驗(yàn)操作。 因?yàn)檫@次交通燈的控制要求實(shí)現(xiàn)的功能比以前復(fù)雜、不僅要有各個(gè)方向通行燈的定時(shí)指示。還需要有擴(kuò)展功能。整個(gè)程序中、子程序的調(diào)用比較頻繁。
編完程序后,我在Protues中畫系統(tǒng)原理圖。以前曾用CAD畫過圖,但是感覺Protues和CAD二者還是有一定區(qū)別的。有的原件不怎么好找,畫圖、調(diào)試感覺有點(diǎn)麻煩。也費(fèi)了許多時(shí)間,但是感覺整個(gè)過程,收獲還是不少的。
附錄2程序
#include <reg52.h>//數(shù)碼管選擇位
sbit EW_1=P1^0;
sbit EW_2=P1^1;
sbit NS_1=P1^2;
sbit NS_2=P1^3;
sbit add_red_time=P1^4; //加紅燈時(shí)間按鈕
sbit add_green_time=P1^5; //加綠燈時(shí)間按鈕
sbit reduce_red_time=P1^6; //減紅燈時(shí)間按鈕
sbit reduce_green_time=P1^7; //減綠燈時(shí)間按鈕
sbit NS_led=P2^6; //南北向燈緊急控制按鈕
sbit EW_led=P2^7; //東西向燈緊急控制按鈕
sbit EW_red=P2^0; //東西向紅燈
sbit EW_green=P2^1; //東西向綠燈
sbit EW_yellow=P2^2; //東西向黃燈
sbit NS_red=P2^3; //南北向紅燈
sbit NS_green=P2^4; //南北向綠燈
sbit NS_yellow=P2^5; //南北向黃燈
char count=0; //計(jì)數(shù),count=20表示1s
char red_time=30; //紅燈停留時(shí)間
char green_time=25; //綠燈停留時(shí)間
char yellow_time=0; //黃燈停留時(shí)間
char NS_second=0; //南北紅綠燈秒計(jì)時(shí)
char EW_second=0; //東西紅綠燈秒計(jì)時(shí)
char code smgduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共陽數(shù)碼管段碼表,仿真中用的是共陰數(shù)碼管,所以使用時(shí)需對段碼取反
char display_data[4]={0}; //show_data[0]顯示南北計(jì)時(shí)十位,show_data[1]顯示南北計(jì)時(shí)個(gè)位,show_data[2]顯示東西計(jì)時(shí)十位,show_data[3]顯示東西計(jì)時(shí)個(gè)位
char temp_data[4]={0};
char NS_R_G_mode=0; //南北紅綠燈亮模式 0 紅燈 1 綠燈 2 黃燈
char EW_R_G_mode=1; //東西紅綠燈亮模式 0 紅燈 1 綠燈 2 黃燈
bit NS_R_G_flag=0; //南北紅綠燈標(biāo)識(shí)位 0 紅燈 1 綠燈
bit EW_R_G_flag=0; //東西紅綠燈標(biāo)識(shí)位 0 紅燈 1 綠燈
void delay(unsigned int i) //簡單延時(shí)
{
while(i--);
}
void Timer_init() //定時(shí)器初始化
{
//定時(shí)50ms
TMOD = 0x01; //定時(shí)器方式1
TH0 = 0x3C; //定時(shí)器賦初值
TL0 = 0xB0;
EA = 1; //開啟總中斷
ET0 = 1; //開啟定時(shí)器中斷
TR0 = 1; //開啟定時(shí)器
}
void Init() //系統(tǒng)初始化
{
P0=0x00;
P2=0x00;
EW_1=1;
EW_2=1;
NS_1=1;
NS_2=1;
NS_led=1;
EW_led=1;
NS_second=red_time; //默認(rèn)初始時(shí)南北向燈亮紅燈,并賦紅燈時(shí)長
EW_second=green_time; //默認(rèn)初始時(shí)東西向燈亮綠燈,并賦綠燈時(shí)長
yellow_time=red_time-green_time;//黃燈時(shí)間為紅燈時(shí)間與綠燈時(shí)間差
Timer_init();
}
void NS_SMG_drive(char *buff) //南北向數(shù)碼管驅(qū)動(dòng)
{
//顯示十位
NS_1=0;
NS_2=1;
P0=~smgduan[buff[0]]; //段碼取反
delay(5); //間隔一段時(shí)間掃描
P0=0x00; //消隱
NS_1=1;
NS_2=0;
P0=~smgduan[buff[1]];
delay(5);
P0=0x00; //關(guān)閉南北向數(shù)碼管
NS_1=1;
NS_2=1;
}
void EW_SMG_drive(char *buff) //東西向數(shù)碼管驅(qū)動(dòng)
{
EW_1=0;
EW_2=1;
P0=~smgduan[buff[2]]; //段碼取反
delay(5); //間隔一段時(shí)間掃描
P0=0x00; //消隱
EW_1=1;
EW_2=0;
P0=~smgduan[buff[3]];
delay(5);
P0=0x00; //關(guān)閉東西向數(shù)碼管
EW_1=1;
EW_2=1;
}
void data_del(char *buff,char data1,char data2) //數(shù)據(jù)處理
{
buff[0]=data1/10; //取data1的十位
buff[1]=data1%10; //取data1的個(gè)位
buff[2]=data2/10; //取data2的十位
buff[3]=data2%10; //取data2的個(gè)位
}
void Time_del() //計(jì)時(shí)處理
{
if(count>=20) //判斷是否滿1s
{
NS_second--; //南北向燈計(jì)時(shí)自減
EW_second--; //東北向燈計(jì)時(shí)自減
switch(NS_R_G_mode) //南北向燈
{
case 0: //紅燈
{
if(NS_second<0)
{
NS_second=green_time; //開始綠燈倒計(jì)時(shí)
NS_R_G_mode=1; //紅燈亮完綠燈亮
}
}break;
case 1: //綠燈
{
if(NS_second<0)
{
NS_second=yellow_time; //開始黃燈倒計(jì)時(shí)
NS_R_G_mode=2; //綠燈亮完黃燈亮
}
}break;
case 2: //黃燈
{
if(NS_second<0)
{
NS_second=red_time; //開始紅燈到計(jì)時(shí)
NS_R_G_mode=0; //黃燈亮完紅燈亮
}
}break;
default:break;
}
void R_G_Y_led() //紅綠燈驅(qū)動(dòng)
{
switch(NS_R_G_mode) //南北向
{
case 0: //紅燈
{
NS_yellow=0; //黃燈滅
NS_red=1; //紅燈亮
}break;
case 1: //綠燈
{
NS_red=0; //紅燈滅
NS_green=1; //綠燈亮
}break;
case 2: //黃燈
{
NS_green=0; //綠燈滅
if(count<10) //黃燈以1hz頻率閃爍
NS_yellow=1;
else
NS_yellow=0;
}break;
default:break;
}
switch(EW_R_G_mode) //東西向
{
case 0: //紅燈
{
EW_yellow=0; //黃燈滅
EW_red=1; //紅燈亮
}
if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//設(shè)置紅綠燈時(shí)長時(shí)任一設(shè)置按鈕都可觸發(fā)
{
TR0 = 0; //關(guān)閉定時(shí)器
P2=0x00; //清零P2寄存器
EW_led=1; //EW_led、NS_led引腳也在P2寄存器內(nèi),但是后面需要這兩個(gè)按鈕結(jié)束設(shè)置紅綠燈時(shí)長任務(wù),故而這兩個(gè)引腳要拉高
NS_led=1;
while(1)
{
data_del(temp_data,red_time,green_time);//顯示當(dāng)前紅綠燈時(shí)長
NS_SMG_drive(temp_data);
EW_SMG_drive(temp_data);
if(add_red_time==0) //判斷加紅燈時(shí)間按鈕是否按下
{
delay(5); //消抖
if(add_red_time==0)
{
red_time++; //紅燈時(shí)間自加
if(red_time>99) //限制紅燈時(shí)間最大值為99
red_time=99;
data_del(temp_data,red_time,red_time);//南北向數(shù)碼管顯示紅燈時(shí)長
NS_SMG_drive(temp_data);
}while(!add_red_time); //等待加紅燈時(shí)間按鈕彈起
}
if(add_green_time==0) //判斷加綠燈時(shí)間按鈕是否按下
{
delay(5);
if(add_green_time==0)
{
green_time++; //綠燈時(shí)間自加
if(green_time>95) //限制綠燈時(shí)間最大值95
green_time=95;
data_del(temp_data,green_time,green_time);//東西向數(shù)碼管顯示綠燈時(shí)長
EW_SMG_drive(temp_data);
}while(!add_green_time); //等待加綠燈時(shí)間按鈕彈起
}
if(reduce_red_time==0) //判斷減紅燈時(shí)間按鈕是否按下
{
delay(5);
if(reduce_red_time==0)
{
red_time--; //紅燈時(shí)間自減
if(red_time<10) //限制紅燈時(shí)間最小值10
red_time=10;
data_del(temp_data,red_time,red_time);
NS_SMG_drive(temp_data);
}while(!reduce_red_time); //等待減紅燈時(shí)間按鈕彈起
}
if(reduce_green_time==0) //判斷減綠燈時(shí)間按鈕是否按下
{
delay(5);
if(reduce_green_time==0)
{
green_time--; //綠燈時(shí)間自減
if(green_time<5) //限制綠燈時(shí)間最小值5
green_time=5;
data_del(temp_data,green_time,green_time);
EW_SMG_drive(temp_data);
}while(!reduce_green_time); //等待減綠燈時(shí)間按鈕彈起
}
if((NS_led==0)||(EW_led==0)) //任一緊急控制按鈕按下則結(jié)束設(shè)置紅路燈時(shí)長任務(wù)
{
break;
}
}while((!NS_led)||(!EW_led)); //等待緊急控制按鈕彈起
TR0 = 1; //開啟定時(shí)器
yellow_time=red_time-green_time; //更新黃燈時(shí)間
}
}
void Urgent() //紅綠燈緊急控制
{
if((NS_led==0)||(EW_led==0)) //任一緊急控制按鈕按下觸發(fā)
{
TR0 = 0; //關(guān)閉定時(shí)器
P2=0x00;
EW_led=1;
NS_led=1;
EW_1=1; //關(guān)閉所有數(shù)碼管
EW_2=1;
NS_1=1;
NS_2=1;
while((!NS_led)||(!EW_led)); //判斷緊急控制按鈕按是否彈起
while(1)
{
if(NS_R_G_flag) //根據(jù)NS_R_G_flag狀態(tài)交替亮紅燈或者綠燈
{
NS_green=1;
NS_red=0;
}
else
{
NS_red=1;
NS_green=0;
}
if(EW_R_G_flag) //根據(jù)EW_R_G_flag狀態(tài)交替亮紅燈或者綠燈
{
EW_green=1;
EW_red=0;
}
else
{
EW_red=1;
EW_green=0;
}
if(NS_led==0) //判斷南北向緊急控制按鈕是否按下
{
delay(5);
if(NS_led==0)
{
NS_R_G_flag=!NS_R_G_flag; //NS_R_G_flag狀態(tài)取反
}while(!NS_led); //等待南北向緊急控制按鈕彈起
}
if(EW_led==0) //判斷東西向緊急控制按鈕是否按下
{
delay(5);
if(EW_led==0)
{
EW_R_G_flag=!EW_R_G_flag; //EW_R_G_flag狀態(tài)取反
}while(!EW_led); //等待東西向緊急控制按鈕彈起
}
if((add_red_time==0)||(add_green_time==0)||(reduce_red_time==0)||(reduce_green_time==0))//任一紅綠燈設(shè)置時(shí)長按鈕按下結(jié)束緊急控制人物
{
TR0 = 1; //開啟定時(shí)器
break;
}
}while((!add_red_time)||(!add_green_time)||(!reduce_red_time)||(!reduce_green_time));//等待紅綠燈時(shí)間設(shè)置按鈕彈起
P2=0x00;
EW_led=1;
NS_led=1;
}
}
void main()
{
Init();
while(1)
{
Time_del(); //時(shí)間處理
data_del(display_data,NS_second,EW_second);//數(shù)據(jù)處理
NS_SMG_drive(display_data); //南北向數(shù)碼管驅(qū)動(dòng)
EW_SMG_drive(display_data); //東西向數(shù)碼管驅(qū)動(dòng)
R_G_Y_led(); //紅綠燈驅(qū)動(dòng)
Set_time(); //紅綠燈時(shí)長設(shè)置
Urgent(); //緊急控制
}
}
void Timer0(void) interrupt 1 //定時(shí)器中斷
{
TH0 = 0x3C;
TL0 = 0xB0;
count++; //觸發(fā)中斷后計(jì)數(shù)值自加,定時(shí)器中斷每50ms觸發(fā)一次
}
|
|