主要利用FPGA作為主控。
以FPGA為核心,設計一個交通燈控制器,每個路口都有紅、黃、綠三盞燈。該交通信號燈控制器由一條車道A和一條車道B匯合成十字路口,在每個入口處設置紅、綠、黃三色信號燈,紅燈亮禁止通行,綠燈亮允許通行,黃燈亮則給行駛中的車輛有時間停在禁行線外。用紅、綠、黃發光二極管作信號燈。
1.2要求(1)東西、南北兩個方向的信號燈必須交替工作且兩個方向通行時間不同; (2)顯示采用LED光柱或數碼管倒計時的方式。 (3)遇有緊急情況可人為將兩個方向都置為紅燈。 (4)每個路口用2個七段數碼管倒計時顯示。
2. FPGA模塊方案論證及選擇各模塊端口及信號連接如下圖所示: 
由上圖可知,FPGA部分包括四個模塊,頂層模塊(top_traffic)、交通燈控制模塊(traffic_light)、數碼管顯示模塊(seg_led)、led燈控制模塊(led)。在頂層模塊中完 成對其它三個模塊的例化,并實現各模塊之間的數據傳遞。 頂層模塊(top_traffic):頂層模塊完成了對其它三個子模塊的例化、實現了子模塊間 的信號連接、并將led燈和數碼管的驅動信號輸出給外接設備(交通信號燈外設)。 交通燈控制模塊(traffic_light):交通燈控制模塊是本次實驗的核心代碼,這個模塊 控制信號燈的狀態轉換,將實時的狀態信號state[1:0]輸出給led燈控制模塊(led),同時將 東西和南北方向的實時時間數據ew_time[5:0]和sn_time[5:0]輸出給數碼管顯示模塊 (seg_led)。 數碼管顯示模塊(seg_led):接收交通燈控制模塊傳遞過來的東西和南北方向的實時時間數據ew_time[5:0]和sn_time[5:0],并以此驅動對應的數碼管,將數據顯示出來。 led燈控制模塊(led):根據接收到的實時狀態信號state[1:0],驅動東西和南北方向的led發光。
3. 原理設計
3.1基本原理點FPGA開發板上左邊的P6擴展口可以用來外接交通信號燈擴展模塊,交通信號 燈擴展模塊的原理圖如圖 38.3.1所示。  圖 38.3.1 交通信號燈原理圖
由上圖可知,交通信號燈擴展模塊四個方向共12個LED燈,而我們使用6個LED控制信號來 驅動12個LED燈,這是因為東西方向或者南北方向LED燈的亮滅狀態總是一致的,所以我們將東西方向或者南北方向顏色相同的LED燈并聯在一起,這樣設計的好處是減少了交通信號燈擴展模塊LED控制信號的引腳。 上圖中四個共陽型數碼管分別對應四個路口,每個路口用兩位數碼管顯示當前狀態的剩余 時間。我們知道,在十字路口中,東西方向或者南北方向數碼管顯示的時間總是一樣的。以東西方向為例,正因為這兩個方向顯示的時間一致,所以這兩個方向的數碼管,它們的十位可以用同一個位選信號來控制,個位用另一個位選信號來控制,這樣的話,就可以實現兩個位選信號控制東西方向共4位數碼管的亮滅,南北方向的數碼管同理。這樣設計的好處是減少了交通信號燈擴展模塊位選信號的引腳。 數碼管由PNP型三極管驅動,當三極管的基極為低電平時,數碼管相應的位被選通,所以交通信號燈擴展模塊的位選信號是低電平有效的。 3.2系統組成框圖交通燈控制模塊將需要顯示的時間數據連接到數碼管顯示模塊,同時將狀態信號連接到led燈控制模塊,然后數碼管顯示模塊和led燈控制模塊驅動交通信號燈外設工作。系統總體框架圖如圖 38.4.1所示,
3.3單元電路設計3.3.1 FPGA最小系統 FPGA最小系統包括:FPGA芯片、下載電路、外部時鐘、復位電路和電源。 如果使用NIOS II軟嵌入式處理器還要包括SDRAM和Flash。
圖3-3 FPGA最小系統 3.3.2 數碼管顯示電路 采用簡單的4組2位共陽極數碼管數碼管由PNP型三極管驅動,當三極管的基極為低電平時,數碼管相應的位被選通,所以交通信號燈擴展模塊的位選信號是低電平有效的。
 圖3-4數碼管顯示電路
3.4總體電路圖交通燈控制模塊將需要顯示的時間數據連接到數碼管顯示模塊,同時將狀態信號連接到led燈控制模塊,然后數碼管顯示模塊和 led燈控制模塊驅動交通信號燈外設工作。 總體電路圖如下圖所示:
圖3-6整體電路 3.5 程序設計3-7 系統軟件流程圖 3.6元件列表發光二極管(紅綠黃) | 12個 | 2.54單排針1*40 | 2排 | 三極管8550 | 4個 | 排母 | 2排 | 數碼管2位共陽 | 4組 | FPGA模塊 | 1塊 |
4.方案實現與測試(或調試)實現題上已給要求,在程序調試花費時間較多。  交通燈成品及實驗現象
課題二:電梯1、設計的目的與要求 1.1目的設計以8952單片機、AVR或ARM和步進電機為核心,設計電梯控制器。假設電梯安裝一個樓層為4樓的樓上。其人機接口包括顯示器、鍵盤、喇叭、指示燈。 1.2要求 每層樓電梯口都有上樓、下樓兩個按鈕,一個7段數碼顯示器作為電梯當前層指示燈。兩個發光二極管作為電梯運行方向的指示燈;進入電梯里面,按數字鍵選擇要去的樓層,一個7段數碼管顯示當前層顯示,兩個發光二極管作為電梯上行和下行指示燈。步進電機正轉,上行,反轉,表示下行。啟動按鈕按下去表示電梯控制系統可以運行。緊急停止按鈕按下,電機停止運動。報警按鈕按下,啟動蜂鳴器和閃爍紅色報警燈。 1.3 分工 馬浩寧:電路設計、程序調試 張曉涵:刻板、焊電路 王春燕:寫論文、查找資料 2、方案論證及選擇 2.1 總體設計方案設計的基本思想是采用STM32F103C8T6單片機作為核心采用8位LED靜態顯示來實時顯示電梯所在樓層。采用行列式鍵盤矩陣作為外呼內選電路,由于是4層樓,故選用4×4矩陣鍵盤,鍵盤矩陣共16個按鍵,其中6個按鍵是各層樓外呼按鍵,2個表示電梯啟動和停止的控制按鍵,電梯狀態是通過3個發光二極管顯示的,綠燈亮表示電梯在向上運行,黃燈亮表示電梯在向下運行,紅燈亮表示電梯故障急停狀態總體方框圖如圖2-1所示: 總體方框下圖所示:
2.2 主控芯片選擇 方案一:多片單片機控制方案。這種方案是使用多片單片機,其中一片是作為主控制器,另外設置了轎廂控制系統,每層的控制系統分別由一個單片機控制,然后通過主控制器和副控制器之間的通訊,實現電梯系統的控制。這種方案的控制系統的結構簡單明了,各個系統之間相互獨立便于維護和修檢。所以根據功能要求需要選用1片STM32單片機就能可以實現該電梯的功能。不過單片機之間的通訊較多,在目前通訊是個難點,可能導致電梯運行過程不穩定。 方案二:一片單片機為主控制器的方案。MCU采用一個單片機控制所有的按鍵、屏幕顯示、電動機的轉動等,并對以上所有信號進行處理。這種方案的控制系統相對復雜,只適用于較簡單的電梯控制系統,因為這次的設計是四層電梯控制系統,所以選用這種方案。單片機技術目前較為成熟,自身資源豐富,硬件設計簡單,成本低,可靠性高,結合軟件完全可以實現電梯運行狀況的簡單模擬。 權衡以上二種方案方案分析,采用方案二。 2.3 樓層顯示選擇方案一:采用點陣式的液晶顯示器(LCD)來顯示各種相關的數據以及相關的信息。點陣式的液晶顯示器雖然屬于低功耗的器件,但其價格比較貴。 方案二:采用傳統的八段數碼管(LED)顯示電梯實時所到的樓層。雖功耗大,但其軟件驅動相對比較簡單,硬件電路調試也比較方便,價格便宜,亮度大,能滿足本設計的要求。 以上兩種方案中,選擇方案一。 2.4 電動機驅動模塊選擇方案一:步進電機作為設計的執行部件,在定位性能的步進電機是非常優越的。步進電機和普通電機的區別主要在于其脈沖驅動形式,步進電機不需要A/D 轉換,能夠直接將數字脈沖信號轉化為角位移。常用的步進電機每轉一步,角度轉1.8°,在應用中,步進電機可以同時來完成兩個工作,一個是傳遞轉矩,第二個是傳遞信息,在本設計中作為傳遞信息用。 方案二:直流電機作為執行元件的設計,直流電機的功能是讓線圈總是交替地處于穩定狀態和不穩定的平衡狀態,通過兩個半圓環形電樞將穩定平衡線圈消除。這樣一個載流線圈總是降低磁場。直流電機中常用的系統,高轉矩,高扭矩,低慣量。 以上兩種方案采用方案一。 利用DXP畫圖軟件構建原理圖如下圖所示:
3、 原理設計 3.1 STM32F103C8T6功能簡介 STM32F103C8T6是一款基于ARM Cortex-M 內核STM32系列的32位的微控制器,程序存儲器容量是64KB,需要電壓2V~3.6V,具有高達1MB的Flash、電機控制、USB和CAN,該系列利用一流的外設和低功耗、低壓操作實現了高性能,同時還以可接受的價格、利用簡單的架構和簡便易用的工具實現了高集成度。從以上3種方案,很容易看出,采用方案3,電路設計比較簡潔,軟件設計也比較簡單,故采用方案3。STM32F103C8T6實物圖以及引腳結構圖如圖:
圖3-1 STM32原理圖
圖 3-1 STM32F103C8T6實物圖
3.2 單片機最小系統最小系統包括復位電路和時鐘電路兩部分,其中復位電路采用上電自動復位,如圖3-2所示: 圖3-2 單片機最小系統
3.3 按鍵電路本電路采用了13個按鍵。分別利用了P2和P3 端口,單片機采用行和列掃描法來判別這些按鍵中哪個鍵按下, S1-S13為微動按鍵,分別控制電梯的啟動、停止、急停及電梯樓層呼叫開關,然后可根據每個按鍵的功能來通過單片機控制電梯的運行。
圖 3-3 矩陣按鍵原理圖
圖3-4 矩陣按鍵
各按鈕開關說明: 電梯內:K4:緊急停止 K5:終止停止 K14:關門 K9:選擇一樓 K10:選擇二樓 K11:選擇三樓 K12:選擇四樓 電梯外:K1:一樓電梯上行 K2:二樓電梯上行 K3:三樓電梯上行 K6:二樓電梯下行 K7:三樓電梯下行 K8:四樓電梯下行 K15:啟動 K16:停止 3.4報警電路設計報警電路接單片機P35口,當端口變成低電平時, VCC電壓加載到蜂鳴器使其發聲、報警發光二極管亮,如圖3-5。  圖3-5 報警電路 3.5顯示電路設計采用點陣式的液晶顯示器(LCD12864)來顯示各種相關的數據以及相關的信息。點陣式的液晶顯示器屬于低功耗的器件,顯示清晰便利 如圖3.7,采用LCD12864顯示電路,VCC接3.3V,RS接單片機A5,RW接單片機A6, EN接單片機A7口,當有輸出時,直接在lcd 屏幕上進行顯示。
圖3-6 顯示電路設計
4、方案實現與調試 4.1 軟件設計思想設計采用微動按鍵來代替外呼按鈕,而電梯的運行方向和電梯啟動和停止是根據這些呼叫按鍵和選擇按鍵來決定的,所以單片機通過掃描鍵盤來獲取各層呼叫狀態,從而控制電梯的運行。故按鍵掃描是本系統軟件設計中的重要一部分,另外要把鍵盤掃描到的各層的按鍵信息存儲起來,然后和電梯的運行狀態比較,判斷是否響應各層呼叫,當電梯到達目的樓層時電機停止,可隨意選擇去哪一層,然后電梯選擇判斷去哪一層,繼續運行。 由于本設計采用單片機實現自動控制,主要完成了整個系統系統如數碼管的顯示,按鍵的響應,轉動電機的控制,延時等均由相應的子程序來完成。 軟件設計思想:使用模塊化的C語言編程,軟件系統的功能層次化設計方法,包括多個單一功能的子程序的。通過調用不同的子程序,實現復雜的控制功能。這是方便調試,修改。軟件編程是一種多功能,智能化,操作簡便。在本設計中,可以把程序的各部分相互結合起來,達到完成各項設計的功能。 4.2 電梯主程序
根據任務要求,電梯的程序應滿足以下要求: (1)初始化程序使LCD顯示“1”表示電梯處在一樓,等待人進入電梯; (2)主程序主要包括: ①判斷電梯選擇去哪一層,根據判斷情況來控制電梯運行,相應的指示燈顯示運行方向,到達目標樓層后相應的數碼管顯示電梯所在樓層; ②電梯在運行過程中要不斷的掃描鍵盤,從而來判斷各樓層是否有其他呼叫請求; ③設置電梯啟動、停止及緊急功能按鍵; ④實時顯示電梯所在位置及運行狀態(上行/下行); ⑤緊急按鈕是用于電梯出現意外時,用來報警求救; 圖4-1 主程序流程圖
電梯的整個軟件設計包括一下幾部分:電梯邏輯控制模塊、電梯運行模塊、鍵盤模塊、樓層顯示模塊。
電梯的整個軟件設計包括一下幾部分:電梯邏輯控制模塊、電梯運行模塊、鍵盤模塊、樓層顯示模塊。 4.3 按鍵方式鍵盤是獨立按鍵,采用的是查詢方式,即外接獨立按鍵的時候,是按鍵的一端接地,另一端與I/O引腳相連,當按鍵按下的時候,引腳輸入的是低電平,而按鍵未按下的時候,引腳輸入的是高電平[6]。利用C語言編程時只要用檢測高低電平來判斷是否有按鍵按下就可以了。其程序源代碼見附錄1。 4.4 顯示系統 顯示屏12864顯示全部 4.5 電機演示系統采用步進電機作為本設計的執行元件,步進電機在定位性能方面十分優越。步進電機和普通電機的區別主要就在于其脈沖驅動的形式,步進電機不需要A/D 轉換,能夠直接將數字脈沖信號轉化為角位移。常用的步進電機每轉一步,角度轉1.8°,在應用中,步進電機可以同時完成兩個工作,其一是傳遞轉矩,其二是傳遞信息,在本設計中作為傳遞信息用,步進電機使用的是28BYJ-5V。電梯運行前按啟動按鈕,步進電機8個節拍循環旋轉,電梯每上升或下降一層電機順時針或者逆時針轉動40度。 4.6軟件編譯調試在軟件調試中,采用keil仿真軟件進行程序調試。首先分別調試各個功能程序,再對整個程序進行調試,以便修改錯誤碼。具體的調試方法如下: 首先在keil軟件中選擇AT89C52作為CPU,因為該軟件中沒有STC89C52RC,但是基本功能和之差不多,將晶振頻率設置為11.0592MHZ,然后新建一個文件,將各個功能程序錄入,先檢查程序有無明顯錯誤,保存過后編譯程序,如果有錯誤時就根據提示加以修改,當各個功能程序編譯完成后,再對整個程序全速執行,查看程序有哪些地方出現錯誤,對應錯誤的提示來調整程序,糾正錯誤直到程序正確無誤,調試結束后軟件調試界面如下圖5-1所示: 圖5-1 軟件調試界面 4.7 實物制作及系統測試 在原理圖及原材料確定好的基礎上直接進行實物制作,進行各部件在電路板上的組配和焊接。
圖3-9 矩陣按鍵實物圖
圖4-1 報警電路實物圖
圖4-2 電機驅動電路實物圖
對系統進行測試,首先啟動電機運行,電梯位于一樓,按下二樓按鍵,上行燈點亮,步進電機轉動,到達目標樓層停下,此時數碼管顯示當前樓層。然后再一次按下三、四樓的按鍵,電梯先后在三樓、四樓停下。最后再按下二樓按鈕,電機逆時針旋轉停在二樓,最后在一樓停下。而且各指示燈和數碼管顯示都正常。 通過上電測試,電梯在上升或者下降過程中先響應上升或者下降樓層的信號,并對最近樓層呼叫有優先級的響應。系統具有方向優先、距離優先的功能,基本模擬了實際電梯運行,完成題目設計要求。 4.8 元器件清單
5、總結 經過這一段時間選擇和設計,完成了一個具有基本功能的電梯控制系統。系統是一個四層樓電梯控制系統。它能實現一個電梯具有的基本功能,包括:電梯上下運行功能,電梯選層功能,樓層顯示功能,電梯的啟動和停止及緊急報警功能,智能初始化功能。并且加入了自我設計的電機模塊,不僅基本達到了設計要求和目的,同時也不乏自我的創新設計。 通過這次設計,雖然遇到的困難重重,但是受益匪淺,對單片機在實物中應用的能力有一個很好的了解,這種開放式的設計,我從中學到的不僅僅是所設計方面的知識,更重要的是學習方法以及資料查找的技巧,學會了利用身邊現有的資源和人緣,作為我去更好學習的一個階梯,雖然這次設計時間并不長,但是我發現我們對自主學習能力有所提高。學無止境,在今后的學習生活中,我將把學到的知識靈活的運用到學習、工作和生活當中。而且在設計過程中,不僅是在學習新知識這一塊上有了很大的提高,同時我的意志力也得到了很好的鍛煉。只有你堅持,努力了,才能讓自己學到和收獲更多,才能更好的適應這個社會。
- module top_traffic(
- input sys_clk , //系統時鐘信號
- input sys_rst_n , //系統復位信號
-
- output [3:0] sel , //數碼管位選信號
- output [7:0] seg_led , //數碼管段選信號
- output [5:0] led //LED使能信號
- );
-
- //wire define
- wire [5:0] ew_time; //東西方向狀態剩余時間數據
- wire [5:0] sn_time; //南北方向狀態剩余時間數據
- wire [1:0] state ; //交通燈的狀態,用于控制LED燈的點亮
-
- //*****************************************************
- //** main code
- //*****************************************************
- //交通燈控制模塊
- traffic_light u0_traffic_light(
- .sys_clk (sys_clk),
- .sys_rst_n (sys_rst_n),
- .ew_time (ew_time),
- .sn_time (sn_time),
- .state (state)
- );
-
- //數碼管顯示模塊
- seg_led u1_seg_led(
- .sys_clk (sys_clk) ,
- .sys_rst_n (sys_rst_n),
- .ew_time (ew_time),
- .sn_time (sn_time),
- .en (1'b1),
- .sel (sel),
- .seg_led (seg_led)
- );
-
- //led燈控制模塊
- led u2_led(
- .sys_clk (sys_clk ),
- .sys_rst_n (sys_rst_n),
- .state (state ),
- .led (led )
- );
-
- endmodule
- module traffic_light(
- //input
- input sys_clk , //系統時鐘
- input sys_rst_n , //系統復位
-
- output reg [1:0] state , //交通燈的狀態,用于控制LED燈的點亮
- output reg [5:0] ew_time , //交通燈東西向數碼管要顯示的時間數據
- output reg [5:0] sn_time //交通燈南北向數碼管要顯示的時間數據
- );
-
- //parameter define
- parameter TIME_LED_Y = 5'd3; //黃燈發光的時間
- parameter TIME_LED_R = 5'd30; //紅燈發光的時間
- parameter TIME_LED_G = 5'd27; //綠燈發光的時間
- parameter WIDTH = 25_000_000; //產生頻率為1hz的時鐘
-
- //reg define
- reg [4:0] time_cnt; //產生數碼管顯示時間的計數器
- reg [24:0] clk_cnt; //用于產生clk_1hz的計數器
- reg clk_1hz; //1hz時鐘
-
- //*****************************************************
- //** main code
- //*****************************************************
- //計數周期為0.5s的計數器
- always @ (posedge sys_clk or negedge sys_rst_n)begin
- if(!sys_rst_n)
- clk_cnt <= 25'b0;
- else if (clk_cnt < WIDTH - 1'b1)
- clk_cnt <= clk_cnt + 1'b1;
- else
- clk_cnt <= 25'b0;
- end
-
- //產生頻率為1hz的時鐘
- always @(posedge sys_clk or negedge sys_rst_n)begin
- if(!sys_rst_n)
- clk_1hz <= 1'b0;
- else if(clk_cnt == WIDTH - 1'b1)
- clk_1hz <= ~ clk_1hz;
- else
- clk_1hz <= clk_1hz;
- end
-
- //切換交通信號燈工作的4個狀態,并產生數碼管要顯示的時間數據
- always @(posedge clk_1hz or negedge sys_rst_n)begin
- if(!sys_rst_n)begin
- state <= 2'd0;
- time_cnt <= TIME_LED_G ; //狀態1持續的時間
- end
- else begin
- case (state)
- 2'b0: begin //狀態1
- ew_time <= time_cnt + TIME_LED_Y - 1'b1;//東西方向數碼管要顯示的時間數據
- sn_time <= time_cnt - 1'b1; //南北方向數碼管要顯示的時間數據
- if (time_cnt > 1)begin //time_cnt等于1的時候切換狀態
- time_cnt <= time_cnt - 1'b1;
- state <= state;
- end
- else begin
- time_cnt <= TIME_LED_Y; //狀態2持續的時間
- state <= 2'b01; //切換到狀態2
- end
- end
- 2'b01: begin //狀態2
- ew_time <= time_cnt - 1'b1;
- sn_time <= time_cnt - 1'b1;
- if (time_cnt > 1)begin
- time_cnt <= time_cnt - 1'b1;
- state <= state;
- end
- else begin
- time_cnt <= TIME_LED_G; //狀態3持續的時間
- state <= 2'b10; //切換到狀態3
- end
- end
- 2'b10: begin //狀態3
- ew_time <= time_cnt - 1'b1;
- sn_time <= time_cnt + TIME_LED_Y - 1'b1;
- if (time_cnt > 1)begin
- time_cnt <= time_cnt - 1'b1;
- state <= state;
- end
- else begin
- time_cnt <= TIME_LED_Y; //狀態4持續的時間
- state <= 2'b11; //切換到轉態4
- end
- end
- 2'b11: begin //狀態4
- ew_time <= time_cnt - 1'b1;
- sn_time <= time_cnt - 1'b1;
- if (time_cnt > 1)begin
- time_cnt <= time_cnt - 1'b1;
- state <= state;
- end
- else begin
- time_cnt <= TIME_LED_G;
- state <= 2'b0; //切換到狀態1
- end
- end
- default: begin
- state <= 2'b0;
- time_cnt <= TIME_LED_G;
- end
- endcase
- end
- end
-
- endmodule
-
- module seg_led(
- input sys_clk , //系統時鐘
- input sys_rst_n , //系統復位
- input [5:0] ew_time , //東西方向數碼管要顯示的數值
- input [5:0] sn_time , //南北方向數碼管要顯示數值
- input en , //數碼管使能信號
- output reg [3:0] sel , //數碼管位選信號
- output reg [7:0] seg_led //數碼管段選信號,包含小數點
- );
-
- //parameter define
- parameter WIDTH = 50_000; //計數1ms的計數深度
-
- //reg define
- reg [15:0] cnt_1ms; //計數1ms的計數器
- reg [1:0] cnt_state; //用于切換要點亮數碼管
- reg [5:0] num; //數碼管要顯示的數據
-
- //wire define
- wire [5:0] data_ew_0; //東西方向數碼管的十位
- wire [5:0] data_ew_1; //東西方向數碼管的各位
- wire [5:0] data_sn_0; //南北方向數碼管的十位
- wire [5:0] data_sn_1; //南北方向數碼管的各位
-
- //*****************************************************
- //** main code
- //*****************************************************
- assign data_ew_0 = ew_time / 4'd10; //取出東西向時間數據的十位
- assign data_ew_1 = ew_time % 4'd10; //取出東西向時間數據的個位
- assign data_sn_0 = sn_time / 4'd10; //取出南北向時間數據的十位
- assign data_sn_1 = sn_time % 4'd10; //取出南北向時間數據的個位
-
- //計數1ms
- always @ (posedge sys_clk or negedge sys_rst_n) begin
- if (!sys_rst_n)
- cnt_1ms <= 15'b0;
- else if (cnt_1ms < WIDTH - 1'b1)
- cnt_1ms <= cnt_1ms + 1'b1;
- else
- cnt_1ms <= 15'b0;
- end
-
- //計數器,用來切換數碼管點亮的4個狀態
- always @ (posedge sys_clk or negedge sys_rst_n) begin
- if (!sys_rst_n)
- cnt_state <= 2'd0;
- else if (cnt_1ms == WIDTH - 1'b1)
- cnt_state <= cnt_state + 1'b1;
- else
- cnt_state <= cnt_state;
- end
-
- //先顯示東西方向數碼管的十位,然后是個位。再顯示南北方向數碼管的十位,然后個位
- always @ (posedge sys_clk or negedge sys_rst_n) begin
- if(!sys_rst_n) begin
- sel <= 4'b1111;
- num <= 4'b0;
- end
- else if(en) begin
- case (cnt_state)
- 3'd0 : begin
- sel <= 4'b1110; //驅動東西方向數碼管的十位
- num <= data_ew_0;
- end
- 3'd1 : begin
- sel <= 4'b1101; //驅動東西方向數碼管的個位
- num <= data_ew_1;
- end
- 3'd2 : begin
- sel <= 4'b1011; //驅動南北方向數碼管的十位
- num <= data_sn_0;
- end
- 3'd3 : begin
- sel <= 4'b0111; //驅動南北方向數碼管的個位
- num <= data_sn_1 ;
- end
- default : begin
- sel <= 4'b1111;
- num <= 4'b0;
- end
- endcase
- end
- else begin
- sel <= 4'b1111;
- num <= 4'b0;
- end
- end
-
- //數碼管要顯示的數值所對應的段選信號
- always @ (posedge sys_clk or negedge sys_rst_n) begin
- if (!sys_rst_n)
- seg_led <= 8'b0;
- else begin
- case (num)
- 4'd0 : seg_led <= 8'b1100_0000;
- 4'd1 : seg_led <= 8'b1111_1001;
- 4'd2 : seg_led <= 8'b1010_0100;
- 4'd3 : seg_led <= 8'b1011_0000;
- 4'd4 : seg_led <= 8'b1001_1001;
- 4'd5 : seg_led <= 8'b1001_0010;
- 4'd6 : seg_led <= 8'b1000_0010;
- 4'd7 : seg_led <= 8'b1111_1000;
- 4'd8 : seg_led <= 8'b1000_0000;
- 4'd9 : seg_led <= 8'b1001_0000;
- default : seg_led <= 8'b1100_0000;
- endcase
- end
- end
-
- Endmodule
-
- module led (
- input sys_clk , //系統時鐘
- input sys_rst_n , //系統復位
- input [1:0] state , //交通燈的狀態
- output reg [5:0] led //紅黃綠LED燈發光使能
- );
-
- //parameter define
- parameter TWINKLE_CNT = 25_000_000; //讓黃燈閃爍的計數次數
-
- //reg define
- reg [24:0] cnt; //讓黃燈產生閃爍效果的計數器
-
- //計數時間為0.2s的計數器,用于讓黃燈閃爍
- always @(posedge sys_clk or negedge sys_rst_n)begin
- if(!sys_rst_n)
- cnt <= 25'b0;
- else if (cnt < TWINKLE_CNT - 1'b1)
- cnt <= cnt + 1'b1;
- else
- cnt <= 25'b0;
- end
-
- //在交通燈的四個狀態里,使相應的led燈發光
- always @(posedge sys_clk or negedge sys_rst_n)begin
- if(!sys_rst_n)
- led <= 6'b100100;
- else begin
- case(state)
- 2'b00:led<=6'b100010; //led寄存器從高到低分別驅動:東西向
- //紅綠黃燈,南北向紅綠黃燈
- 2'b01: begin
- led[5:1]<=5'b10000;
- if(cnt == TWINKLE_CNT - 1'b1) //計數滿0.2秒讓黃燈的亮滅狀況切換一次
- //產生閃爍的效果
- led[0] <= ~led[0];
- else
- led[0] <= led[0];
- end
- 2'b10:led<=6'b010100;
- 2'b11: begin
- led[5:4]<=2'b00;
- led[2:0]<=3'b100;
- if(cnt == TWINKLE_CNT - 1'b1)
- led[3] <= ~led[3];
- else
- led[3] <= led[3];
- end
- default:led<=6'b100100;
- endcase
- end
- end
-
- endmodule
-
復制代碼
51hei.png (14.68 KB, 下載次數: 59)
下載附件
2020-4-12 15:56 上傳
完整的Word格式文檔51黑下載地址:
基于FPGA的交通燈設計.7z
(6.47 MB, 下載次數: 81)
2020-4-12 15:53 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|