EDA第9章 系統(tǒng)設(shè)計實(shí)例_第1頁
EDA第9章 系統(tǒng)設(shè)計實(shí)例_第2頁
EDA第9章 系統(tǒng)設(shè)計實(shí)例_第3頁
EDA第9章 系統(tǒng)設(shè)計實(shí)例_第4頁
EDA第9章 系統(tǒng)設(shè)計實(shí)例_第5頁
已閱讀5頁,還剩78頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、第9章 電子電路的VHDL綜合設(shè)計本章給出了12個綜合設(shè)計實(shí)例,其中前8個設(shè)計實(shí)例涉及到電子設(shè)計系統(tǒng)常用的顯示功能(如LED數(shù)碼管顯示、點(diǎn)陣顯示及液晶顯示)、鍵盤輸入功能、模/數(shù)和數(shù)/模轉(zhuǎn)換控制功能,以及信息傳輸過程中用到的同步編/解碼和差錯控制編碼。后面4個綜合性的設(shè)計實(shí)例,如任意波形信號發(fā)生器、密碼鎖、多功能鬧鐘和音樂演奏發(fā)生器作為電子設(shè)計大賽的部分功能也會經(jīng)常涉及到。每一個設(shè)計實(shí)例都給出了仿真圖和在硬件平臺上驗(yàn)證時的導(dǎo)線連接,若讀者的硬件平臺和作者的不一樣,讀者只需讀懂實(shí)例代碼,然后對代碼作適當(dāng)?shù)男薷募皩?dǎo)線連接的修改即可。本章由簡入深的介紹方式,能幫助讀者及時地鞏固前面章節(jié)所學(xué)的VHDL

2、語言知識,相信當(dāng)讀者把這些項(xiàng)目全部訓(xùn)練完后,其設(shè)計能力會得到大大的提高。9.1 六位數(shù)碼動態(tài)掃描顯示電路的設(shè)計9.1.1 數(shù)碼管動態(tài)掃描顯示原理多位LED數(shù)碼管顯示可以分為靜態(tài)和動態(tài)顯示。靜態(tài)顯示時要求每一位數(shù)碼管都應(yīng)有一個數(shù)據(jù)鎖存器驅(qū)動LED的ag及小數(shù)點(diǎn)DP端,用于鎖存各位數(shù)碼管要顯示的不同數(shù)據(jù),另外,每一位數(shù)碼管的公共端還需要接有效電平。顯然,顯示的位數(shù)越多,需要的鎖存器也就越多,這樣很不經(jīng)濟(jì)。一般多位數(shù)碼管顯示多采用動態(tài)掃描顯示。動態(tài)掃描顯示時,將所有數(shù)碼管的各個控制端(ag、dp)并行的連接到同一數(shù)據(jù)線上,而各顯示器的公共端COM有位掃描信號控制,互不干擾。為了使各顯示器顯示不同的內(nèi)

3、容,先在數(shù)據(jù)線上送出第一位要顯示數(shù)字或內(nèi)容的段碼,然后位掃描信號使得第一位數(shù)碼管的公共端有效,這樣第一位數(shù)碼管顯示相應(yīng)的字符或數(shù)字,而其他各位數(shù)碼管熄滅,接著熄滅第一位數(shù)碼管,點(diǎn)亮第二位數(shù)碼管,依次輪流點(diǎn)亮,直到最后一位被點(diǎn)亮,然后重復(fù)點(diǎn)亮第一位數(shù)碼管,如此循環(huán)。當(dāng)掃描的頻率比較低時,數(shù)碼管顯示的信息會出現(xiàn)閃爍,但當(dāng)掃描頻率提高到使得每個數(shù)碼管每秒的點(diǎn)亮次數(shù)大于24次(一般取50次以上)時,由于數(shù)碼管的余暉效應(yīng)及人眼的視覺暫留效應(yīng),人眼就感覺不出閃爍了,好像是多位數(shù)碼管被同時點(diǎn)亮的。但掃描的位數(shù)過多,為了滿足每位數(shù)碼管的掃描頻率,勢必要減少每位數(shù)碼管導(dǎo)通的時間,這樣數(shù)碼管顯示信息的亮度將會降低

4、。9.1.2 設(shè)計要求與設(shè)計思路設(shè)計要求:設(shè)計一個8位數(shù)碼管共陰極動態(tài)掃描顯示控制電路,要顯示的信息比如”93434080”,其他要顯示的信息讀者可自行修改代碼。設(shè)計思路:該設(shè)計功能很簡單,只需要三個進(jìn)程即可完成該設(shè)計要求。一個進(jìn)程用于產(chǎn)生位掃描信號;第二個進(jìn)程完成對8個數(shù)碼管選通掃描和送出對應(yīng)位要顯示的字符;而第三個進(jìn)程完成顯示的字符或數(shù)字到7段字型碼的譯碼輸出。9.1.3 VHDL代碼設(shè)計library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity ledscan isport(cl

5、k:in std_logic; sg:out std_logic_vector(6 downto 0);-段控制信號輸出 bt:out std_logic_vector(2 downto 0);-位控制信號輸出end ledscan;architecture one of ledscan issignal cnt8:std_logic_vector(2 downto 0);signal A:integer range 0 to 15;begin P1:process(clk) beginif clk'event and clk='1' then cnt8<=cnt

6、8+1; end if; end process P1;P2:process(cnt8) begin case cnt8 is -8位顯示的數(shù)為93434080,這8位數(shù)可以根據(jù)需要靈活改變 when "000"=>bt<="000"A<=9; when "001"=>bt<="001"A<=3; when "010"=>bt<="010"A<=4; when "011"=>bt<=&quo

7、t;011"A<=3; when "100"=>bt<="100"A<=4; when "101"=>bt<="101"A<=0; when "110"=>bt<="110"A<=8; when "111"=>bt<="111"A<=0; when others =>null; end case; end process P2; P3:proc

8、ess(A) -十六進(jìn)制數(shù)轉(zhuǎn)換成共陰極字形碼的譯碼電路 begin case A is when 0 =>sg<="0111111" when 1 =>sg<="0000110" when 2 =>sg<="1011011" when 3 =>sg<="1001111" when 4 =>sg<="1100110" when 5 =>sg<="1101101" when 6 =>sg<=&qu

9、ot;1111110" when 7 =>sg<="0000111" when 8 =>sg<="1111111" when 9 =>sg<="1101111" when 10 =>sg<="1110111" when 11 =>sg<="1111100" when 12 =>sg<="0111001" when 13 =>sg<="1011110" when 1

10、4 =>sg<="1111001" when 15 =>sg<="1110001" when others =>null; end case; end process P3; end;9.1.4 時序仿真 仿真結(jié)束時間設(shè)定為100ms,clk的周期設(shè)定為5ms(頻率為200Hz),bt顯示基數(shù)值設(shè)定為“Unsigend Decimal”即無符號十進(jìn)制數(shù),如下圖9-1所示。仿真前的波形如圖9-2所示,仿真后所得的波形圖如9-3所示。圖9-1 bt基數(shù)值設(shè)定圖圖9-2 仿真前波形設(shè)置圖圖9-3 仿真后的波形圖

11、從上面的仿真圖9-3可以看出,在bt等于0的時刻,段控制輸出信號sg輸出的是8位數(shù)“93434080”的第一個數(shù)字即9的字形碼“11101111”,仿真完全正確。9.1.5硬件邏輯驗(yàn)證對輸入輸出端口鎖定引腳后再重新編譯,然后連接導(dǎo)線,并將代碼下載到ACEX1K家族的FPGA芯片EP1K30TC144-3中驗(yàn)證。導(dǎo)線連接說明:(1)輸入端口clk分配的引腳接實(shí)驗(yàn)箱上時鐘分頻器模塊的clk2或clk3插孔,使clk2或clk3輸出的頻率大于等于400Hz(臨界閃爍頻率為50Hz,有8只數(shù)碼管需要刷新,故刷新頻率應(yīng)大于50Hz×8=400Hz);(2)段控制輸出端口sg分配的引腳接實(shí)驗(yàn)箱上

12、8位8字形共陰極數(shù)碼管區(qū)的a,b,c,d,e,f,g插孔;(3)位控制輸出端口bt分配的引腳接16*16點(diǎn)陣區(qū)的sel0,sel1和sel2插孔。注:sel2sel1sel0=000時,最右邊的一只數(shù)碼管亮,sel2sel1sel0=111時,最左邊的一只數(shù)碼管亮。硬件驗(yàn)證方法:將上述代碼下載編程到CPLD器件后,數(shù)碼管區(qū)顯示“93434080”。9.2 矩陣式鍵盤接口電路的設(shè)計9.2.1鍵盤掃描與識別原理1. 鍵盤的分類鍵盤是最常見的計算機(jī)輸入設(shè)備,它廣泛應(yīng)用于微型計算機(jī)和各種終端設(shè)備上。下面對鍵盤分類作一簡單的介紹。按鍵值編碼方式可分為: (硬件)編碼鍵盤與非(硬件)編碼鍵盤。編碼鍵盤采用

13、專用的編碼/譯碼器件,被按下的鍵由該器件譯碼輸出相應(yīng)的鍵碼/鍵值。增加了硬件開銷,但編程簡單,適用于規(guī)模大的鍵盤。非編碼鍵盤采用軟件編碼/譯碼的方式,通過掃描,對每個被按下的鍵判別輸出相應(yīng)的鍵碼/鍵值。不增加硬件開銷,編碼靈活,適用于小規(guī)模的鍵盤,特別是單片機(jī)系統(tǒng)。但編程較復(fù)雜,占CPU時間。按鍵組合連接方式可分為:獨(dú)立式鍵盤與矩陣式鍵盤。獨(dú)立式鍵盤的每個鍵相互獨(dú)立,如圖9-4所示,各自與一條I/O線相連,通過直接讀取該I/O線的高/低電平狀態(tài)識別按鍵。一線一鍵,占I/O口線多,但按鍵識別(編程)簡單,判鍵速度快,多用于設(shè)置控制鍵、功能鍵等鍵數(shù)少的場合。矩陣式鍵盤的鍵按矩陣排列,如圖9-5所示

14、,各鍵處于矩陣行/列的結(jié)點(diǎn)處,通過對連在行(列)的I/O線送已知電平的信號,然后讀取列(行)線的狀態(tài)信息。鍵多時占用I/O口線少,但判鍵速度慢,多用于設(shè)置數(shù)字鍵等鍵數(shù)多的場合。 圖9-4 獨(dú)立式按鍵結(jié)構(gòu)圖 圖9-5 矩陣式按鍵結(jié)構(gòu)圖2. 鍵盤掃描的基本原理鍵盤的掃描要完成有無按鍵的識別及其求對應(yīng)按鍵的鍵號。掃描過程具體包括以下步驟:(1) 判別有無鍵按下;(2) 去除鍵的機(jī)械抖動影響機(jī)械按鍵輸出的電壓波形如下圖9-6所示,在按下鍵及其按鍵釋放時出現(xiàn)了電壓的高低波動,稱為抖動,抖動時間一般在5ms10ms之間,為了保證按下一次鍵只做一次響應(yīng)處理,必須消除按鍵的抖動影響。可以采用硬件或軟件方案消除

15、抖動影響。圖9-6 按鍵抖動波形圖硬件方案可以通過施密特或雙穩(wěn)態(tài)去抖電路(如圖9-7)。軟件方案可以延時10ms20ms后再次判斷。圖9-7 雙穩(wěn)態(tài)去抖電路圖 (3) 掃描獲取閉合鍵的行、列值; (4) 根據(jù)行列值用計算法或查表法得到鍵值; (5) 判斷閉合鍵是否釋放,如沒釋放則繼續(xù)等待;(6) 保存閉合鍵號3.鍵盤掃描的方式 鍵盤掃描的方式有編程掃描方式、定時掃描方式、中斷掃描方式三種。后兩種一般是利用單片機(jī)來實(shí)現(xiàn)。定時掃描方式是通過設(shè)定單片機(jī)內(nèi)部的定時器產(chǎn)生一定時間(例如10 ms)的定時,當(dāng)定時時間到就產(chǎn)生定時器溢出中斷,CPU響應(yīng)中斷后在中斷服務(wù)程序中完成鍵盤的掃描功能。該方式的缺點(diǎn)是

16、CPU工作效率仍不夠高,因?yàn)槎〞r時間到后,即使沒有鍵按下,也要完成一次鍵盤的掃描。為進(jìn)一步提高CPU工作效率,可采用中斷掃描工作方式。即當(dāng)無鍵按下時,CPU處理自己的工作,當(dāng)有鍵按下時,產(chǎn)生中斷請求(需要增加一個與門電路),CPU轉(zhuǎn)去執(zhí)行鍵盤掃描中斷服務(wù)程序,并識別鍵號。本實(shí)驗(yàn)項(xiàng)目采用編程掃描方式,針對圖9-5所示的矩陣式按鍵結(jié)構(gòu),其原理如下:先讓第0列處于低電平,其余列處于高電平,檢查是否有行線變低,若某一行變?yōu)榈碗娖?,則第0列與該行的交叉點(diǎn)處有按鍵按下;若所有的行都為高電平,則表示第0列無鍵按下;再讓第1列處在低電平,其余列處于高電平,依此循環(huán),這種方式稱為鍵盤掃描。 鍵號=列首鍵號(0、

17、4、8、12、16、20、24、28)+行號(0、1、2、3)9.2.2 設(shè)計要求與設(shè)計思路設(shè)計要求:完成4*8小鍵盤的識別,并將其中的16個鍵定義為數(shù)字鍵:0、1、2A、BF(其余的16個鍵可以定義成功能鍵),并將按下的這16個鍵的數(shù)字左移動顯示在8位數(shù)碼管上。設(shè)計思路:要完成按鍵的識別和顯示,除了需要4*8的矩陣鍵盤電纜外,還需要以下電路模塊:(1)時鐘產(chǎn)生電路。該系統(tǒng)需要三種不同頻率的時鐘:系統(tǒng)時鐘(它的頻率最高,其它的頻率的時鐘可以由它分頻得到)、消除鍵盤抖動時鐘以及鍵盤列掃描和8位七段數(shù)碼管顯示掃描共用的時鐘。(2)鍵盤掃描電路。該電路用來產(chǎn)生掃描鍵盤8列所需要的順序變化的序列:00

18、0001010011100101110111000,周而復(fù)始。當(dāng)掃描信號為000時,經(jīng)過74LS138譯碼后掃描的是鍵盤的第1列,并讀取該列四行的狀態(tài),若有鍵按下,則停止列掃描并完成按鍵編碼和移位存儲;若該列沒有鍵按下,則繼續(xù)掃描下一列。(3)消除抖動電路。對機(jī)械式開關(guān)的按鍵,在按下和釋放時會出現(xiàn)圖9-6所示的電壓波形起伏的抖動現(xiàn)象,在靈敏度高(或掃描頻率高)的電路,一次按鍵的動作可能會被誤判成幾次按鍵動作。為了克服這個問題,需要一個計數(shù)器,計數(shù)器的位數(shù)根據(jù)系統(tǒng)的時鐘頻率高低而定,每當(dāng)識別到有鍵按下時,計數(shù)器就清零,按鍵釋放后計數(shù)器要在系統(tǒng)時鐘的作用下計滿溢出后,才認(rèn)為是一次按鍵動作完成。實(shí)驗(yàn)

19、箱上4*8的鍵盤的定義如下:0123MEMESC4567REGEXC89AbLASTSTEPCdEFNEXTENTERCRTL空空空空SHIFT沒有沒有按行的方向依次取6個位置鍵排成一行就是實(shí)驗(yàn)箱上鍵盤的實(shí)際布局,具體如下:0123MEMESC4567REGEXC89AbLASTSTEPCdEFNEXTENTERCRTL空空空空SHIFT9.2.3 VHDL代碼設(shè)計library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all ;entity keyboard isport ( clk ,clr: in

20、 std_logic ; columndecode: out std_logic_vector (2 downto 0) ; -用于驅(qū)動138譯碼器選取4*8鍵盤的8條列線的輸出端口inkeyrow: in std_logic_vector (3 downto 0) ; -讀取4*8鍵盤的4條行線的端口segout : out std_logic_vector (7 downto 0) -輸出字形端口,用于連接7段led的a,b,c,d,e,f,g段 );end keyboard; architecture doit of keyboard issignal clkdiv_val: std_l

21、ogic_vector(1 downto 0);signal columnscan: std_logic_vector(2 downto 0);signal counter: std_logic_vector(7 downto 0);signal reg0,reg1,reg2,reg3,reg4,reg5,reg6,reg7: std_logic_vector(3 downto 0);-存放0F的數(shù)字寄存器信號signal num_encode: std_logic_vector(3 downto 0);signal row_col_code: std_logic_vector(6 downt

22、o 0);signal zx_reg0,zx_reg1,zx_reg2,zx_reg3,zx_reg4,zx_reg5,zx_reg6,zx_reg7: std_logic_vector(7 downto 0); -存放字形碼的寄存器信號signal clk1,test,koff: std_logic;component decode port( ssin : in std_logic_vector(3 downto 0); ssout: out std_logic_vector(7 downto 0) );end component;begintest<=inkeyrow(3) and

23、 inkeyrow(2) and inkeyrow(1) and inkeyrow(0);P1: process(clr,clk) begin if(clr='0') then clkdiv_val<="00" -分頻系數(shù) elsif(clk'event and clk='1') then clkdiv_val<=clkdiv_val+1; end if;end process P1;clk1<='0' when clkdiv_val<="01" else -列掃描時鐘clk

24、1是clk的4次分頻 '1'P2: process(clr,clk1,test) begin if(clr='0') then columnscan<="000" -列掃描信號為0,停止掃描鍵盤,第一位數(shù)碼管亮 elsif(clk1'event and clk1='1') then if(test='0') or (koff='0') then columnscan<=columnscan;-有鍵按下時,columnscan值不變,停止掃描列,同時也停止掃描8位數(shù)碼管 els

25、e columnscan<=columnscan+1;-沒有鍵按下時,columnscan加1掃描下一列,同時也動態(tài)掃描8位數(shù)碼管 end if; end if;end process P2;columndecode<=columnscan;-信號columnscan送列譯碼輸出端口columndecoderow_col_code<=columnscan&inkeyrow; -將按下鍵的列和行位置碼并置起來P3: process(clk,test)begin if(clk'event and clk='0') then if(row_col_c

26、ode="0001110") then -對行列位置碼進(jìn)行從0,1,2,.,F的編碼 num_encode<=x"0" elsif(row_col_code="0011110") then num_encode<=x"1" elsif(row_col_code="0101110") then num_encode<=x"2" elsif(row_col_code="0111110") then num_encode<=x"

27、3" elsif(row_col_code="1101110") then num_encode<=x"4" elsif(row_col_code="1111110") then num_encode<=x"5" elsif(row_col_code="0001101") then num_encode<=x"6" elsif(row_col_code="0011101") then num_encode<=x"

28、7" elsif(row_col_code="1001101") then num_encode<=x"8" elsif(row_col_code="1011101") then num_encode<=x"9" elsif(row_col_code="1101101") then num_encode<=x"a" elsif(row_col_code="1111101") then num_encode<=x"

29、b" elsif(row_col_code="0101011") then num_encode<=x"c" elsif(row_col_code="0111011") then num_encode<=x"d" elsif(row_col_code="1001011") then num_encode<=x"e" elsif(row_col_code="1011011") then num_encode<=x"

30、f" elsif(test='0') then num_encode<=x"f" end if; end if;end process P3;P4: process(test,clk,clr) -防止按鍵抖動的進(jìn)程 begin if(clr='0') then counter<="00000000" -清零輸入端clr為有效電平0時,信號counter清零 koff<='1' elsif(clk'event and clk='1') then if(tes

31、t='0') then counter<="00000000" -有鍵按下時,信號(或稱計數(shù)器)counter清零 koff<='0' -按鍵斷開標(biāo)志,koff=0表示按鍵沒有斷開 elsif(counter<"11111110") then -按鍵釋放后,若counter<254則counter加1 counter<=counter+1; elsif(counter="11111110") then koff<='1' -counter=254時,k

32、off=1表示按鍵已經(jīng)斷開或釋放。 end if; end if;end process P4;P5: process(koff,clr) begin if(clr='0') then -clr=0時寄存器全部清0 reg0<="0000" reg1<="0000" reg2<="0000" reg3<="0000" reg4<="0000" reg5<="0000" reg6<="0000" re

33、g7<="0000" elsif(koff'event and koff='1') then reg0<=num_encode;-koff從0變到1,說明有鍵按下并釋放,讀取該次按鍵并左移顯示 reg1<=reg0; reg2<=reg1; reg3<=reg2; reg4<=reg3; reg5<=reg4; reg6<=reg5; reg7<=reg6; end if;end process P5;-數(shù)字寄存器信號regi與字形譯碼器輸入端口相連,字形譯碼器輸出端口與信號zx_regi相連U1

34、: decode port map(ssin=>reg0, ssout=>zx_reg0);U2: decode port map(ssin=>reg1, ssout=>zx_reg1);U3: decode port map(ssin=>reg2, ssout=>zx_reg2);U4: decode port map(ssin=>reg3, ssout=>zx_reg3); U5: decode port map(ssin=>reg4, ssout=>zx_reg4);U6: decode port map(ssin=>re

35、g5, ssout=>zx_reg5);U7: decode port map(ssin=>reg6, ssout=>zx_reg6);U8: decode port map(ssin=>reg7, ssout=>zx_reg7); segout<=zx_reg0 when columnscan="000" else -字形碼寄存器信號送segout端口 zx_reg1 when columnscan="001" else zx_reg2 when columnscan="010" else zx_

36、reg3 when columnscan="011" else zx_reg4 when columnscan="100" else zx_reg5 when columnscan="101" else zx_reg6 when columnscan="110" else zx_reg7 when columnscan="111" else x"00"end doit;-數(shù)字編碼到字形編碼的譯碼模塊library ieee;use ieee.std_logic_1164.al

37、l;use ieee.std_logic_unsigned.all ;entity decode isport( ssin : in std_logic_vector(3 downto 0); ssout: out std_logic_vector(7 downto 0) );end decode;architecture a of decode isbeginssout<=x"3f" when ssin="0000" else -將數(shù)字編碼譯碼成共陰極字形碼 x"06" when ssin="0001" e

38、lse x"5b" when ssin="0010" else x"4f" when ssin="0011" else x"66" when ssin="0100" else x"6d" when ssin="0101" else x"7d" when ssin="0110" else x"07" when ssin="0111" else x"7

39、f" when ssin="1000" else x"6f" when ssin="1001" else x"77" when ssin="1010" else x"7c" when ssin="1011" else x"39" when ssin="1100" else x"5e" when ssin="1101" else x"79" when

40、 ssin="1110" else x"71" when ssin="1111" else x"00"end a;9.2.4 時序仿真仿真結(jié)束時間設(shè)定為50ms,clk的時鐘周期設(shè)定為50us,占空比50%。先在整個仿真時間內(nèi),將inkeyrow的值設(shè)定為“1111”,然后再選定一部分時間段如10ms22.8ms,將該段inkeyrow的值修改成“1101”,如圖9-8所示。仿真后的波形圖如下圖9-9所示,從圖中可以看出,當(dāng)inkeyrow由1101變?yōu)?111的時刻為22.8ms,再經(jīng)過254個防止抖動的時鐘即2

41、54*0.05ms=12.7ms之后,也就是在35.5ms時刻,讀入該按鍵位置碼:列碼為000 ,行碼為1101,由上面的代碼可知道位置被定義成了數(shù)字鍵“6”,而6的共陰極字形碼01111101B=0x7d。通過仿真可知道該代碼正確無誤。圖9-8 仿真前的波形設(shè)置圖圖9-9 仿真后的波形圖9.2.5硬件邏輯驗(yàn)證對輸入輸出端口鎖定引腳后再重新編譯,然后連接導(dǎo)線,并下載代碼。導(dǎo)線連接說明:(1)輸入端口clk分配的引腳接實(shí)驗(yàn)箱上時鐘分頻器模塊的clk2插孔;(2)輸入端口clr分配的引腳接實(shí)驗(yàn)箱上撥碼開關(guān)輸出插孔;(3)輸入端口inkeyrow分配的引腳接實(shí)驗(yàn)箱上矩陣鍵盤的行線插孔KIN0,KIN

42、1,KIN2,KIN3;(4)段控制輸出端口segout分配的引腳接實(shí)驗(yàn)箱上8位8字形共陰極數(shù)碼管區(qū)的a,b,c,d,e,f,g插孔;(5)鍵盤列譯碼輸出端口columndecode分配的引腳接實(shí)驗(yàn)箱上16*16點(diǎn)陣區(qū)的sel0,sel1和sel2插孔。注:sel2sel1sel0=000時,最右邊的一只數(shù)碼管亮,sel2sel1sel0=111時,最左邊的一只數(shù)碼管亮。硬件驗(yàn)證方法:將上述代碼下載編程到CPLD器件后,按下實(shí)驗(yàn)箱鍵盤上的數(shù)字鍵0F,則在數(shù)碼管上左移動顯示按下的鍵值。當(dāng)clr連接的開關(guān)撥向下方即輸出低電平時,熄滅數(shù)碼管已經(jīng)顯示的數(shù)字鍵,由于停止掃描時,列掃描信號columnsc

43、an<=”000”,即最右邊的一個數(shù)碼管譯碼仍然有效,因而最右邊的一個數(shù)碼管顯示”0”。9.3 16×16點(diǎn)陣漢字顯示控制器的設(shè)計9.3.1點(diǎn)陣字符產(chǎn)生及顯示原理點(diǎn)陣就是一個一個的點(diǎn)組成的陣列,通過點(diǎn)亮不同的點(diǎn)顯示不同的內(nèi)容。顯然,要顯示漢字、字符及數(shù)字,首先要得到對應(yīng)的點(diǎn)陣碼,這可以通過現(xiàn)有的字模提取軟件很方便地得到對應(yīng)的點(diǎn)陣碼。這樣的字模提取軟件有很多,下圖9-10就是從網(wǎng)上下載的畔畔16×16字模提取軟件。只要在該軟件界面的“右旋90度(R)”按鈕左邊的輸入框內(nèi)輸入漢字、字符或數(shù)字,然后選擇字模的取模順序以及顯示結(jié)果的模式(ASM形式以十六進(jìn)制H結(jié)尾,而C51形

44、式以十六進(jìn)制0x開頭),最后點(diǎn)擊“提取字模(O)”按鈕,即可在最下面的欄中顯示出字模提取的結(jié)果。比如在輸入框中輸入漢字“曲”,字模提取的順序選擇ABCD項(xiàng)即為:橫向從左至右。為了得到漢字列方向的編碼,可以將漢字“右旋轉(zhuǎn)90度”,則旋轉(zhuǎn)后漢字的橫向編碼即為漢字的縱向從下至上的編碼。點(diǎn)擊“向右旋轉(zhuǎn)90度”按鈕,然后再點(diǎn)擊“提取字?!卑粹o,則在最下面的欄中以字節(jié)形式顯示出了字幕提取后的結(jié)果。掃描16×16點(diǎn)陣的工作原理同8位掃描數(shù)碼管的原理類似。也可分為靜態(tài)顯示和動態(tài)顯示。對于靜態(tài)顯示,則要求16列(行)的每一列(行)都要有1個數(shù)據(jù)鎖存器,硬件電路比較復(fù)雜。而動態(tài)顯示則需要1個16位的數(shù)據(jù)

45、鎖存器用于驅(qū)動列(行)方向的16個點(diǎn),由4-16的譯碼器選定某一列(行)有效。比如先輸出第0列的點(diǎn)陣碼并讓第0列有效,則第0列的某些點(diǎn)被點(diǎn)亮,持續(xù)一段時間后熄滅該列所有的點(diǎn),然后再點(diǎn)亮第1列,只要按列(行)的方向掃描速度足夠快,由于人眼睛視覺暫留的作用,點(diǎn)陣顯示的漢字看起來就沒有閃爍,好像是靜止的。圖9-10 畔畔16×16字模提取軟件界面圖9.3.2 設(shè)計思路將要顯示的字符串,通過字模提前軟件按列的方向從下自上提取16*16點(diǎn)陣字模,按照下高位上低位從下自上、從左到右排列字節(jié),并將這些點(diǎn)陣碼存儲到配置的RAM中。通過設(shè)計一個掃描控制模塊對16*16點(diǎn)陣的16列進(jìn)行列掃描,并不斷地進(jìn)

46、行刷新,每當(dāng)更新掃描的列時,控制器也對RAM的地址加1以取出存儲在RAM中的對應(yīng)列碼送往16*16的16根行線,為了能實(shí)現(xiàn)漢字的動態(tài)顯示可以設(shè)置一個列的基地址,RAM的地址等于列的基地址加015的偏移地址。16*16點(diǎn)陣控制器原理如圖9-11所示。圖9-11 16*16點(diǎn)陣控制器原理圖9.3.3 VHDL代碼設(shè)計下面的代碼在16*16點(diǎn)陣模塊上顯示“曲阜師范大學(xué)信傳學(xué)院”library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity dianzhen is port (On_Off: in std_

47、logic;-控制點(diǎn)陣顯示器是否顯示漢字的端口 Left_right: in std_logic;-控制漢字左移動或右移動顯示的端口 jmp_disp: in std_logic;-控制漢字跳動顯示的端口-即漢字突然出現(xiàn)一段時間后又突然熄滅的方式HZDispSpeedCLK: in std_logic;-控制漢字的顯示快慢的時鐘 Scan16ColumnCLK: in std_logic;-用于動態(tài)掃描點(diǎn)陣顯示器16列的時鐘 -該時鐘的頻率應(yīng)該比漢字的顯示時鐘快的多sel: out std_logic_vector(3 downto 0);-該端口端 1 口連接至4-16譯碼器的輸入端-譯碼器

48、的輸出Y0-Y15硬件電路分別接至點(diǎn)陣顯示器的16列-其中點(diǎn)陣顯示器最右邊的列是第0列,最左邊的列是15列 L15_0: out std_logic_vector(15 downto 0);-用來連接點(diǎn)陣顯示器的16根行信號-從上到下依次為L0行至L15行end;architecture arc_dianzhen of dianzhen issignal din: std_logic_vector(7 downto 0);signal dout: std_logic_vector(15 downto 0);signal a,b: std_logic_vector(7 downto 0);beg

49、inprocess(HZDispSpeedCLK,On_Off,jmp_disp,Left_right) begin if(On_Off='1')then -On_Off='1'點(diǎn)陣顯示器不顯示字符 if(Left_right='0')then b<="11110001"-指向起始位置b=-15-a從0000變化到1111時向下滑動一個包含16列的窗口 else -Left_right='1' b<="10100000"-指向最后一個字的第16列的下一位置,以便最后一個漢字左移動

50、全部顯示完-再向下滑動一個16列窗口,則執(zhí)行when others=>dout<=x"0000"不顯示漢字 end if; elsif(HZDispSpeedCLK'event and HZDispSpeedCLK='1')then if(jmp_disp='0'and Left_right='0')then -jmp_disp='0'表示不跳動顯示字符,Left_right='0'表示字符左移動顯示 if(b="10100000")then b<=

51、"11110001"-b=-15,b+"00001111"="00000000" else b<=b+1; end if; elsif(jmp_disp='0'and Left_right='1')then -jmp_disp='0'表示不跳動顯示字符,Left_right='1'表示字符右移動顯示 if(b="11110001")then b<="10100000" else b<=b-1; end if; el

52、se -jmp_disp='1'時,不管Left_right='1'或'0',都逐個字符跳動著顯示 if(b="10100000")then b<="00000000" else b<=(b and "11110000")+16;-字符在左移或右移動顯示時,若jmp_disp='1',則可能會出現(xiàn)一塊點(diǎn)陣顯示器上-不能完全顯示一個字符,而是顯示著前一個字符的右半部分和后一個字符的-左半部分。為了讓b指向一個字符的起始位置,可以屏蔽掉b的低四位(一個漢字占16列

53、) end if; end if; end if; end process;process(Scan16ColumnCLK,On_Off) begin if(On_Off='1' )then a<="00000000" elsif(Scan16ColumnCLK'event and Scan16ColumnCLK='1')then if(a="00001111")then -a用來掃描點(diǎn)陣顯示器的16列 a<="00000000" else a<=a+1; end if; en

54、d if; end process; din<=a+b;process(din,On_Off) begin if(On_Off='0')then case din is when"00000000"=>dout<=x"0000" -1 when"00000001"=>dout<=x"fff0" -2 when"00000010"=>dout<=x"4210" -3 when"00000011"=&g

55、t;dout<=x"4210" -4 when"00000100"=>dout<=x"4210" -5 when"00000101"=>dout<=x"7fff" -6 when"00000110"=>dout<=x"4210" -7 曲 when"00000111"=>dout<=x"4210" -8 when"00001000"=>d

56、out<=x"4210" -9 when"00001001"=>dout<=x"7fff" -10 when"00001010"=>dout<=x"4210" -11 when"00001011"=>dout<=x"4210" -12 when"00001100"=>dout<=x"4210" -13 when"00001101"=>do

57、ut<=x"fff8" -14 when"00001110"=>dout<=x"0010" -15 when"00001111"=>dout<=x"0000" -16 when"00010000"=>dout<=x"1000" -1 when"00010001"=>dout<=x"1000" -2 when"00010010"=>dout

58、<=x"1000" -3 when"00010011"=>dout<=x"17FC" -4 when"00010100"=>dout<=x"1254" -5 when"00010101"=>dout<=x"1254" -6 when"00010110"=>dout<=x"1256" -7 when"00010111"=>dout<=

59、x"FE55" -8 阜 when"00011000"=>dout<=x"1254" -9 when"00011001"=>dout<=x"1254" -10 when"00011010"=>dout<=x"1254" -11 when"00011011"=>dout<=x"13DE" -12 when"00011100"=>dout<=

60、x"1004" -13 when"00011101"=>dout<=x"1800" -14 when"00011110"=>dout<=x"1000" -15 when"00011111"=>dout<=x"0000" -16 when"00100000"=>dout<=x"0000" -1 when"00100001"=>dout<=x

61、"8FFC" -2 when"00100010"=>dout<=x"4000" -3 when"00100011"=>dout<=x"3000" -4 when"00100100"=>dout<=x"0FFF" -5 when"00100101"=>dout<=x"0000" -6 when"00100110"=>dout<=x"

62、;0002" -7 when"00100111"=>dout<=x"3FF2" -8 師 when"00101000"=>dout<=x"0012" -9 when"00101001"=>dout<=x"0012" -10 when"00101010"=>dout<=x"FFFE" -11 when"00101011"=>dout<=x"

63、1012" -12 when"00101100"=>dout<=x"2012" -13 when"00101101"=>dout<=x"1FFB" -14 when"00101110"=>dout<=x"0012" -15 when"00101111"=>dout<=x"0000" -16 when"00110000"=>dout<=x"

64、0404" -1 when"00110001"=>dout<=x"0444" -2 when"00110010"=>dout<=x"FD94" -3 when"00110011"=>dout<=x"0424" -4 when"00110100"=>dout<=x"026F" -5 when"00110101"=>dout<=x"0004&

65、quot; -6 when"00110110"=>dout<=x"3FE4" -7 when"00110111"=>dout<=x"4024" -8 范 when"00111000"=>dout<=x"4024" -9 when"00111001"=>dout<=x"4224" -10 when"00111010"=>dout<=x"442F" -11 when"

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論