1.設計目的- 學習AT89C51的原理及應用
- 了解使用單片機處理復雜邏輯的方法
2.設計任務 本系統的軟件設計主要分為四大模塊:定時模塊、倒計時顯示、紅綠燈顯示、按鍵輸入。定時模塊通過定時器T0在模式1下,完成1秒的定時功能,每1秒時間到,將會對通行時間進行倒計時。顯示模塊采用動態顯示的方式,段選碼從P2端口輸出,位選碼從P1端口輸出。紅綠燈顯示采用單片機IO端口直接驅動,當IO端口輸出低電平時,相應的發光二極管發光;當IO端口輸出高電平時,相應的發光二極管熄滅。按鍵輸入,主要完成“東西通行”、“南北通行”、“禁止通行”三個功能,每次按鍵輸入的時候,會對按鍵進行軟件消抖,從而保證按鍵的準確輸入。 基本要求 a顯示電路采用七段共陰極數碼管顯示,南北方向的數碼管的段選端分別與P2端口的P2.0~P2.7相連,位選端分別與P1.2和P1.3相連;東西方向的數碼管的段選端也與P2端口的P2.0~P2.7相連,位選端分別與P1.0和P1.1相連 b. 實現這三個功能:東西通行、南北通行、禁止通行。
在以上設計基礎上,在單片機的P1.0-P1.3口分別接入4個按鍵:
- 東西方向和南北方向的通行時間輸入和輸入時間的顯示
- 在綠燈亮起時,添加聲音提示行人通行。
3.設計原理圖
4.數字鐘程序流程圖 
圖9.3 智能交通燈控制主程序流程圖 
代碼:
- #include <reg51.h> //包含MCS-51單片機頭文件
- #define uchar unsigned char //定義宏uchar
- #define uint unsigned int //定義宏uint
- sbit P1_0 =P1^0; //定義單片機IO口P1.0
- sbit P1_1 =P1^1; //定義單片機IO口P1.1
- sbit P1_2 =P1^2; //定義單片機IO口P1.2
- sbit P1_3 =P1^3; //定義單片機IO口P1.3
- sbit ew_red=P0^0; //定義單片機IO口P0.0為東西方向紅燈控制位
- sbit ew_yellow=P0^1; //定義單片機IO口P0.1為東西方向黃燈控制位
- sbit ew_green=P0^2; //定義單片機IO口P0.2為東西方向綠燈控制位
- sbit sn_red=P0^3; //定義單片機IO口P0.3為南北方向紅燈控制位
- sbit sn_yellow=P0^4; //定義單片機IO口P0.4為南北方黃燈控制位
- sbit sn_green=P0^5; //定義單片機IO口P0.5為南北方向綠燈控制位
- sbit key_earth_west=P3^2; //定義單片機IO口P3.2東西方向通行控制按鍵
- sbit key_sourth_north= P3^3; //定義單片機IO口P3.3南北方向通行控制按鍵
- sbit all_not=P3^4; //定義單片機IO口P3.4為全部禁行控制位
- sbit key_earth_west_add=P3^0; //定義單片機IO口P3.0為東西加
- sbit key_earth_west_jian= P3^1; // 定義單片機IO口P3.1為東西減
- sbit key_sourth_north_add=P3^5; // 定義單片機IO口P3.5為南北加
- sbit key_sourth_north_jian= P3^6; // 定義單片機IO口P3.6為南北減
- uchar code s7_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- //七段碼顯示表
- uchar a,b,c,d; //定義東西南北時間
- uchar sou_nor_time; //南北通行時間變量定義
- uchar east_weat_time; //東西通行時間變量定義
- uchar time_flag; //時間標志位定義
- uchar traffic_flag; //traffic_flag=0時南北通行,traffic_flag=1時東西通行
- uchar time_multiply; //定義計時變量
- void delayms(uchar z) //延時子程序
- {
- uchar i,j; //定義變量i,j
- for(i=z;i>0;i--) //for循環,共循環z次
- for(j=110;j>0;j--); //for循環,共循環j次
- }
- void display_time( ) //顯示倒計時子程序
- {
- P1_0 =0; //P1.0輸出低電平,位選使能
- P1_1 =1; //P1.1輸出高電平
- P1_2 =1; //P1.2輸出高電平
- P1_3 =1; //P1.3輸出高電平
- P2=s7_table[a/10]; //P2端口輸出顯示的段碼
- delayms(2); //延時2毫秒
- P2=0; //P2端口輸出低電平
- P1_0 =1; //P1.0輸出高電平
-
- P1_1 =0; //P1.1輸出低電平,位選使能
- P2=s7_table[b%10]; //P2端口輸出顯示的段碼
- delayms(2); //延時2毫秒
- P2=0; //P2端口輸出低電平
- P1_1 =1; //P1.1輸出高電平
-
- P1_2 =0; //P1.2輸出低電平,位選使能
- P2=s7_table[(c)/10]; //P2端口輸出顯示的段碼
- delayms(2); //延時2毫秒
- P2=0; //P2端口輸出低電平
- P1_2 =1; //P1.2輸出高電平
-
- P1_3 =0; //P1.3輸出低電平,位選使能
- P2=s7_table[(d)%10]; //P2端口輸出顯示的段碼
- delayms(2); //延時2毫秒
- P2=0; //P2端口輸出低電平
- P1_3 =1; //P1.3輸出高電平
- }
- void south_north_allow() //南北通行允許子程序
- {
- ew_red=0; //東西方向紅燈亮
- ew_green=1; //東西方向綠燈熄滅
- ew_yellow=1; //東西方向黃燈熄滅
-
- sn_red=1; //南北方向紅燈熄滅
- sn_green=0; //南北方向綠燈亮
- sn_yellow=1; //南北方向黃燈熄滅
- }
- void east_west_allow() //東西通行允許子程序
- {
- ew_red=1; //東西方向紅燈熄滅
- ew_green=0; //東西方向綠燈亮
- ew_yellow=1; //東西方向黃燈熄滅
- sn_red=0; //南北方向紅燈亮
- sn_green=1; //南北方向綠燈熄滅
- sn_yellow=1; //南北方向綠燈熄滅
- }
- void init0_timer0() //定時器0初始化子程序
- {
- TMOD=0X01; //定時器0設置為模式1
- TH0=(65536-50000)/256; //TH0裝載初值
- TL0=(65536-50000)%256; //TL0裝載初值
- ET0=1; //開啟定時器中斷
- EA=1; //開啟CPU中斷
- TR0=1; //啟動定時器T0
- }
- void keyscan() //鍵盤掃描子程序
- {
- if(key_sourth_north==0) //判斷南北通行控制按鍵是否按下
- {
- delayms(2); //延時2毫秒
- if(key_sourth_north==0) //再次判斷南北通行控制按鍵是否按下
- {
- south_north_allow(); //調用南北通行子程序
- while(!key_sourth_north) display_time(); //南北通行時,
- //顯示通行倒計時
- TR0=0; //南北通行結束,關閉定時器T0
-
- }
- }
- if(key_earth_west==0) //判斷東西通行控制按鍵是否按下
- {
- delayms(2); //延時2毫秒
- if(key_earth_west==0) //再次判斷東西通行控制按鍵是否按下
- {
- east_west_allow(); //調用東西通行子程序
- while(!key_earth_west) display_time(); //東西通行時,
- //顯示通行倒計時
- TR0=0; //東西通行結束,關閉定時器T0
- }
- }
- if(all_not==0) //判斷全部禁行按鍵是否按下
- {
- delayms(2); //延時2毫秒
- if(all_not==0) //再次全部禁行按鍵是否按下
- {
- TR0=0; //進入全部禁行子程序,關閉定時器T0
- ew_red=0; //東西方向紅燈亮
- ew_green=1; //東西方向綠燈熄滅
- ew_yellow=1; //東西方向黃燈熄滅
- sn_red=0; //南北方向紅燈亮
- sn_green=1; //南北方向綠燈熄滅
- sn_yellow=1; //南北方向黃燈熄滅
- }
- }
- if(key_earth_west_add==0) // 東西時間+1
- {
- delayms(200);
- if(key_earth_west_add==1)
- {
- east_weat_time=east_weat_time+1;
- time_flag=time_flag+1;
- }
- }
- if(key_earth_west_jian==0) //東西時間-1
- {
- delayms(200);
- if(key_earth_west_jian==1)
- {
- east_weat_time=east_weat_time-1;
- time_flag=time_flag-1;
- }
- }
- if(key_sourth_north_add==0) //南北時間+1
- {
- delayms(200);
- if(key_sourth_north_add==1)
- {
- sou_nor_time=sou_nor_time+1;
- time_flag=time_flag+1;
- }
- }
- if(key_sourth_north_jian==0) //南北時間-1
- {
- delayms(200);
- if(key_sourth_north_jian==1)
- {
- sou_nor_time=sou_nor_time-1;
- time_flag=time_flag-1;
- }
- }
- }
-
- void main() //主程序
- {
- sou_nor_time=15; //初始化南北通行時間為15秒
- east_weat_time=6; //初始化東西通行時間為6秒
- traffic_flag=0; //初始化,南北通行
- time_flag=sou_nor_time; //設置南北通行的時間
- time_multiply =0; //計時變量初始化
-
- init0_timer0(); //調用定時器T0初始化子程序
- south_north_allow(); //調用南北通行允許子程序
-
- while(1) // while(1)無限循環
- {
- keyscan(); //調用鍵盤掃描子程序
- display_time(); //調用顯示倒計時子程序
- }
- }
- void int0_isr() interrupt 1 //定時器T0中斷服務程序
- {
- TH0=(65536-50000)/256; //TH0裝載初值
- TL0=(65536-50000)%256; //TL0裝載初值
- time_multiply++; //計時變量加1
- if(time_multiply>=20) //判斷計時變量是否大于20
- {
- time_multiply=0; //計時變量大于20,則把計時變量清零
- time_flag--; //倒計時的秒數減1
-
- if(traffic_flag==0) //若traffic_flag為0,則進入南北通行模式
- {
- if(time_flag>2) //南北通行倒計時進行中
- {
- south_north_allow();//南北通行紅綠燈輸出
- a=time_flag;
- b=time_flag;
- c=time_flag-3;
- d=time_flag-3;
- }
- else if(time_flag>0) //若倒計時時間小于2秒
- {
- sn_red=1;
- sn_green=1;
- sn_yellow=0; //此時南北黃燈亮2秒
- ew_red=0; //此時東西仍然是紅燈亮
- ew_green=1;
- ew_yellow=1;
- a=time_flag;
- b=time_flag;
- c=0;
- d=0;
-
- }
- else
- {
- traffic_flag=1; //此時南北通行計時結束,改為東西通行模式
- time_flag= east_weat_time; //東西通行時間變量賦值
- }
- }
- if(traffic_flag==1) //此時為東西通行模式
- {
- if(time_flag>2) //東西通行計時未結束
- {
- east_west_allow(); //東西通行紅綠燈輸出
- c=time_flag; //北時間
- d=time_flag; //南時間
- a=time_flag-3; //西時間
- b=time_flag-3; //東時間
-
- }
- else if(time_flag>0)
- {
-
- ew_red=1; //此時東西黃燈亮2秒
- ew_green=1;
- ew_yellow=0;
- sn_red=0; //此時南北仍然是紅燈亮
- sn_green=1;
- sn_yellow=1;
- c=time_flag;
- d=time_flag;
- a=0;
- b=0;
- }
- else
- {
- traffic_flag=0; //此時東西通行計時結束,改為東西通行模式
- time_flag= sou_nor_time; //南北通行時間變量賦值
- }
- }
- }
- else if(time_multiply>=10) //判斷計時變量是否大于20
- {
- if(traffic_flag==0) //若traffic_flag為0,則進入南北通行模式
- {
- if(time_flag>2) //南北通行倒計時進行中
- {
- south_north_allow();//南北通行紅綠燈輸出
- }
- else if(time_flag>0) //若倒計時時間小于2秒
- {
- sn_red=1;
- sn_green=1;
- sn_yellow=1; //此時南北黃燈亮2秒
- ew_red=0; //此時東西仍然是紅燈亮
- ew_green=1;
- ew_yellow=1;
- }
- else
- {
- traffic_flag=1; //此時南北通行計時結束,改為東西通行模式
- time_flag= east_weat_time; //東西通行時間變量賦值
- }
- }
- if(traffic_flag==1) //此時為東西通行模式
- {
- if(time_flag>2) //東西通行計時未結束
- {
- east_west_allow(); //東西通行紅綠燈輸出
- }
- else if(time_flag>0)
- {
-
- ew_red=1; //此時東西黃燈亮2秒
- ew_green=1;
- ew_yellow=1;
- sn_red=0; //此時南北仍然是紅燈亮
- sn_green=1;
- sn_yellow=1;
- }
- else
- {
- traffic_flag=0; //此時東西通行計時結束,改為東西通行模式
- time_flag= sou_nor_time; //南北通行時間變量賦值
- }
- }
- }
- }
復制代碼 |