51單片機電子制作DIY-----交通燈控制器


作者:李剴

出處:https://blog.csdn.net/Kevin_8_Lee

或者  https://www.cnblogs.com/kevin-nancy/

歡迎轉載,但也請保留上面這段聲明。謝謝!(上面兩個都是我的博客,只是在不同平台)

 

首先說一下背景吧 :

最近在幫別人做一些小東西,是用51做的,主要給他們提供單片機課設的思路。 且由於時間問題,我也沒有將程序進行優化,只是拿來分享一下,大家可以參考。 有思路之后可以稍微花點時間去優化一下代碼,是代碼更簡潔。

馬丁·福勒 的一句名言與君共勉:

任何一個傻瓜都會寫能夠讓機器理解的代碼,只有好的程序員才能寫出人類可以理解的代碼。—Martin Fowler

 

ok, 廢話不多說,下面是設計要求及制作過程,proteus仿真以及代碼流程的介紹

 

1)  題目及設計要求

題目: 交通燈控制器

要求:

 

1、紅燈和綠燈相互轉換時經過黃燈,黃燈閃爍三次(6秒);

 

2、主干道方向通行30秒,輔干道方向通行20秒,單獨左轉信號15秒;先直行信號,后左轉信號。

 

3、設手動、自動、特殊情況三種方式。

 

4、特殊情況時所有路口紅燈都亮,給120、110等通行。

 

5、自動時顯示各種狀態倒計時。

 

 

2)C51編程以及電路仿真軟件

編程:

 51單片機的C語言編程一般都是keil3或者keil4,我一直以來用的keil3,這次使用的keil4,其實都一樣的。

 

注:關於keil3/4/5的資料和安裝破解教程,在我的另一篇博客講過了,可以參考一下  點擊藍字-->> keil3/4/5安裝破解教(附百度雲資源)

 

 

keil4打開的界面如下:

 

 

(PS:: 不過這次做這些東西的過程中,keil4經常自己卡死,害得我只能任務管理器關閉它,超級煩,不知道什么原因,有了解的可以評論一下告訴我,感激不盡 .............但是老版本的keil3卻很穩定)

 

仿真

proteus仿真軟件

我用的7版本的

 

 

proteus打開界如下:

 

 

這個界面里面的電路圖與這個交通燈無關,是我以前做的一個,只是給大家演示

 

 

3)解決思路

硬件部分:

交通燈顯示部分分為6個部分

  • [ 1] 首先:主干道通行30秒 其中單獨左轉15秒 黃燈6秒

1)主干道--------綠燈 輔干道--------紅燈 0-15s // 單獨直行

2)主干道--------藍燈 輔干道--------紅燈 15-24s // 單獨左轉

3)主干道--------黃燈 輔干道--------紅燈 24-30s // 黃燈減速


  • [ 2] 輔干道通行20秒 單獨左轉15秒 黃燈6秒

4)主干道--------紅燈 輔干道--------綠燈 0-5s

5)主干道--------紅燈 輔干道--------藍燈 5-14s

6)主干道--------紅燈 輔干道--------黃燈 14-20s


 

 

模擬交通的燈的幾個led燈的顯示在程序中就是按照上面的流程顯示的,由 1)—>2)—>…—>6)—>1)->… 一直循環

 

仿真電路圖各個部分展示:

(1)單片機 & 復位電路 & 晶振

 

(2)交通燈部分

 

上圖標注了每個燈對應的引腳 以及每個燈的顏色

分別在上面和右面放置了一排 用來表示道路的方向

D1-D4指示的是主干道         D5-D8指示的是輔干道

 

(3)數碼管顯示部分

這部分是和交通燈部分一起的  為了方便看到我寫的標注,我把交通燈抹去了,抹去的部分就是上面交通燈的部分

 

 

 

 

(該芯片使用方法這里不多說,網上很多資料。。。本質就是一個鎖存器)

 

軟件部分

 

首先代碼流程圖如下,對這個畫圖軟件不是很熟,畫的很垃圾,不過大致能體現出來

 

4)部分代碼展示及解釋

# include <reg52.h> # define uchar unsigned char # define uint  unsigned int sbit wela = P2^7;          // 數碼管位選
sbit dula = P2^6;        // 數碼管段選

 

// 按鍵位定義
sbit    key_auto     = P3^0;    // 自動
sbit    key_step     = P3^1;    // 手動
sbit    key_emerg     = P3^2;    // 緊急情況 110/120通過

 

// 四位八段共陽極數碼管數字顯示編碼
uchar code table[]={ //"0" "1" "2" "3"
0x3f,0x06,0x5b,0x4f, //"4" "5" "6" "7"
0x66,0x6d,0x7d,0x07, //"8" "9" "A" "B"
0x7f,0x6f,0x77,0x7c, //"C" "D" "E" "F"
0x39,0x5e,0x79,0x71 };

 

// 交通燈編碼 自動模式時,交通燈亮燈順序 我編成了一個數組,方便使用
 uchar code light[]={ // 主G輔R 主G輔R 主Y輔R
    0xdb,       0xde,     0xd7, // 主R輔G 主R輔B 主R輔R
    0xbd,       0xed,     0x7d, };

 

// 定時器0中斷服務函數 用於計算時間過了幾秒
void timer0() interrupt 1 { TH0=0x4c;        // 定時器裝初值 50ms(11.05926MHz TH0=0x4c TL0=0x00) 
    TL0=0x00;        // (12MHz 的初值是 TH0=0x3c TL0=0xb0)
    cnt++; if(cnt == 20) { cnt = 0; sec++;      // 記錄1秒
 } }

 

// 按鍵掃描函數
void key_scan() { //判斷那個按鍵盤下
    
    /********************** 自動模式 *********************/
    ///如果是自動模式,就讓交通燈正常運行 並顯示倒計時
    // Display_C_time(15-sec); // 主干道倒計時顯示 // Display_R_time(30-sec); // 輔干道倒計時顯示 // P1 = light[0]; // 交通燈編碼顯示 // 具體代碼省略、、、、、、、、、、
    
     /********************** 手動模式 *********************/
    //手動模式就讓交通等步進變換
    if(key_step == 0) { delay_ms(5); if(key_step == 0) { if(light_num == 6) { light_num = 0; } P1 = light[light_num]; light_num++; while(!key_step);  // 松手檢測
 } } /********************** 緊急模式 *********************/
    // 緊急模式 用於120/110緊急通行 // 讓主干道和輔干道都是紅燈即可 // 具體代碼省略、、、、、、、、、、、
 }

 

// 最后在主函數里面初始化   然后循環掃描按鍵

void main() { system_Init(); // 系統初始化 里面是對定時器中斷以及數碼管進行初始化

    while(1) { key_scan(); } }

 

5)整體效果演示

 

因為這個是幫別人設計的,所以完整源碼和仿真工程文件不貼出。         如果需要完整的仿真以及源碼,請私聊我或者評論留下聯系方式

今天所有的懶惰都會換來明天的卑微            加油吧!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM