做者:李剴
出處:https://blog.csdn.net/Kevin_8_Lee
或者 https://www.cnblogs.com/kevin-nancy/
歡迎轉載,但也請保留上面這段聲明。謝謝!(上面兩個都是個人博客,只是在不一樣平臺)
首先說一下背景吧 :html
最近在幫別人作一些小東西,是用51作的,主要給他們提供單片機課設的思路。 且因爲時間問題,我也沒有將程序進行優化,只是拿來分享一下,你們能夠參考。 有思路以後能夠稍微花點時間去優化一下代碼,是代碼更簡潔。程序員
馬丁·福勒 的一句名言與君共勉:編程
任何一個傻瓜都會寫可以讓機器理解的代碼,只有好的程序員才能寫出人類能夠理解的代碼。—Martin Fowler數組
ok, 廢話很少說,下面是設計要求及製做過程,proteus仿真以及代碼流程的介紹函數
題目: 交通燈控制器優化
要求:ui
一、紅燈和綠燈相互轉換時通過黃燈,黃燈閃爍三次(6秒);編碼
二、主幹道方向通行30秒,輔幹道方向通行20秒,單獨左轉信號15秒;先直行信號,後左轉信號。spa
三、設手動、自動、特殊狀況三種方式。.net
四、特殊狀況時全部路口紅燈都亮,給120、110等通行。
五、自動時顯示各類狀態倒計時。
編程:
51單片機的C語言編程通常都是keil3或者keil4,我一直以來用的keil3,此次使用的keil4,其實都同樣的。
注:關於keil3/4/5的資料和安裝破解教程,在個人另外一篇博客講過了,能夠參考一下 點擊藍字-->> keil3/4/5安裝破解教(附百度雲資源)
keil4打開的界面以下:
(PS:: 不過此次作這些東西的過程當中,keil4常常本身卡死,害得我只能任務管理器關閉它,超級煩,不知道什麼緣由,有了解的能夠評論一下告訴我,感激涕零 .............可是老版本的keil3卻很穩定)
仿真
proteus仿真軟件
我用的7版本的
proteus打開界以下:
這個界面裏面的電路圖與這個交通燈無關,是我之前作的一個,只是給你們演示
模擬交通的燈的幾個led燈的顯示在程序中就是按照上面的流程顯示的,由 1)—>2)—>…—>6)—>1)->… 一直循環
上圖標註了每一個燈對應的引腳 以及每一個燈的顏色
分別在上面和右面放置了一排 用來表示道路的方向
D1-D4指示的是主幹道 D5-D8指示的是輔幹道
這部分是和交通燈部分一塊兒的 爲了方便看到我寫的標註,我把交通燈抹去了,抹去的部分就是上面交通燈的部分
(該芯片使用方法這裏很少說,網上不少資料。。。本質就是一個鎖存器)
首先代碼流程圖以下,對這個畫圖軟件不是很熟,畫的很垃圾,不過大體能體現出來
# 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(); } }
由於這個是幫別人設計的,因此完整源碼和仿真工程文件不貼出。 若是須要完整的仿真以及源碼,請私聊我或者評論留下聯繫方式
今天全部的懶惰都會換來明天的卑微 加油吧!!!