基于89C52的交通燈系統(tǒng)

交通燈控制設(shè)計(jì)

一稚照、選題背景

????每個(gè)城市的交通就猶如人體的血管蹂空,人類生命的持續(xù)需要心臟為血液提供動力,依靠血液來在人體內(nèi)完成各類物質(zhì)交換果录,完成新陳代謝上枕,保持一個(gè)健康的體魄,而城市的交通于整個(gè)城市的重要性不亞于血液于人體弱恒,城市需要依靠一個(gè)可以正常運(yùn)轉(zhuǎn)的交通系統(tǒng)來推動交流與發(fā)展辨萍。

????交通系統(tǒng)也可以稱作為交通網(wǎng),由各個(gè)部分的道路和相關(guān)設(shè)施組成返弹,現(xiàn)如今的交通網(wǎng)是發(fā)達(dá)但不完善的锈玉,雖然隨著智能化的覆蓋面越來越廣,幾年后就可能不再需要交通燈义起,但交通燈依然是城市規(guī)劃者引導(dǎo)車流人流最實(shí)惠又最穩(wěn)定的工具拉背。步入下一個(gè)時(shí)代前,需要工程師先參透舊時(shí)代默终,有故方能新是經(jīng)過歷史的證明的椅棺,所以下一個(gè)工具的誕生需要對交通燈的工作原理進(jìn)行剖析及穩(wěn)定實(shí)現(xiàn)犁罩,此次設(shè)計(jì)的目的更多的是在于對舊事物的思考,并引出新事物的設(shè)想

????我國交通信號燈分為3種:紅燈代表暫停两疚;黃燈代表緩行床估;綠燈代表通行。本設(shè)計(jì)通過采用電子元件對交通燈控制電路進(jìn)行設(shè)計(jì),實(shí)現(xiàn)十字路口交通管理的自動化鬼雀。

????針對本次交通燈的制作顷窒,設(shè)計(jì)者依次使用Altium designer 2016完成原理圖的設(shè)計(jì),PCB的手動布線源哩,再使用相關(guān)設(shè)備制作電路板,最后依靠keil軟件寫入C語言程序以達(dá)到硬件和軟件的相互兼容的效果鸦做。


1.1??單片機(jī)簡介

????單片機(jī)又稱單片微控制器,它不是完成某一個(gè)邏輯功能的芯片,而是把一個(gè)計(jì)算機(jī)系統(tǒng)集成到一個(gè)芯片上励烦,相當(dāng)于一個(gè)微型的計(jì)算機(jī),和計(jì)算機(jī)相比泼诱,單片機(jī)只缺少了I/O設(shè)備坛掠。概括的講:一塊芯片就成了一臺計(jì)算機(jī)。它的體積小治筒、質(zhì)量輕屉栓、價(jià)格便宜、控制功能強(qiáng)耸袜、使用方便友多、容易產(chǎn)品化,為學(xué)習(xí)堤框、應(yīng)用和開發(fā)提供了便利條件域滥。

1.2??單片機(jī)編程語言

????程序設(shè)計(jì)需要編程語言,常用的編程語言有:機(jī)器語言蜈抓、匯編語言和高級語言启绰。

????機(jī)器語言是CPU硬件唯一能夠直接識別的語言,在設(shè)計(jì)CPU時(shí)就已經(jīng)確定了其代碼的含義沟使。要執(zhí)行任何操作委可,都必須轉(zhuǎn)換為相應(yīng)的機(jī)器語言,由CPU識別腊嗡、控制執(zhí)行着倾。機(jī)器語言必須為二進(jìn)制代碼,不便于記憶叽唱、使用和直接編寫程序屈呕。

????匯編語言使用人們便于記憶的符號來描述與之相應(yīng)的機(jī)器語言,這些符號稱為助記符棺亭。用助記符表示的指令稱為匯編語言指令虎眨,用助記符編寫出來的程序稱為匯編語言程序。用匯編語言編寫的程序運(yùn)行速度快、占用內(nèi)存單元少嗽桩、效率高岳守,但程序設(shè)計(jì)者必須熟悉單片機(jī)內(nèi)部資源等硬件設(shè)施。

????目前碌冶,社會上廣泛使用的是高級語言(如C語言)湿痢。單片機(jī)不能識別高級語言的程序,因此需要用編譯器對高級語言程序翻譯成機(jī)器語言程序后再寫入單片機(jī)扑庞。作為一種更接近人們習(xí)慣的程序設(shè)計(jì)語言譬重,它使用人們熟悉的文字舶得、符號及數(shù)學(xué)表達(dá)式來編寫程序在验,因此程序的編寫和操作都十分方便,本次交通燈控制程序也選用C語言强品。


二栅隐、方案論證

2.1課程設(shè)計(jì)要求

2.1.1系統(tǒng)功能

(1)在LED數(shù)碼管上顯示倒計(jì)時(shí)塔嬉,單位為秒。

(2)采用LED模擬信號燈租悄,信號燈分東西谨究、南北二組,分別有“紅”“黃”“綠”三種顏色泣棋。分別設(shè)定有南北通行狀態(tài)胶哲,東西通行狀態(tài),夜間黃燈閃爍狀態(tài)外傅。

(3)采用矩陣鍵盤控制狀態(tài)切換纪吮,同時(shí)實(shí)現(xiàn)按0——9的數(shù)字鍵能夠修改南北、東西紅綠黃燈亮燈的時(shí)間萎胰。分別設(shè)置一個(gè)紅碾盟、黃、綠燈按鈕設(shè)置鍵技竟,選擇一個(gè)方向設(shè)置冰肴,另外一個(gè)方向通過計(jì)算可知。設(shè)置一個(gè)數(shù)字輸入確認(rèn)鍵榔组。


2.1.2 硬件設(shè)計(jì)

(1)CPU為89C52單片機(jī)熙尉;

(2)鍵盤為4×4行列式鍵盤,接入單片機(jī)的P1口搓扯,用于輸入相關(guān)的控制指令检痰;

(3)兩個(gè)3位LED數(shù)碼管,顯示相應(yīng)通行方向的倒計(jì)時(shí)時(shí)間锨推;


2.1.3 軟件設(shè)計(jì)

??? (1)控制交通燈程序铅歼。軟件需要使交通燈在不同模式下實(shí)現(xiàn)不同的亮閃模式公壤,且需要綠燈、紅燈與黃燈的相互配合椎椰,實(shí)現(xiàn)在同一時(shí)序下嚴(yán)格按照圖2.1的要求實(shí)現(xiàn)功能厦幅;

??? (2)LED數(shù)碼管顯示程序。需要在軟件的設(shè)計(jì)中實(shí)現(xiàn)段選慨飘、位選确憨,同時(shí)運(yùn)用動態(tài)顯示的方式,完成倒計(jì)時(shí)及計(jì)數(shù)輸入顯示的功能瓤的;

??? (3)鍵盤管理程序(包括鍵掃描休弃、鍵處理程序)。鍵盤為4 * 4矩陣鍵盤堤瘤,不同于獨(dú)立按鍵玫芦,需要在軟件的編寫過程中進(jìn)行循環(huán),以實(shí)現(xiàn)不斷掃描鍵盤本辐,檢測是否輸入及其鍵值,一來實(shí)現(xiàn)各種功能的選擇医增,二來完成計(jì)數(shù)值的輸入慎皱。

2.2 方案介紹

????鑒于實(shí)驗(yàn)室提供的元器件,設(shè)計(jì)者選擇了STC89C52叶骨,在方案設(shè)計(jì)中選擇P0口為三位數(shù)碼管的段選端口茫多,P1口為位選口,P2口為矩陣鍵盤忽刽,兩個(gè)接數(shù)碼管的I/O口都連接了74LS573來進(jìn)行鎖存天揖,P3則用于交通燈信號的輸出,同時(shí)采用了USB供電跪帝,且為上電復(fù)位今膊,同時(shí)采用12M晶振來構(gòu)成51單片機(jī)的最小系統(tǒng)板。


2.3 硬件介紹

2.3.1所用元器件

STC89C52芯片? ????1

74LS573? ? ? ? ? ? ?????2

12MHz晶振? ? ? ? ?????1

30PF電容????????????????2

10uf/50V電解電容????1

10kΩ電阻????????????????1

鍵盤????????????????????????1

鍵盤插針????????????????1

按鍵????????????????????????1

1kΩ排阻????????????????2

1kΩ電阻????????????????6

LED燈????????????????????6

USB口????????????????????1

3位共陰極數(shù)碼管????2

?

2.3.2硬件詳細(xì)介紹

(1)STC89C52

????STC89C51RC/RD+系列單片機(jī)(包括STC89C52RC)是宏晶科技推出的新一代超強(qiáng)抗干擾伞剑、高速斑唬、低功耗的單片機(jī),基于Intel 標(biāo)準(zhǔn)的8052黎泣,指令代碼完全兼容傳統(tǒng)的8051 系列單片機(jī)恕刘,12 時(shí)鐘/機(jī)器周期和6 時(shí)鐘/機(jī)器周期可任意選擇。工作電壓:5.5V- 3.4V(5V 單片機(jī)) 抒倚。工作頻率范圍:0 – 40 MHz,相當(dāng)于普通的8051 的0~80 Mhz褐着,實(shí)際工作頻率可達(dá)到48MHz。用戶應(yīng)用程序空間4K托呕、8K含蓉、13K频敛、16K、20K谴餐、32K姻政、64K 字節(jié)。片上集成1280 字節(jié)岂嗓、512 字節(jié)RAM汁展。通用I/O(32個(gè)),復(fù)位后為:P0厌殉、P1食绿、P2、P3是準(zhǔn)雙向口公罕、弱上拉(普通8051 傳統(tǒng)I/O 口)器紧,P0 口是開漏輸出,作為總線拓展用時(shí)楼眷,不用加上拉電阻铲汪,作為I/O 口用時(shí),需要加上拉電阻罐柳。

(2)單片機(jī)供電電路

????89C52為5V單片機(jī)掌腰,采用USB供電是最常用的方式,不管是連接電腦或移動電源都可以達(dá)到相應(yīng)的適配效果张吉。

(3)振蕩電路

????根據(jù)89C52單片機(jī)的相關(guān)設(shè)定齿梁,采用了12MHz晶振,它起到的作用是為單片機(jī)提供基準(zhǔn)的時(shí)針信號肮蛹,單片機(jī)內(nèi)部所有的工作都是以這個(gè)時(shí)鐘信號為步調(diào)基準(zhǔn)來進(jìn)行工作的勺择。除了晶振以外,還需要兩個(gè)30pF的電容伦忠,電容的作用是幫助晶振起振省核,并維持振蕩信號的穩(wěn)定。單片機(jī)晶體振蕩器提供的時(shí)鐘頻率越高缓苛,單片機(jī)運(yùn)行的速度就越快芳撒。

(4)復(fù)位電路

????根據(jù)實(shí)驗(yàn)要求,要實(shí)現(xiàn)上電復(fù)位未桥,且對于89C52而言笔刹,需要實(shí)現(xiàn)上電時(shí)為RST引腳提供一個(gè)高電平以實(shí)現(xiàn)復(fù)位。?

(5)3位數(shù)碼管電路

????數(shù)碼管分為共陰極數(shù)碼管和共陽極數(shù)碼管兩種冬耿。共陰極數(shù)碼管所有LED燈的陰極連在一起舌菜,而共陽極數(shù)碼管則是所有LED燈的所有陽極連接在一起。在實(shí)驗(yàn)中亦镶,由于實(shí)驗(yàn)室提供的元器件選擇了圖2.7所示的共陰極數(shù)碼管日月,選用時(shí)袱瓮,拉低選用位,拉高選用段爱咬,且選擇74LS573作為驅(qū)動尺借,74LS573 的八個(gè)鎖存器都是透明的D 型鎖存器,當(dāng)使能LE引腳為高時(shí)精拟,(O)輸出將隨數(shù)據(jù)(D)輸入而變燎斩。當(dāng)使能為低時(shí),輸出將鎖存在已建立的數(shù)據(jù)電平上蜂绎。輸出控制不影響鎖存器的內(nèi)部工作栅表,即老數(shù)據(jù)可以保持,甚至當(dāng)輸出被關(guān)閉時(shí)师枣,新的數(shù)據(jù)也可以置入怪瓶。實(shí)驗(yàn)中總共6位數(shù)碼管,為了在節(jié)省I/O口的條件下践美,使電流穩(wěn)定輸出洗贰,必須在位選端和段選端都接入74LS573作為驅(qū)動。

(6)鍵盤電路

????為了提高單片機(jī)系統(tǒng)中I/O口的利用率矩陣鍵盤采用四條I/O線作為行線陨倡,四條I/O線作為列組成鍵盤哆姻,在行和列的每個(gè)交叉點(diǎn)上設(shè)置一個(gè)按鍵,采用4 * 4鍵盤共16個(gè)鍵玫膀。

????在一個(gè)循環(huán)中先掃描第一行,即將第一行輸出0電平爹脾,然后讀入列值帖旨,哪一列出現(xiàn)0電平,就說明該列與第一行跨接的按鍵被按下灵妨,若讀入的列值全為1解阅,則說明與第一行跨接的按鍵沒有被按下,然后按以上步驟逐行掃描泌霍,直到找到被按下的按鍵货抄。

????同時(shí)需要在每一條列線都接上拉電阻,這是為了給高阻抗輸入提供一個(gè)穩(wěn)定的高電平朱转,因?yàn)橛行﹩纹瑱C(jī)的I/O口作為輸出時(shí)只能提供高阻抗輸出與低電平輸出蟹地,被稱作“準(zhǔn)三態(tài)門”,在這些“準(zhǔn)三態(tài)門”口線作為鍵盤行線的掃描時(shí)藤为,提供所謂的“高電平”實(shí)際上驅(qū)動能力是很弱的怪与,列線在讀取時(shí),可能會發(fā)生誤判缅疟,所以必須要在讀取時(shí)加上拉電阻分别,將高阻態(tài)轉(zhuǎn)換為穩(wěn)定的高電平遍愿,才能保證讀取的正確

(7)紅綠燈電路

??? 在實(shí)驗(yàn)中采用了南北方向紅綠黃燈和東西方向紅綠黃燈兩組LED,同時(shí)為了保護(hù)LED接入1kΩ電阻耘斩。

三沼填、過程論述

3.1原理圖制作

??? 本次實(shí)驗(yàn)的原理圖繪制采用了Altium Designer 2016軟件,第一步建立一個(gè)工程括授,在其中建一個(gè)原理圖文件原理圖庫文件坞笙。根據(jù)實(shí)驗(yàn)要求,將所需的元件庫復(fù)制到原理圖庫文件刽脖,等待調(diào)用羞海,由于元件庫的收集過程中不夠全面,還需要自己繪制元器件曲管,同時(shí)繪制相應(yīng)元件的封裝庫却邓。確定具體的電路后,將相應(yīng)的元件放置到原理圖中院水,在不同的硬件電路之間采用網(wǎng)絡(luò)端口腊徙,使得原理圖看起來更加簡潔。

????考慮到P0口和鍵盤需要上拉電阻檬某,選用8位的排阻連接以作為上拉電阻撬腾;LED用P3口控制;數(shù)碼管驅(qū)動電路中恢恼,74LS573的LE端接+5V民傻。

3.2 PCB制作

????新建PCB文件,導(dǎo)入原理圖场斑,布置元器件的位置后漓踢,進(jìn)行手動布線,要求電源線和地線寬度至少在50mil到100mil之間漏隐,而一般的線寬度為25mil喧半,線與線之間、線與孔之間間距為20mil至30mil青责,不能再IC腳之間過線挺据,防止短路。一般的IC焊盤大小為80×80mil脖隶,電源管腳的焊盤應(yīng)盡量大一些扁耐,鍵盤的焊盤應(yīng)為80×100mil,因?yàn)閁SB口固定位置的兩個(gè)引腳比較大浩村,所以固定位置的兩個(gè)焊盤要設(shè)置為5×5mm做葵。之后在PCB板空的位置進(jìn)行覆銅,并設(shè)置覆銅與線和焊盤的距離至少50mil心墅。

3.3 元器件焊接

????腐蝕電路板前要先將PCB文件打印在轉(zhuǎn)印紙上酿矢,用鉆孔機(jī)在銅板的一角鉆孔榨乎,后將銅板和打印好的紙放入環(huán)保型多功能制板系統(tǒng)影印,完成后取出瘫筐,在剛剛打好的孔間穿上繩子蜜暑,浸泡于用于顯影的溶液幾分鐘,之后用清水清洗策肝,再懸掛于腐蝕液上肛捍,浸泡一段時(shí)間后取出。

??? 將元器件按照原理圖焊接在PCB板后使用萬用表對每一段銅線進(jìn)行檢測之众,以排除不必要的麻煩拙毫。???

?

3.4 程序設(shè)計(jì)

3.4.1 主要程序結(jié)構(gòu)分析

??? 在程序設(shè)計(jì)中要求實(shí)現(xiàn)交通燈功能,在主程序中需要設(shè)置開啟鍵棺禾,為了實(shí)現(xiàn)按鍵功能的更加人性化缀蹄,主程序中設(shè)置了兩個(gè)開啟鍵,分別是白天模式開啟鍵和夜晚模式開啟鍵膘婶,按下相應(yīng)開啟鍵即可進(jìn)入相應(yīng)模式缺前,進(jìn)入到各個(gè)模式的子程序中,期間只要按下停止鍵即可重新返回主函數(shù)悬襟。

??? 而在進(jìn)入白天模式后衅码,鍵盤掃描即進(jìn)入了計(jì)數(shù)值設(shè)置模式階段,期間按下各個(gè)方向通行時(shí)間的設(shè)置鍵即可輸入相關(guān)計(jì)數(shù)值改變倒計(jì)時(shí)時(shí)間脊岳,輸入期間還可在第一個(gè)3位數(shù)碼管上顯示相關(guān)數(shù)值逝段,直至按下數(shù)值確認(rèn)鍵,結(jié)束輸入的同時(shí)返回白天模式割捅,進(jìn)行新一輪的倒計(jì)時(shí)惹恃,同時(shí)完成新一輪的時(shí)序。

(1)鍵盤掃描程序

????在鍵盤掃描子函數(shù)前棺牧,采用while()循環(huán),以實(shí)現(xiàn)對程序的不間斷運(yùn)行朗儒,讓矩陣按鍵的一行輸出低電平艘刚,其它三行輸出高電平林螃,判斷當(dāng)前所有列的狀態(tài),下次中斷時(shí)再讓下一行輸出低電平,其它三行輸出高電平瞬项,再次判斷所有列,通過快速的中斷不停的循環(huán)進(jìn)行判斷望忆,最終確定哪個(gè)按鍵按下了鳄炉,同時(shí)將按鍵的鍵值制作為數(shù)組,根據(jù)行值和列值判斷鍵值烟勋,以輸出Statu值以及Value值以用于各個(gè)程序规求。

????程序中首先對所有的列輸入做了掃描筐付、消抖,然后才切換到了下一次的行輸出阻肿,也就是說中斷每次掃描的實(shí)際是上一次輸出選擇的那行按鍵瓦戚,這樣做是因?yàn)槿魏涡盘枏妮敵龅椒€(wěn)定都需要一個(gè)時(shí)間,有時(shí)它足夠快而有時(shí)卻不夠快丛塌,這里的輸入輸出順序的顛倒就是為了讓輸出信號有足夠的時(shí)間來穩(wěn)定较解,并有足夠的時(shí)間來完成它對輸入的影響

(2)定時(shí)器T0中斷程序

????定時(shí)器 T0中斷程序的主要作用是完成倒計(jì)時(shí)計(jì)數(shù),同時(shí)控制等待時(shí)間中黃燈閃爍功能赴邻。定時(shí)器采用工作模式1印衔,即16位定時(shí)器。通過給定時(shí)器0賦初值的方式可以讓定時(shí)器每隔50ms進(jìn)行一次中斷姥敛,循環(huán)20次完成1S的倒計(jì)時(shí)奸焙,同時(shí)每一次中斷都會判斷一次交通燈的狀態(tài),當(dāng)時(shí)間到達(dá)黃燈等待階段時(shí)徒溪,程序?qū)?zhí)行每半秒對黃燈控制口取反操作忿偷,實(shí)現(xiàn)黃燈閃爍功能。

(3)定時(shí)器T1中斷程序

????定時(shí)器T1中斷程序主要的作用是夜晚模式模式黃燈閃爍功能臊泌。采用的定時(shí)器T1初值與T0相同鲤桥,50ms進(jìn)行一次中斷,在中斷中對黃燈所在I/O口取反渠概,完成黃燈閃爍功能茶凳。在開TO的情況下,另外開啟T1對黃燈實(shí)現(xiàn)閃爍功能播揪,主要是為了排除兩個(gè)模式下黃燈閃爍的相互作用贮喧,充分利用單片機(jī)的閑置資源,同時(shí)讓不同模式下的黃燈閃爍時(shí)間都獨(dú)立可調(diào)猪狈,分離兩種模式箱沦,完全排除聯(lián)系以實(shí)現(xiàn)完全的模塊化。


附錄:源程序

?

#include

?

//--定義使用的IO--//

#defineGPIO_DIG?? P0?????????? //段選

#defineGPIO_PLACE P2????????? //位選

#defineGPIO_KEY P1? ?????????? //矩陣鍵盤

#defineGPIO_TRAFFIC P3

?

sbitRED11?? = P3^2;?????????????? //東西方向

sbitYELLOW11= P3^3;

sbitGREEN11 = P3^4;

?

sbitRED01?? = P3^5;?????????????? //南北方向

sbitYELLOW01= P3^6;

sbitGREEN01 = P3^7;

?

//--定義全局變量--//

unsignedchar code DIG_PLACE[6] = {

0x7f,0xbf,0xdf,0xfb,0xf7,0xef};?????????????????????? ? //位選控制??

unsignedchar code DIG_CODE[17] = {

0xeb,0x88,0xd3,0xda,0xb8,0x7a,0x7b,0xc8,

0xfb,0xfa,0x77,0x7c,0x39,0x5e,0x79,0x71};

//0雇庙、1谓形、23疆前、4寒跳、56竹椒、7童太、89A书释、b翘贮、Cd征冷、E择膝、F的顯示碼

unsignedchar DisplayData[6];???? //用來存放要顯示的8位數(shù)的值

unsigned

char Time,Time1,Time2,Time3,Second;//存放定時(shí)時(shí)間

unsignedchar KeyState;???? ??????? //記錄按鍵的狀態(tài),0沒有检激,1

unsignedchar KeyValue;??????//用來存放讀取到的鍵值

unsignedchar KeyNum;????????????????????????? //用來存放輸入的鍵值

unsignedchar NS_In;?????????????????????? //南北通行時(shí)間

unsignedchar Y_In;??????????????????????????????? //黃燈時(shí)間

unsignedchar EW_In;?????????????? ? ?//東西通行時(shí)間

?

//--聲明全局函數(shù)--//

voidTimer0Cofig(void);???? ???????????????????????? ??//定時(shí)器0

voidTimer1Cofig(void);???? ???????????????????????? ??//定時(shí)器1

voidDelay10ms(unsigned int c);? ?????????? ??//延時(shí)10ms

voidDigDisplay(unsigned int n);???????????????????? ? //動態(tài)顯示函數(shù)

voidSETMODE(unsigned char keyValue);???????????? ? //設(shè)置計(jì)數(shù)值函數(shù)

voidDayLight(void);????????????????????????????????????? ? ???//白天模式

voidNightLight(void);??????????????????????????????????? ? //夜晚模式

unsignedchar KeyDown(void);??????????????? ? //檢測按鍵函數(shù)

unsignedchar KeyInput(void);??????????????? ? //數(shù)值輸入函數(shù)

?

/*********************************************************

* 數(shù) ???????? : main

*函數(shù)功能????????? ?? :主函數(shù)

*??? ???????? : KeyValue

*??? ???????? :

*********************************************************/

voidmain(void)

{?????

?????? NS_In = 120;

?????? EW_In = 80;

?????? Y_In?= 6;????????????????????????????? //初始時(shí)序

?????? Time = 0;?????????????

?????? Time1 = 0;

?????? Second = 1;?????????????????????????????? ??//初始化計(jì)數(shù)值

?

?????? while(1)

?????? {

????????????? KeyDown();? ??????????????????? ???//執(zhí)行按鍵檢測函數(shù)

????????????? switch(KeyValue)

????????????? {

???????????????????? case 10:

??????????????????????????? Timer0Cofig();? ?//開定時(shí)器0

??????????????????????????? DayLight();????????? ??//調(diào)用白天模式

??????????????????????????? KeyValue = 17;

??????????????????????????? break;

???????????????????? case 11:

??????????????????????????? Timer1Cofig();? ?//開定時(shí)器1

??????????????????????????? NightLight(); ?? //調(diào)用夜晚模式

??????????????????????????? KeyValue = 17;

??????????????????????????? break;

???????????????????? default: break;

????????????? }

?????? }

}

?

/*********************************************************

* 數(shù) ???????? :中斷開關(guān)

*函數(shù)功能????????? ?? :打開定時(shí)器T0T1

*??? ???????? :

*??? ???????? :

*********************************************************/

??????

voidTimer0Cofig(void)

{

?????? TMOD = 0x01;????

??? TH0?= 0x3C;?????

??? TL0?= 0xB0; //50ms

??? EA??= 1;???? ????

??? ET0?= 1;???????????

??? TR0?= 1;??????????? ????

}

?

voidTimer1Cofig(void)

{

?????? TMOD = 0x10;????

??? TH1?= 0x3C;?????

??? TL1?= 0xB0; //50ms

?????? EA = 1;

?????? ET1 = 1;

?????? TR1 = 1;

}

?

/*********************************************************

* 數(shù) ???????? :中斷0

*函數(shù)功能????????? ?? :定時(shí)器T0中斷函數(shù)

*??? ???????? :

*??? ???????? : Second

*********************************************************/

?????? ??

voidTimer0() interrupt 1

{

?????? TH0 = 0x3C; ????????????????????????? //設(shè)置初始值

?????? TL0 = 0xB0;

?????? Time++;

?????? if(Time == 20)

?????? {

????????????? Second ++;

????????????? Time = 0;

?????? }??????????????????????????????????????????????? ???? //秒數(shù)計(jì)時(shí)疊加

??????

?????? if((Second < (NS_In + Y_In+1))&&(Second > (NS_In)))

?????? {

????????????? Time2++;

?????????????

????????????? if(Time2 == 10)

????????????? {

???????????????????? YELLOW01 = ~YELLOW01;???

???????????????????? Time2 = 0;

????????????? }

?????? }??????????????????????????????????????????????? ???? //南北方向黃燈閃爍

??????

?????? if(Second > (NS_In + Y_In + EW_In ))

?????? {

????????????? Time3++;

?????????????

????????????? if(Time3 == 10)

????????????? {

???????????????????? YELLOW11 = ~YELLOW11;???????????

???????????????????? Time3 = 0;??????????????????

????????????? }

?????? }??????????????????????????????????????????????? ????? //東西方向黃燈閃爍

}

?

/*********************************************************

* 數(shù) ???????? :中斷1

*函數(shù)功能????????? ?? :定時(shí)器T1中斷函數(shù)

*??? ???????? :

*??? ???????? :

*********************************************************/

voidTimer1() interrupt 3

{

?????? TH1 = 0x3C; ????????????????????????? //設(shè)置初始值

?????? TL1 = 0xB0;

?????? Time1++;

??????

?????? if(Time1 == 10)

?????? {

????????????? YELLOW01 = ~YELLOW01;??? //黃燈雙閃

?????? ???YELLOW11 = ~YELLOW11;???????????

????????????? Time1 = 0;

?????? }

}

?

/*********************************************************

* 數(shù) ???????? :計(jì)數(shù)值設(shè)置函數(shù)

*函數(shù)功能????????? ?? :改變計(jì)數(shù)值

*??? ???????? : KeyValue

*??? ???????? : NS_In,EW_In,Y_In

*********************************************************/

?

voidSETMODE(unsigned char KeyValue)

{

?????? GPIO_TRAFFIC = 0x00;

?????? GPIO_PLACE?? = 0xFF;????????????????????????????? //關(guān)閉交通燈肴捉,數(shù)碼管

?

?????? switch(KeyValue)?????????????????????????????????????????????????? //依照按下的鍵對應(yīng)修改時(shí)間

????????????? {

???????????????????? case 12:

????????????? ????????????? KeyInput();NS_In= KeyNum ;?????? //南北通行時(shí)間輸入

??????????????????????????? break;

???????????????????? case 13:

??????????????????????????? KeyInput();EW_In =KeyNum - Y_In ;//東西通行時(shí)間

??????????????????????????? break;?

???????????????????? case 15:

????????????? ????????????? KeyInput();Y_In? = KeyNum ;?????? //黃燈閃爍時(shí)間輸入

??????????????????????????? break;

???????????????????? default: break;

????????????? }

?????? Second = 1;

?????? EA = 1;

}

?

/*********************************************************

* 數(shù) ???????? : DayLight

*函數(shù)功能????????? ?? :白天

*??? ???????? :

*??? ???????? :

*********************************************************/

?

voidDayLight(void)

{

?????? unsigned int a;

?????? a = 1;

??????

?????? while(a)

?????? {

????????????? KeyDown();

????????????? if(KeyValue == 11)??????????????????????????????????????????????????????? //清零并停止計(jì)時(shí)

????????????? {

???????????????????? a = 0;

???????????????????? ET0 = 0;

???????????????????? Second = 0;

???????????????????? GPIO_TRAFFIC = 0xff;

????????????? }

????????????? if(Second == NS_In + EW_In + 2 *Y_In) //結(jié)束一個(gè)周期

????????????? {

???????????????????? Second = 1;

????????????? }

?

????????????? if((KeyValue == 12)||(KeyValue==13)||(KeyValue ==15))

????????????? {

???????????????????? EA=0;

???????????????????? SETMODE(KeyValue);

????????????? }

????????????? //--南北方向通行--//

????????????? if(Second < (NS_In + 1))

????????????? {

???????????????????? DisplayData[0] =DIG_CODE[(NS_In - Second) % 1000 / 100];

???????????????????? DisplayData[1] =DIG_CODE[(NS_In - Second) % 100 / 10];

???????????????????? DisplayData[2] =DIG_CODE[(NS_In - Second) % 10];

???????????????????? DisplayData[3] =DIG_CODE[(NS_In + Y_In - Second) % 1000 / 100];

???????????????????? DisplayData[4] =DIG_CODE[(NS_In + Y_In - Second) % 100 / 10];

???????????????????? DisplayData[5] =DIG_CODE[(NS_In + Y_In - Second) % 10];

???????????????????? DigDisplay(6);???????????????????????????????????????????????????????????????????? //第一個(gè)時(shí)序倒計(jì)時(shí)

?

???????????????????? GPIO_TRAFFIC = 0x7B;

????????????????????

???????????????????? Time2 = 0;

????????????? }

?

????????????? //--黃燈等待切換狀態(tài)--//

????????????? else if(Second < (NS_In + Y_In+1))

????????????? {

???????????????????? DisplayData[0] =DIG_CODE[(NS_In + Y_In - Second) % 1000 / 100];

???????????????????? DisplayData[1] =DIG_CODE[(NS_In + Y_In - Second) % 100 / 10];

???????????????????? DisplayData[2] =DIG_CODE[(NS_In + Y_In - Second) % 10];

???????????????????? DisplayData[3] =DisplayData[0];

???????????????????? DisplayData[4] =DisplayData[1];

???????????????????? DisplayData[5] =DisplayData[2];

???????????????????? DigDisplay(6);???????????????????????????????????????????????????????????????????? //第二個(gè)時(shí)序倒計(jì)時(shí)

????????????????????

???????????????????? GREEN01 = 1;

????????????????????

????????????? ?????? RED11= 0;?????? ???????????????????????????????????????????????????????????? //東西方向紅燈持續(xù)?

????????????????????

????????????? }

?

????????????? //--東西方向通行--//

????????????? else if(Second < (NS_In + Y_In+ EW_In +1) )

????????????? {

???????????????????? DisplayData[0] =DIG_CODE[(NS_In + Y_In + EW_In - Second) % 1000 / 100];

???????????????????? DisplayData[1] =DIG_CODE[(NS_In + Y_In + EW_In - Second) % 100 / 10];

???????????????????? DisplayData[2] =DIG_CODE[(NS_In + Y_In + EW_In - Second) % 10];

???????????????????? DisplayData[3] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 1000 / 100];

???????????????????? DisplayData[4] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 100 / 10];

???????????????????? DisplayData[5] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 10];

???????????????????? DigDisplay(6);???????????????????????????????????????????????????????????????????? //第三個(gè)時(shí)序倒計(jì)時(shí)

?

???????????????????? GPIO_TRAFFIC = 0xCF;

????????????????????

???????????????????? Time2 = 0;

????????????? }

?

????????????? //--黃燈等待切換狀態(tài)--//

????????????? else

????????????? {

???????????????????? DisplayData[0] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 1000 / 100];

???????????????????? DisplayData[1] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 100 / 10];

???????????????????? DisplayData[2] =DIG_CODE[(NS_In + EW_In + 2 * Y_In - Second) % 10];

???????????????????? DisplayData[3] =DisplayData[0];

???????????????????? DisplayData[4] =DisplayData[1];

???????????????????? DisplayData[5] =DisplayData[2];

?????? ????????????? DigDisplay(6);???????????????????????????????????????????????????????????????????? //第四個(gè)時(shí)序倒計(jì)時(shí)

?

???????????????????? GREEN11 = 1;

????????????????????

???????????????????? RED01 = 0;??????? ?????????????????????????????????????????????????????????? //南北方向紅燈亮

????????????? }

?????? }

}

?

/*****************************************************************************

* 數(shù) ???????? : NightLight

*函數(shù)功能????????? ?? :夜晚

*??? ???????? :

*??? ???????? :

*****************************************************************************/

?

voidNightLight(void)

{

?????? unsigned int a;

?????? a = 1;

?????? GPIO_TRAFFIC = 0xB7;

??????

?????? while(a)

?????? {

????????????? KeyDown();

????????????? if(KeyValue == 10)

????????????? {

???????????????????? a = 0;

???????????????????? ET1 = 0;

????????????? }

?????? }

?????? Time1 = 0;

}

?

/*****************************************************************************

* 數(shù) ???????? : DigDisplay

*函數(shù)功能????????? ?? :使用數(shù)碼管顯示

*??? ???????? :

*??? ???????? :

*****************************************************************************/

?

voidDigDisplay(unsigned int n)

{

?????? unsigned char i;

?????? unsigned int j;

??????

?????? for(i=0; i< n; i++)

?????? {

????????????? GPIO_PLACE = DIG_PLACE[i];???? ?? //發(fā)送位選

????????????? GPIO_DIG = DisplayData[i];???? //發(fā)送段碼

????????????? j = 10;?????????????????????????????????????? ?? //掃描間隔時(shí)間設(shè)定

????????????? while(j--);?????

????????????? GPIO_DIG = 0x00;?????????? ????//消隱

?????? }

}

?

/*****************************************************************************

* 數(shù) ???????? : Delay10ms

*函數(shù)功能????????? ?? :延時(shí)函數(shù),延時(shí)10ms

*??? ???????? :

*??? ???????? :

*****************************************************************************/

?

voidDelay10ms(unsigned int c)?? //誤差0us

{

??? unsigned char a, b;

?

??? for (;c>0;c--)

?????? {

????????????? for (b=4;b>0;b--)

????????????? {

???????????????????? for (a=130;a>0;a--);

????????????? }

??????????

?????? }

???????

}

?

/*****************************************************************************

* 數(shù) ???????? : KeyDown

*函數(shù)功能????????? ?? :檢測有按鍵按下并讀取鍵值

*??? ???????? :

*??? ???????? :

*****************************************************************************/

?

unsignedchar KeyDown(void)

{

??? GPIO_KEY = 0xfe;

?

??? while((GPIO_KEY & 0xf0) != 0xf0)???????

??? {

??????? Delay10ms(1);???????????????????

??????? while((GPIO_KEY & 0xf0) !=0xf0)???

??????? {

???????????????????? KeyState=1;

??????????? switch(GPIO_KEY)???????????????

??????????? {

??????????????????????????? case 0xbe:KeyValue=0;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xee:KeyValue=13;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0x7e:KeyValue=14;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xde:KeyValue=15;

????????????????????????????????????????? ?? break;

??????????? }

???????????????????? while((GPIO_KEY & 0xf0)!= 0xf0)

??????????????????????????? ;

??????? }

??? }

??????

?????? GPIO_KEY = 0xfd;???

?

??? while((GPIO_KEY & 0xf0) != 0xf0)

??? {

????????????? Delay10ms(1);???????????????????

??????? while((GPIO_KEY & 0xf0) != 0xf0)

??????? {

???????????????????? KeyState=1;

???????????????????? switch(GPIO_KEY)???????

??????????? {

??????????????? case 0x7d: KeyValue=7;

????????????????????????????????????????? ?? break;?

??????????????????????????? case 0xbd: KeyValue=8;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xdd:KeyValue=9;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xed:KeyValue=12;

????????????????????????????????????????? ?? break;

??????????? }

???????????????????? while((GPIO_KEY & 0xf0)!= 0xf0)

??????????????????????????? ;

??????? }

??? }

?

??? GPIO_KEY = 0xfb;

?

??? while((GPIO_KEY & 0xf0) != 0xf0)

??? {

????????????? Delay10ms(1);???????????????????

??????? while((GPIO_KEY & 0xf0) != 0xf0)

??????? {

???????????????????? KeyState=1;

???????????????????? switch(GPIO_KEY)?

???????????????????? {

??????????????????????????? case 0x7b:KeyValue=4;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xbb:KeyValue=5;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xdb:KeyValue=6;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xeb:KeyValue=11;

????????????????????????????????????????? ?? break;

??????????? }

???????????????????? while((GPIO_KEY & 0xf0)!= 0xf0)

??????????????????????????? ;

??????? }

??? }

?

??? GPIO_KEY = 0xf7;

?

??? while((GPIO_KEY & 0xf0) != 0xf0)

??? {

????????????? Delay10ms(1);???????????????????

??????? while((GPIO_KEY & 0xf0) != 0xf0)

??????? {

???????????????????? KeyState=1;

???????????????????? switch(GPIO_KEY)?

??????????? {

??????????????? case 0x77: KeyValue=1;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xb7:KeyValue=2;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xd7:KeyValue=3;

????????????????????????????????????????? ?? break;

??????????????????????????? case 0xe7:KeyValue=10;

??????????????????????????? ????????????? ??break;

??????????? }

???????????????????? while((GPIO_KEY & 0xf0)!= 0xf0)

??????????????????????????? ;

??????? }

??? }

??? return KeyValue;

?

}

?

/*****************************************************************************

* 數(shù) ???????? : KeyInput

*函數(shù)功能????????? ?? :使用鍵盤輸入數(shù)值

*??? ???????? :

*??? ???????? :

*****************************************************************************/

?

unsignedchar KeyInput(void)

{

?????? unsigned int Ge,Shi,Bai,a;

?????? KeyNum = 0;

?????? Ge?= 0;

?????? Shi = 0;

?????? Bai = 0;

?????? a=1;

??????

?????? while(a)

?????? {

????????????? KeyDown();

????????????? if(KeyValue < 10 &&KeyState == 1)

????????????? {

???????????????????? Bai = Shi;

???????????????????? Shi = Ge;

???????????????????? Ge? = KeyValue;

????????????????????

???????????????????? KeyState = 0;

????????????? }????????????????????????????????????????????????????????????? //移位顯示

?????????????

????????????? DisplayData[0] = DIG_CODE[Bai];

????????????? DisplayData[1] = DIG_CODE[Shi];

????????????? DisplayData[2] = DIG_CODE[Ge];

????????????? DigDisplay(3);

?????????????

????????????? if(KeyValue == 14)

????????????? {

???????????????????? a = 0;

???????????????????? KeyNum = 100 * Bai + 10 *Shi + Ge;?????

????????????? }?????????????????????????????????????????????????????? ?? //數(shù)據(jù)確認(rèn)鍵

?????? }

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叔收,一起剝皮案震驚了整個(gè)濱河市齿穗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺律,老刑警劉巖窃页,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異复濒,居然都是意外死亡脖卖,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門巧颈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畦木,“玉大人,你說我怎么就攤上這事砸泛∈” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵唇礁,是天一觀的道長勾栗。 經(jīng)常有香客問我,道長盏筐,這世上最難降的妖魔是什么围俘? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮琢融,結(jié)果婚禮上楷拳,老公的妹妹穿的比我還像新娘。我一直安慰自己吏奸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布陶耍。 她就那樣靜靜地躺著奋蔚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泊碑,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天坤按,我揣著相機(jī)與錄音,去河邊找鬼馒过。 笑死臭脓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腹忽。 我是一名探鬼主播来累,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼窘奏!你這毒婦竟也來了嘹锁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤着裹,失蹤者是張志新(化名)和其女友劉穎领猾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骇扇,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摔竿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了少孝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片继低。...
    茶點(diǎn)故事閱讀 39,727評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖韭山,靈堂內(nèi)的尸體忽然破棺而出郁季,到底是詐尸還是另有隱情,我是刑警寧澤钱磅,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布梦裂,位于F島的核電站,受9級特大地震影響盖淡,放射性物質(zhì)發(fā)生泄漏年柠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一褪迟、第九天 我趴在偏房一處隱蔽的房頂上張望冗恨。 院中可真熱鬧,春花似錦味赃、人聲如沸掀抹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽傲武。三九已至蓉驹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揪利,已是汗流浹背态兴。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疟位,地道東北人瞻润。 一個(gè)月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像甜刻,于是被迫代替她去往敵國和親绍撞。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容