数字系统设计VHDL实验:洗衣机控制器的设计(简易版)
前言
學校布置的數字系統設計大作業,要求完成VHDL核心代碼的設計,采用quartus II進行相關仿真并且在開發板上實現。由于本人能力有限,目的就是為了完成所要求的功能,就沒有使用元件例化(同時也覺得作業中的要求比較簡單),格式比較隨便,代碼僅供參考
設計目的與要求
總體設計
- 實驗開發環境:QuartusII 9.0
- 硬件資源:EDA-I(便攜式)實驗板
資源布局:
1. 主芯片:ALTERA 公司 EPF10K20TI144-4,提供 2 萬邏輯門
2. 配置芯片:ALTERA 公司 EPM240T100C5N
3. USB 串并轉換芯片:FTDI 公司的 FT245BL
4. 通用時鐘(時鐘頻率:0.9Hz-6MHz 范圍內可調整):4 組
5. 通用 LED 指示燈:24 個
6. 通用電平輸入/LED 指示:24 個
7. 通用脈沖輸入按鍵:8 個
8. 動態數碼管顯示:8 個
- 數碼管顯示資源
實驗箱上共有 8 個數碼管,其中 SEL7—SEL0 作為數碼管選擇信號,ABCDEFGH
依次對應 7 段譯碼器及小數點的選通信號。
8 個數碼管共用 8 個段選擇信號,在設計的時候,可以選擇讓 SEL7—SEL0 依次有效(SEL 信號低電平有效),然后對應的每個 SEL,ABCDEFGH有其相應的值(段選擇信號高電平有效),只要掃描頻率足夠,由于人眼的視覺暫留,用戶觀察到 8 個數碼管同時發光,且每個數碼管顯示的值互相不干擾。如某時刻 SEL0 的值為 0,ABCDEFGH 的值為 00001100,則最右邊數碼管顯示的值為“1”。數碼管的段選排列圖如圖所示:
- LED 輸出顯示資源
一共有24個發光二極管當輸出為高電平時,發光二極管導通,產生光源;當輸出為低電平時,發光二極管無法導通,燈不亮。
- 輸入開關/輸出顯示復用資源
實驗箱上共有 24 個開關與 24 個發光二極管,當需要輸入時,開關閉合(對于撥碼開關向上),則對應輸入值為邏輯“1”且發光二極管亮,若開關斷開,則輸入值為邏輯“0”,數碼管不亮。當作為輸出時,輸出值為邏輯“1”,則發光二極管亮,當輸出值為邏輯“0”時,發光二極管不亮。
基本原理
設計流程
EDA的設計流程主要包括設計輸入、設計處理、設計驗證、器件編程和硬件測試等5個步驟。
本次實驗中,我采用通過硬件描述語言VHDL進行電路設計的方式;然后進行綜合適配,對設計輸入的文件進行邏輯化簡,優化,對輸入文件進行語法檢查,最后產生編程文件;
設計驗證即時序仿真和功能仿真。通常情況下,先進行功能仿真,驗證其實現的功能是否滿足原設計的要求。在功能仿真已經完成,確認設計文件表達的功能滿足要求后,再進行綜合適配和時序仿真。器件編程是指將設計處理中產生的編程數據下載到具體的可編程器件中,也就是所說的板載測試,將下載文件通過FPGA編程器載入目標芯片FPGA中。硬件測試是指將含有載入了設計的FPGA的硬件系統進行統一測試,便于在真實的環境中檢驗設計效果。
總體結構分析
洗衣機控制器總體上分為狀態控制模塊、指示燈、顯像管控制模塊。其中的核心模塊是定時模塊,應通過定時模塊來決定洗衣機當前所在的狀態和所控制的顯像管。
洗衣機總共有6個狀態,分別為啟動、正轉、反轉、浸泡、脫水、結束;每個狀態對應一個指示燈,當一個狀態結束時,另一個狀態及其對應的指示燈需要立即銜接上去。
定時模塊主要用于確定剩余時間,首先將輸入的CLK信號分頻為1Hz,控制每個狀態的運行過程,將實時時間顯示在數碼管上。當倒計時結束后發送結束信號,顯示特定的信息。
顯像管控制模塊包括用于顯示各過程的二極管,也包括顯示時間的顯像管。通過高頻率地來回控制兩個顯像管,人用肉眼看上去就不會覺得有閃動,從而實時顯示當前時間。
子模塊設計
定時模塊需用到兩個CLK信號,其中一個用于控制倒計時,另一個用于控制時間在顯像管上的顯示。將用于倒計時的CLK信號設置成1Hz,每過1Hz,總時間減1,當個位數為0時,控制十位數減1,同時將個位的數重新置為9;十位減至0,此時若個位位置為0時,個位的數開始每經過1Hz加1,持續5秒,最后重新置0,整個狀態結束。十位和個位的起始數值由用戶選擇的模式來決定,若是浸泡洗,則分別為6和5;若是快速洗,則分別為6和0;若是脫水模式,則分別置為1和0。
控制兩個顯像管分別顯示十位和個位,需要輸入極快的CLK信號,在極短的時間內來回顯示兩個顯像管,從而使人們看上去像同時控制了兩個顯像管。
本次控制器設置了6個狀態,實驗要求是將所有狀態運行一遍。但觀察生活中的洗衣機我們可知道,洗衣機可以選擇從任意一個狀態開始,所以我添加了浸泡洗,分離出了脫水,該控制器總共有三種模式可選擇;每個狀態都有一個顯像管所對應,包括暫停狀態。
VHDL代碼:
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity led isport(clk: in std_logic; --時間控制信號sjkz: in std_logic; --數碼管控制qidong: in std_logic; --啟動信號zanting:in std_logic; --暫停信號fenggan:in std_logic; --脫水信號jingpaoxi:in std_logic; -浸泡洗信號qidongdeng:out std_logic; --啟動指示燈zhengzhuan:out std_logic; --正轉指示燈fanzhuan:out std_logic; --反轉指示燈jingpao:out std_logic; --浸泡指示燈tuoshui:out std_logic; --脫水指示燈jieshudeng:out std_logic; --結束指示燈zantingdeng:out std_logic; --暫停指示燈ledag:out std_logic_vector(7 downto 0);Bt:out std_logic_vector(7 downto 0)); end led;architecture arc of led is signal cnt1: integer range 0 to 8 :=6; signal cnt2: integer range 0 to 9 :=0; signal jsjs: integer range 0 to 5 :=0; --結束倒計時控制信號 signal guan:integer range 0 to 1; signal cntx:integer range 0 to 1; --兩個數碼管控制信號 signal jieshu:std_logic :='0'; begin--控制特定的數碼管 P1:process(cnt1,cnt2) begin case cntx ISwhen 0=> BT<="11111101";guan<=0; --顯示十位的數碼管when 1=> BT<="11111110";guan<=1; --顯示個位的數碼管when others=>NULL;End case;end process p1;--兩個數碼管來回顯示控制 p2:process(sjkz)beginif sjkz='1' then cntx<=1;else cntx<=0;end if;end process p2;--倒計時進程控制 P3:process(clk) beginqidongdeng<='0';if fenggan='1' and jingpaoxi='0' and qidong='0' thencnt1<=1;elsif jingpaoxi='1' and fenggan='0' and qidong='0' thencnt2<=5;elseif qidong='1' thenqidongdeng<='1';if clk'event and clk='1' then --每隔1Hz進行一次減1操作if zanting='0' thenzantingdeng<='0';if jieshu='0' thenif cnt2=0 and cnt1 /=0 then cnt1<=cnt1-1;cnt2<=9;elsif cnt2=0 and cnt1=0 thencnt1<=0;cnt2<=0;else cnt1<=cnt1;cnt2<=cnt2-1;end if;if cnt1=5 or cnt1=4 then if cnt2=9 or cnt2=7 or cnt2=5 or cnt2=3 or cnt2=1 thenzhengzhuan<='1';else zhengzhuan<='0';end if;end if;if cnt1=3 or cnt1=2 then if cnt2=9 or cnt2=7 or cnt2=5 or cnt2=3 or cnt2=1 thenfanzhuan<='1';else fanzhuan<='0';end if;end if;if cnt1=1 then if cnt2=9 or cnt2=7 or cnt2=5 or cnt2=3 or cnt2=1 thenjingpao<='1';else jingpao<='0';end if;end if;if cnt1=0 thenif cnt2=9 or cnt2=7 or cnt2=5 or cnt2=3 or cnt2=1 thentuoshui<='1';else tuoshui<='0';end if;if cnt2=0 thenjieshudeng<='1';jieshu<='1';end if;end if;else cnt1<=0;cnt2<=0; if jsjs=5 thenjieshudeng<='0';cnt1<=8;cnt2<=0;elsejsjs<=jsjs+1;cnt2<=jsjs+1;jieshudeng<='1'; end if;end if;else cnt1<=cnt1;cnt2<=cnt2;zantingdeng<='1';end if;end if;end if;end if;end process P3;--顯像管顯示資源控制 P4:process(guan,cnt1,cnt2) beginif guan=1 thencase cnt2 is --控制個位的數碼管顯示數字信息when 0 => ledag <="11111100";when 1 => ledag <="01100000";when 2 => ledag <="11011010";when 3 => ledag <="11110010";when 4 => ledag <="01100110";when 5 => ledag <="10110110";when 6 => ledag <="10111110";when 7 => ledag <="11100000";when 8 => ledag <="11111110";when 9 => ledag <="11110110";when others => null;end case;elsecase cnt1 is --控制十位的數碼管顯示數字信息when 0 => ledag <="11111100";when 1 => ledag <="01100000";when 2 => ledag <="11011010";when 3 => ledag <="11110010";when 4 => ledag <="01100110";when 5 => ledag <="10110110";when 6 => ledag <="10111110";when 7 => ledag <="11100000";when 8 => ledag <="00000001";when others => null;end case;end if;end process P4; end arc;引腳分布
注意!一定要根據自己使用的開發板上的引腳來設置,下面我只能提供我所使用的開發板的引腳分布,設置不一定要一模一樣,具體情況具體布局
輸入信號主要分三大類型,第一類是左上角藍色部分的通用時鐘信號,用于發送固定時鐘頻率的波動信號,這里選擇一個合適的頻率來回切換當前一瞬間所控制的數碼管,再選擇一個合適的頻率用來控制倒計時速度
第二類就是紅色部分中的電平信號,將開關向上撥動表示該引腳輸出高電平,向下
表示低電平
第三類就是黑色部分的脈沖信號,按一次表示輸出一個高脈沖,不像電平信號會一直維持當前狀態,所以可以用于電話按鍵等方面
開發板應該都具備這些基本輸入信號類型,建議看看開發板相應的說明書
板載測試
- 開始狀態
標準狀態下,控制器從60秒開始倒計時,70端口代表開始信號,若將其置為1,程序開始運行。 - 運行過程:
啟動指示燈在按下啟動按鍵后即點亮,顯像管根據題目要求,在規定時間內產生變化,根據倒計時時間來決定表示各個狀態的二極管閃爍。
運行結束:
5秒倒計時結束后,結束指示燈長亮,顯像管顯示規定數值。
分析與總結
本實驗中系統設計已達成目的,完成了所要求的各功能,但還有一些地方可以進行優化,比如在程序中加入一部分對波形圖顯示進行優化的代碼,使顯像管對應的二進制表示改變成人們更習慣的十進制。
這次大作業,我收獲最大的就是EDA操作的流程,VHDL語言的使用以及進程之間的通信都有了更深刻的認識,在實際操作中遇到了很多人都會遇到的問題,這些問題不會在書中講述,只有靠平時的經驗積累,才能為以后工作少走彎路。使用硬件描述語言需要我們學會從硬件的角度出發,理解信號傳遞之間的邏輯,在使代碼精簡的同時,確保系統運行的穩定性和正確性。
總結
以上是生活随笔為你收集整理的数字系统设计VHDL实验:洗衣机控制器的设计(简易版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017年真题精选(六)
- 下一篇: 2018总结以及2019展望