新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于單片機的交通燈信號控制器設計

        基于單片機的交通燈信號控制器設計

        作者: 時間:2011-10-22 來源:網絡 收藏

        設計一個基于。已知東、西、南、北四個方向各有紅黃綠色三個燈,在東西方向有兩個數碼管,在南北方向也有兩個數碼管。要求交通燈按照表1進行顯示和定時切換,并要求在數碼管上分別倒計時顯示東西、南北方向各狀態的剩余時間。
        表1 交通燈的狀態切換表

        南北方向

        東西方向

        序號

        狀態

        序號

        狀態

        1

        綠燈亮25秒,紅、黃燈滅

        1

        紅燈亮30秒,綠、黃燈滅

        2

        黃燈亮5秒,紅、綠燈滅

        3

        紅燈亮30秒,綠、黃燈滅

        2

        綠燈亮25秒,紅、黃燈滅

        3

        黃燈亮25秒,紅、綠燈滅

        回到狀態1

        回到狀態1

        3.2.1模塊1:系統設計
        (1)任務分析與整體設計思路
        試題要求實現的功能主要包括計時功能、動態掃描以及狀態的切換等幾部分。
        計時功能:要實現計時功能則需要使用定時器來計時,通過設置定時器的初始值來控制溢出中斷的時間間隔,再利用一個變量記錄定時器溢出的次數,達到定時1秒中的功能。當計時每到1秒鐘后,東西、南北信號燈各狀態的暫存剩余時間的變量減1。當暫存剩余時間的變量減到0時,切換到下一個狀態,同時將下一個狀態的初始的倒計時值裝載到計時變量中。開始下一個狀態,如此循環重復執行。
        動態掃描:需要使用4個數碼管分別顯示東西、南北的倒計時數字,將暫存各狀態剩余時間的數字從變量中提取出“十位”和“個位”,用動態掃描的方式在數碼管中顯示。
        整個程序依據定時器的溢出數來計時,每計時1S則相應狀態的剩余時間減1,一直減到0時觸發下一個狀態的開始。
        (2)型號及所需外圍器件型號,硬件電路原理圖

        圖3-5 交通燈硬件電路原理圖
        選用MCS51系列AT89S51單片機作為微控制器,選擇兩個四聯的共陰極數碼管組成8位顯示模塊,由于AT89S51單片機驅動能力有限,采用兩片74HC244實現總線的驅動,一個74HC244完成共陰極數碼管位控線的控制和驅動,另一個74HC244完成數碼管的7段碼輸出,在7段碼輸出口上各串聯一個100歐姆的電阻對7段數碼管限流。用P3口的P3.0-P3.5完成發光二極管的控制,實現交通燈信號的顯示,每個發光二極管串聯500歐姆電阻起限流作用。硬件電路原理圖如圖3-5所示。
        (3)程序設計思路,單片機資源分配以及程序流程
        ①單片機資源分配
        單片機P3口的P3.0-P3.1引腳用作輸出,控制發光二極管的顯示。在計時模塊中,需要定義兩個數組變量(init_sn[3],init_ew[3])來存儲東西、南北兩個方向在不同狀態中倒計時的初始值,題目中每個方向的交通燈共有3種顯示狀態,因此數組元素個數為3。還需要定義兩個變量( cnt_ sn, cnt_ ew)暫存東西、南北兩個方向的倒計時剩余時間。
        在狀態的切換中,為了明確當前處于哪種狀態,東西、南北方向各設置一個狀態變量(state_val_sn, state_val_ew),當倒計時的剩余時間到零時,狀態變量增1,表示啟動下一個狀態,當該變量增到3時變為0,回到序號為1的狀態。
        ②程序設計思路
        在設計中,由于沒有鍵盤功能,因此只涉及定時計數和動態掃描功能。主程序將變量初始化之
        后,設置單片機定時器和中斷特殊功能寄存器的初始值,將定時器T1的工作方式設置為8位自動
        裝載模式,定時器每隔250us產生一次溢出。
        在初始化變量與寄存器后,主程序進入一個循環結構,在循環中只做動態掃描的工作,根據東西、南北兩向的剩余時時間進行動態掃描顯示。
        計時以及狀態的切換通過定時器的中斷服務程序來實現,在中斷服務程序中,每計時到一秒時,則各方向當前狀態的剩余時間減1,一直減到0時觸發下一個狀態的開始,改變交通燈的指示。
        ③程序流程

        (4)軟硬件調試方案
        軟件調試方案:偉福軟件中,在“文件新建文件”中,新建C語言源程序文件,編寫相應的程序。在“文件新建項目”的菜單中,新建項目并將C語言源程序文件包括在項目文件中。
        在 “項目編譯”菜單中將C源文件編譯,檢查語法錯誤及邏輯錯誤。在編譯成功后,產生以 “*.hex”和“*.bin” 后綴的目標文件。
        硬件調試方案:在設計平臺中,將單片機的P3.0-P3.5分別與獨立式鍵盤的相應位通過插線連接起來。
        在偉福中將程序文件編譯成目標文件后,運行“MCU下載程序”,選擇相應的flash 數據文件,點擊“編程”按鈕,將程序文件下載到單片機的Flash中。
        然后,上電重新啟動單片機,檢查所編寫的程序是否達到題目的要求,是否全面完整地完成試題的內容。

        3.2.2 程序設計(僅供參考的C語言源程序)
        //晶振:11.0592M T1-250微秒溢出一次
        /*變量的定義:
        show_val_sn,show_val_ew: 顯示的值0-59
        state_val_sn,state_val_ew: 狀態值 南北方向0-綠燈亮;1-黃燈亮;2-紅燈亮
        T1_cnt: 定時器計數溢出數
        cnt_sn,cnt_ew: 倒計時的數值
        init_sn[3],init_ew[3] 倒計時
        led_seg_code:數碼管7段碼
        */
        #include "reg51.h"
        sbit SN_green=P3^2 ;//南北方向綠燈
        sbit SN_yellow=P3^1 ;//南北方向黃燈
        sbit SN_red=P3^0 ;//南北方向紅燈
        sbit EW_green=P3^5 ;//東西方向綠燈
        sbit EW_yellow=P3^4 ;//東西方向黃燈
        sbit EW_red=P3^3 ;//東西方向紅燈
        unsigned char data cnt_sn,cnt_ew;
        unsigned int data T1_cnt;
        unsigned char data state_val_sn,state_val_ew;
        char code led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
        char code init_sn[3]={24,4,29};
        char code init_ew[3]={29,24,4};
        //------------------------
        void delay(unsigned int i)//延時
        { while(--i); }
        //------------------------
        void led_show(unsigned int u,unsigned int v)
        { unsigned char i;
        i=u%10; //暫存個位
        P0=led_seg_code[i];
        P2=0xbf;
        delay(100); //延時
        i=u%100/10; //暫存十位
        P0=led_seg_code[i];
        P2=0x7f;
        delay(100); //延時
        i=v%10; //暫存個位
        P0=led_seg_code[i];
        P2=0xfe;
        delay(100); //延時
        i=v%100/10; //暫存十位
        P0=led_seg_code[i];
        P2=0xfd;
        delay(100); //延時
        }
        //-------------------------
        void timer1() interrupt 3 //T1中斷
        { T1_cnt++;
        if(T1_cnt>3999) //如果計數>3999, 計時1s
        { T1_cnt=0;
        if (cnt_sn!=0) //南北方向計時
        { cnt_sn--; }
        else
        { state_val_sn++;
        if (state_val_sn>2) state_val_sn=0;
        cnt_sn=init_sn[state_val_sn];
        switch (state_val_sn) //根據狀態值,刷新各信號燈的狀態
        { case 0: SN_green=0 ;//南北方向綠燈
        SN_yellow=1 ;//南北方向黃燈
        SN_red=1 ;//南北方向紅燈
        break;
        case 1: SN_green=1 ;//南北方向綠燈
        SN_yellow=0 ;//南北方向黃燈
        SN_red=1 ;//南北方向紅燈
        break;
        case 2:SN_green=1 ;//南北方向綠燈
        SN_yellow=1 ;//南北方向黃燈
        SN_red=0 ;//南北方向紅燈
        break;
        }
        }
        if (cnt_ew!=0) //東西方向計時
        { cnt_ew--; }
        else
        { state_val_ew++;
        if (state_val_ew>2) state_val_ew=0;
        cnt_ew=init_ew[state_val_ew];
        switch (state_val_ew) //根據狀態值,刷新各信號燈的狀態
        { case 0: EW_green=1 ;//東西方向綠燈
        EW_yellow=1;//東西方向黃燈
        EW_red=0 ;//東西方向紅燈
        break;
        case 1: EW_green=0 ;//東西方向綠燈
        EW_yellow=1 ;//東西方向黃燈
        EW_red=1 ;//東西方向紅燈
        break;
        case 2: EW_green=1 ;//東西方向綠燈
        EW_yellow=0 ;//東西方向黃燈
        EW_red=1 ;//東西方向紅燈
        break;
        }
        }
        }
        }
        //-------------------------
        main()
        {//初始化各變量
        cnt_sn=init_sn[0];
        cnt_ew=init_ew[0];
        T1_cnt=0;
        state_val_sn=0; //啟動后,默認工作在序號為1的狀態
        state_val_ew=0;
        //初始化各燈的狀態
        SN_green=0 ;//南北方向綠燈亮
        SN_yellow=1 ;//南北方向黃燈滅
        SN_red=1 ;//南北方向紅燈滅
        EW_green=1 ;//東西方向綠燈滅
        EW_yellow=1;//東西方向黃燈滅
        EW_red=0 ;//東西方向紅燈亮
        //初始化51的寄存器
        TMOD=0x20;//用T1計時 8位自動裝載定時模式
        TH1=0x19;//0x4b; //500微秒溢出一次; 250=(256-x)*12/11.0592 -> x= 230.4
        TL1=0x19;
        EA=1; //開中斷
        ET1=1;
        TR1=1; //開定時器T1
        while(1)
        { led_show(cnt_sn,cnt_ew);}}
        //主程序結束



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 佛山市| 塘沽区| 天柱县| 锡林郭勒盟| 巩留县| 余干县| 曲阳县| 太保市| 海口市| 安吉县| 察隅县| 江都市| 登封市| 汉寿县| 百色市| 敦煌市| 靖远县| 海门市| 福安市| 白玉县| 龙门县| 万年县| 长治县| 新营市| 朝阳区| 安乡县| 徐州市| 洛川县| 新蔡县| 香河县| 乡城县| 化德县| 钦州市| 图片| 木兰县| 乃东县| 新干县| 德格县| 沧州市| 深州市| 苏尼特右旗|