這是我花了一段時間寫出來的基于單片機的十字路口紅綠燈,下面的附件包含了源代碼,仿真圖,還有生成的hex文件。
功能如下
功能1:紅燈和綠燈相互轉換時經過黃燈,黃燈閃爍三次(6秒)
利用延時函數實現黃燈閃爍;紅綠黃LED燈接地,用P1口連接LED燈,置P1低電平點亮,置高電平熄滅.
基本功能:輸入輸出,延時函數
外接元件:紅綠黃LED燈
外接元件功能:有熄滅和點亮兩種狀態.
功能2:主干道方向通行30秒,輔干道方向通行20秒,單獨左轉信號15秒;先直行信號,后左轉信號。
讓連接直行綠燈的P1口置低電平和用定時器中斷計時30s,再讓連接左轉綠燈的P1口置低電平和用定時器中斷計時15秒.
基本功能:輸入輸出,定時器中斷
外接元件:LED燈;LED數碼管
外接元件功能:連接電路和斷開電路;可以顯示時間
功能3:設手動、自動、特殊情況三種方式。
通過按鍵來實現三種情況的實現
P3口各連接一個開關后接地,作為手動檔和自動檔、特殊情況檔.使開關置0就能選擇自己想要的一種方式
基本功能:輸入輸出
外接元件:按鈕
外接元件功能:連接電路和斷開電路
功能4:特殊情況時所有路口紅燈都亮,給120、110等通行。
LED燈接地,四個路口12個LED燈都接P1口
使P1口全部置1,LED燈熄滅
再使連接紅燈的P1口置0
基本功能:輸入輸出
外接元件:LED燈
外接元件功能:熄滅和點亮兩種情況
功能5:自動時顯示各種狀態倒計時。
通過定時器中斷和LED數碼管的顯示來實現各種狀態的倒計時.
基本功能:定時器中斷
外接元件:LED數碼管
外接元件功能:可以顯示時間
功能6:夜間模式
(夜間的時候,四個路口一直亮黃燈)
類似于特殊情況,使P1=0x77,即可實現
基本功能:輸入輸出
外接元件:LED燈
外接元件功能:點亮和熄滅兩種狀態
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.gif (202.64 KB, 下載次數: 77)
下載附件
2022-6-3 05:16 上傳
紅綠燈.png (243.14 KB, 下載次數: 55)
下載附件
2022-5-30 13:07 上傳
單片機源程序如下(程序有詳細注釋):
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit wela = P2^7; // 數碼管位選
- sbit dula = P2^6; // 數碼管段選
- // 下面是八個交通燈對應的位定義
- sbit LED1_blue = P1^0;
- sbit LED1_red = P1^1;
- sbit LED1_green = P1^2;
- sbit LED1_yellow = P1^3;
- sbit LED2_blue = P1^4;
- sbit LED2_red = P1^5;
- sbit LED2_green = P1^6;
- sbit LED2_yellow = P1^7;
- // 按鍵位定義
- sbit key_auto = P3^0; // 自動
- sbit key_step = P3^1; // 手動
- sbit key_emerg = P3^2; // 緊急情況 110/120通過
- sbit key_night = P3^6;// 夜間模式
- uint cnt = 0; // 記錄定時器定時了多少毫秒
- uint sec = 0; // 記錄定時器計時了多少秒
- uchar light_num = 0;
- // 四位八段共陰極數碼管數字顯示編碼
- 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,
- 0xdf, 0xee, 0xdd
- };
- /*************函數聲明********************/
- void delay_ms(uint);
- void system_Init();
- void Display_R_time(uchar);
- void Display_C_time(uchar);
- void key_scan();
- void main()
- {
- system_Init();
- while(1)
- {
- key_scan();
- }
- }
- // 毫秒級延時
- void delay_ms(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=123;y>0;y--);
- }
- // 系統初始化
- void system_Init()
- {
- wela=0; // 關閉位選
- dula=0; // 關閉段選
- TMOD=0x01; // 定時器0方式1 16位
- TH0=0x4c; // 定時器裝初值 50ms(11.05926MHz TH0=0x4c TL0=0x00)
- TL0=0x00; // (12MHz 的初值是 TH0=0x3c TL0=0xb0)
- EA=1; // 開總中斷
- ET0=1; // 開定時器0中斷
- TR0=1; // 允許中斷溢出
- }
- // 顯示橫向的(即輔干道)倒計時
- void Display_R_time(uchar time)
- {
- uchar time_tens, time_ones;
- time_tens = time / 10; // 提取倒計時時間的十位數
- time_ones = time % 10; // 提取倒計時時間的個位數
- // 下面對兩位數倒計時時間進行顯示(數碼管)
- P0=0xff;
- wela=1;
- P0=0xbf;
- wela=0;
- dula=1;
- P0=table[time_tens];
- dula=0;
- delay_ms(1);
-
- P0=0xff;
- wela=1;
- P0=0x7f;
- wela=0;
- dula=1;
- P0=table[time_ones];
- dula=0;
- delay_ms(1);
- }
- // 顯示豎向的(即主干道)倒計時
- void Display_C_time(uchar time)
- {
- uchar time_tens, time_ones;
- time_tens = time / 10;
- time_ones = time % 10;
-
- P0=0xff;
- wela=1;
- P0=0xfb;
- wela=0;
- dula=1;
- P0=table[time_tens];
- dula=0;
- delay_ms(1);
- P0=0xff;
- wela=1;
- P0=0xf7;
- wela=0;
- dula=1;
- P0=table[time_ones];
- dula=0;
- delay_ms(1);
- }
- void key_scan()
- {
- if(key_auto == 0)
- {
- delay_ms(5);
- if(key_auto == 0) // 自動按鈕按下
- {
- // 主干道通過 輔干道紅燈
- if(sec <= 15)
- {
- Display_C_time(15-sec); // 倒計時顯示
- Display_R_time(30-sec);
- P1 = light[0]; // 主道綠燈亮 輔道紅燈亮
- }
- else if(sec > 15 && sec <= 24)
- {
- Display_C_time(24-sec); // 倒計時顯示
- Display_R_time(30-sec);
- P1 = light[1]; // 主道藍燈亮 單獨左轉 輔道紅燈亮
- }
- else if(sec > 24 && sec <= 30)
- {
- Display_C_time(30-sec); // 倒計時顯示
- Display_R_time(30-sec);
- P1 = light[2]; // 主道黃燈亮 輔道紅燈亮
- }
-
- // 下面換道
- else if(sec > 30 && sec <= 35)
- {
- Display_R_time(35-sec); // 倒計時顯示
- Display_C_time(50-sec);
- P1 = light[3]; // 主道紅燈亮 輔道綠燈亮
- }
- else if(sec > 35 && sec <= 44)
- {
- Display_R_time(44-sec); // 倒計時顯示
- Display_C_time(50-sec);
- P1 = light[4]; // 主道紅燈亮 輔道藍燈亮 單獨左轉信號
- }
- else if(sec > 44 && sec <= 50)
- {
- Display_R_time(50-sec); // 倒計時顯示
- Display_C_time(50-sec);
- P1 = light[5]; // 主道紅燈亮 輔道黃燈亮
- }
-
- else
- {
- sec = 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); // 松手檢測
- }
- }
- // 緊急情況 emergency
- if(key_emerg == 0)
- {
- delay_ms(5);
- if(key_emerg == 0)
- {
- P1 = 0xdd; // 主干道輔干道都是紅燈
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
Keil代碼與Proteus8.8仿真下載:
基于單片機的十字路口紅綠燈控制器.7z
(347.29 KB, 下載次數: 76)
2022-6-3 05:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|