基于STC89C51單片機(jī)的簡(jiǎn)易交通信號(hào)燈
前言
本設(shè)計(jì)學(xué)校的一次單片機(jī)實(shí)訓(xùn)。
一、基本原理
利用51單片機(jī)控制各個(gè)路口紅綠燈及時(shí)間顯示。
1、設(shè)計(jì)的重點(diǎn):
1、題目要求
1、各個(gè)路口紅綠燈亮滅的規(guī)則,暫不考慮左轉(zhuǎn)方向;
2、倒計(jì)時(shí)的實(shí)現(xiàn),利用單片機(jī)的定時(shí)器進(jìn)行計(jì)數(shù)得到秒信號(hào);
3、時(shí)間顯示:東西南北四個(gè)方向的時(shí)間一致,當(dāng)東西方向?yàn)?0秒綠燈通行時(shí)間,同時(shí)南北方向?yàn)?0秒紅燈禁止時(shí)間,因此硬件連接時(shí)可考慮東西南北方向可采用同一接法;最后相當(dāng)于2個(gè)數(shù)碼管動(dòng)態(tài)顯示,具體見(jiàn)參考電路框圖。
4、按鍵設(shè)置(擴(kuò)展要求):設(shè)置鍵按一次,設(shè)置主干道通信時(shí)間(即次干道禁止時(shí)間),按第二次,設(shè)置主干道禁止時(shí)間(即次干道通信時(shí)間),按第三次,可作為緊急通信鍵。設(shè)置時(shí)間需要確定,可通過(guò)確定鍵實(shí)現(xiàn),也可通過(guò)延時(shí)確定,如10秒。當(dāng)然也可根據(jù)需要增加相應(yīng)的按鍵。
2、性能指標(biāo)要求
1、各方向的紅、綠色信號(hào)燈能按照設(shè)定規(guī)則運(yùn)行;
2、綠燈亮之前,黃燈閃爍5次;
3、紅燈和綠燈倒計(jì)時(shí)間能夠正確顯示;
4、兩干道的車(chē)輛不會(huì)會(huì)車(chē)沖突。
5、可以擴(kuò)展其他功能(如按鍵設(shè)置時(shí)間,按鍵模擬警車(chē))
二、原理圖設(shè)計(jì)
1、電路框圖
大概的設(shè)計(jì)流程圖如下:
2、原理圖
原理圖畫(huà)法有很多種,符合設(shè)計(jì)要求即可,基本就是在最小系統(tǒng)的基礎(chǔ)上加入按鍵電路、數(shù)碼管顯示電路、led信號(hào)燈三個(gè)部分就行了。一般情況下數(shù)碼數(shù)碼管接到P0口上( 記得加上拉電阻),六個(gè)信號(hào)燈接到P1口,四個(gè)按鍵接到P3口,(P3.4、P3.5、P3.6、P3.7)。
三、硬件電路搭建
1.元器件
主控芯片:stc89c52rc、數(shù)碼管:兩位共陰數(shù)碼管(5621AS-1)
洞洞板一塊(萬(wàn)用板)
12顆led燈(紅黃綠分別4顆)、四個(gè)按鍵、以及搭建最小系統(tǒng)所需的原件
另外還需一個(gè)TTL下載器用于代碼的燒錄。
跳線若干。
1.實(shí)物焊接圖
實(shí)物焊接正面圖
實(shí)物背面焊接圖
焊接過(guò)程注意事項(xiàng)(難點(diǎn))
其實(shí)整個(gè)電路難點(diǎn)在于焊接,考驗(yàn)對(duì)烙鐵的使用和實(shí)際動(dòng)手的能力(雖然我焊接的比較丑但在整個(gè)焊接過(guò)程中只要心中有圖基本就不會(huì)出什么問(wèn)題了)。
個(gè)人焊接建議是先把最先系統(tǒng)部分焊接完后先燒錄一下代碼看看能不能成功燒錄,不要著急焊接其他部分,只要完成了最小系統(tǒng)的焊接后面的就照著原理圖連線。
另外就是分不清數(shù)碼管上的10個(gè)引腳如何焊接的,只要把數(shù)碼管對(duì)應(yīng)下圖連到P0口,a, b, c, d, e, f, g, dp 對(duì)應(yīng)P0.0—P0.7,1和2是位選端,接到P2.0和P2.1。
四、軟件代碼部分
1、編譯環(huán)境和燒錄軟件
編譯器是keil5會(huì)使用就行這里不過(guò)多講解只要會(huì)建工程燒代碼就行了,
代碼燒錄器是stc-isp,
1.代碼
代碼部分基本每一句我都給了注釋?zhuān)赡苡行](méi)描述好,但基本只要了解C語(yǔ)言基本都能讀懂了,打開(kāi)Keil uVision5或者Keil uVision4,新建個(gè)工程復(fù)制粘貼就去就可以了。
代碼如下(示例):文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-819701.html
#include"REG52.H"
#include"intrins.h"
#define uchar unsigned char//定義全局變量無(wú)符號(hào)字符型uchar
#define uint unsigned int//定義全局變量無(wú)符號(hào)整型uint
uchar Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//數(shù)碼管段碼
uchar nt=60,wt=60,sz=0,t,DJS=60,seg=60,tx=10;//定義變量
bit ms=0;//標(biāo)志位
sbit k = P3^4; //進(jìn)入時(shí)間設(shè)置
sbit g = P3^5; //結(jié)束設(shè)置
sbit a = P3^7; //時(shí)間加
sbit j = P3^6; //時(shí)間減
sbit we1=P2^0;//數(shù)碼管位選端第一位
sbit we2=P2^1;//數(shù)碼管位選端第二位
sbit NSG=P1^2;//南北方向綠燈
sbit NSY=P1^1;//黃燈
sbit NSR=P1^0;//紅燈
sbit WEG=P1^5;//東西方向綠燈
sbit WEY=P1^4;//黃燈
sbit WER=P1^3;//紅燈
/函數(shù)聲明/
void delay(uint t);//延時(shí)函數(shù)
void display();//數(shù)碼管顯示函數(shù)
void Init_Timer0(void);//定時(shí)器
void NST();//南北指示燈函數(shù)
void WET();//東西指示燈函數(shù)
void jstx();//緊急通行
void keycan();//按鍵設(shè)置函數(shù)
主函數(shù)/
void main()
{
Init_Timer0();//定時(shí)器初始化
while(1)
{
if(sz==3) //判斷標(biāo)志位第三次按下為緊急通行
{
//ms==!(1&&0);//ms==3緊急通行時(shí)黃燈不閃碩
seg=tx; //數(shù)碼管顯示的值為10
jstx(); //執(zhí)行緊急通行函數(shù)
}
if(sz==1) //判斷標(biāo)志位第1次按下為南北倒計(jì)時(shí)設(shè)置
{seg=nt;} //數(shù)碼管初始值為南北倒計(jì)時(shí)時(shí)間60秒
if(sz==2) //判斷標(biāo)志位第2次按下為南北倒計(jì)時(shí)設(shè)置
{seg=wt;} //數(shù)碼管初始值為東西倒計(jì)時(shí)時(shí)間60秒
if(sz==0) //沒(méi)按下時(shí)正常執(zhí)行正常通行
{
if(ms==0) //如果ms==0,
{NST();} //執(zhí)行南北倒計(jì)時(shí)設(shè)置
if(ms==1) //如果ms==1,
{WET();} //執(zhí)行東西倒計(jì)時(shí)設(shè)置
}
keycan();//按鍵子函數(shù)
display();//數(shù)碼管顯示子函數(shù)
}
}
/延時(shí)函數(shù)/
void delay(uint t)
{
uchar x,y;
for(x=0;x<t;x++) //普通延時(shí)函數(shù)
for(y=0;y<200;y++);
}
///數(shù)碼管顯示函數(shù)//
void display()
{
we1=0;//位選十位關(guān)
we2=1;//位選個(gè)位開(kāi)
P0=Tab[seg%10]; //顯示個(gè)位
delay(5); //延時(shí)
P0=0x00; //數(shù)碼管清零(消影)
we1=1; //位選十位開(kāi)
we2=0; //位選個(gè)位關(guān)
P0=Tab[seg/10]; //顯示十位
delay(5); //延時(shí)
P0=0x00; //數(shù)碼管清零
}
//定時(shí)器
void Init_Timer0(void)
{
TMOD &= 0XF0;
TMOD |= 0x01; //使用模式1,16位定時(shí)器
TH0=0x3c; //裝初值3c b0 為50ms
TL0=0xb0;
IP=0x02; //定時(shí)器0優(yōu)先級(jí)高
TR0=1; //啟用T0計(jì)數(shù)器/定時(shí)器
ET0=1; //打開(kāi)T0定時(shí)器中斷
EA=1; //總中斷開(kāi)關(guān),任何中斷都無(wú)法執(zhí)行
}
void timer0 (void) interrupt 1 //using 0
{
TH0=0x3c; //初值,產(chǎn)生50ms定時(shí)
TL0=0xb0;
t++; //t一直自加,加一次是50ms加到20次
if(t==20) //20個(gè)50毫秒等于1000毫秒等于1秒
{
DJS--; //倒計(jì)時(shí)自減
t=0;
if(DJS<=5)//如果倒計(jì)時(shí)小于等于5秒
{
if(ms==1) //判斷通道如果標(biāo)志位ms為1代表南北通道的黃燈閃爍
{NSY=~NSY;} //黃燈閃爍
if(ms==0) //ms為0代表東西通道的黃燈閃爍
{WEY=~WEY;} //黃燈閃爍
else(NSY||WEY==1);
}
if(DJS==0) //如果倒計(jì)時(shí)結(jié)束
{
ms=~ms; //南北通道替換
NSY=1; //南北通道黃燈熄滅
WEY=1; //東西通道黃燈熄滅
if(ms==0) //第一個(gè)按鍵標(biāo)志位ms=0
{DJS=nt;} //倒計(jì)時(shí)為初始值nt=60秒
if(ms==1) //第一個(gè)按鍵標(biāo)志位ms=1
{DJS=wt;} //倒計(jì)時(shí)為初始值wt=60秒
}
if(sz==3) //判斷標(biāo)志位第3次按下進(jìn)入緊急通行模式
{
tx--; //緊急模式下的10秒倒計(jì)時(shí)(tx變量開(kāi)頭處設(shè)置的10)
if(tx==0)//如果倒計(jì)時(shí)結(jié)束
{sz=0;}//恢復(fù)正常通行狀態(tài)
}
}
}
/**********東西通行函數(shù)*******************/
void WET()
{
seg=DJS;//數(shù)碼管顯示初始狀態(tài)的60秒倒計(jì)時(shí)時(shí)間
NSG=1;//南北綠燈滅
NSR=0;//南北紅燈亮
NSY=1;//南北黃燈滅
WER=1;//東西紅燈滅
WEG=0;//東西綠燈亮
WEY=1;//東西黃燈滅
}
/**********南北通行函數(shù)*******************/
void NST()
{
seg=DJS;//數(shù)碼管顯示初始狀態(tài)的60秒倒計(jì)時(shí)時(shí)間
NSG=0;
NSR=1;
NSY=1;
//亮滅情況同東西通行情況同理
WER=0;
WEG=1;
WEY=1;
}
/**************緊急通行函數(shù)*******************/
void jstx()
{
NSG=1;
NSR=0;
NSY=1;//只有紅燈亮,其他全滅
WEG=1;
WER=0;
WEY=1;
}
/**************按鍵設(shè)置函數(shù)*******************/
void keycan()
{
if(k==0)//
{
delay(10);//延時(shí)一下是為了消抖
if(k==0) //設(shè)置鍵按下進(jìn)入設(shè)置狀態(tài)
{
sz++; //設(shè)置按鍵按一次自加一次
if(sz==4) //第四次按下
{sz=0;} //回到初始狀態(tài)
if(sz==3) //判斷標(biāo)志位第3次按下進(jìn)入緊急通行模式
{tx=10;} //緊急模式倒計(jì)時(shí)時(shí)間賦值為10
}
while(!k);//不滿(mǎn)足第一個(gè)按鍵按下就跳出循環(huán)
}
if(a==0&&sz==1) //
{
delay(10);//延時(shí)消抖
if(a==0&&sz==1)//a變量代表加按鍵sz變量代表設(shè)置按鍵
{
nt++; //按了一次設(shè)置鍵后,按時(shí)加鍵,南北方向時(shí)間加一
if(nt==61) //南北方向上的時(shí)間加到60,為什是61?因?yàn)榘吹?1次的時(shí)候其實(shí)按的是1
{nt=1;} //跳回1
}
while(!a); //跳出循環(huán)
}
if(a==0&&sz==2) //按了第二次設(shè)置鍵后,按時(shí)加鍵,西南方向時(shí)間加一
{
delay(10);//延時(shí)消抖
if(a==0&&sz==2)
{
wt++;//東西方向時(shí)間加
if(wt==61)//東西方向上的時(shí)間加到60,為什是61?因?yàn)榘吹?1次的時(shí)候其實(shí)按的是1
{wt=1;}//跳回1
}
while(!a);//跳出循環(huán)
}
if(j==0&&sz==1)//按了第一次設(shè)置鍵后,按時(shí)間減按鍵,按一次南北方向時(shí)間減一
{
delay(10);//延時(shí)消抖
if(j==0&&sz==1)
{
nt--;//南北方向時(shí)間減
if(nt==0)//減到0
{nt=60;}//跳回60
}
while(!j);//跳出循環(huán)
}
if(j==0&&sz==2)//按了第二次設(shè)置鍵后,按時(shí)間減鍵,西南方向時(shí)間減一
{
delay(10);//延時(shí)消抖
if(j==0&&sz==2)
{
wt--;
if(wt==0)//減到0
{wt=60;}//跳回60
}
while(!j);//跳出循環(huán)
}
if(g==0)//設(shè)置完成,按下后保存設(shè)置,退出設(shè)置狀態(tài)
{
delay(10); //延時(shí)消抖
if(g==0)
{sz=0;} //回到初始狀態(tài)
while(!g); //跳出循環(huán)
}
}
總結(jié)
這是我大一期間的一個(gè)單片機(jī)實(shí)訓(xùn),出于最近好多學(xué)弟問(wèn)設(shè)計(jì)原理就簡(jiǎn)單潦草的總結(jié)了一下,當(dāng)然最核心的資料都是有的,只要?jiǎng)邮帜芰?qiáng)一點(diǎn),照著原理圖焊接好電路,燒代碼基本就OK了。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-819701.html
到了這里,關(guān)于基于51單片機(jī)的交通信號(hào)燈的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!