Verilog HDL數(shù)字設(shè)計(jì)教程(賀敬凱)第7章_第1頁(yè)
Verilog HDL數(shù)字設(shè)計(jì)教程(賀敬凱)第7章_第2頁(yè)
Verilog HDL數(shù)字設(shè)計(jì)教程(賀敬凱)第7章_第3頁(yè)
Verilog HDL數(shù)字設(shè)計(jì)教程(賀敬凱)第7章_第4頁(yè)
Verilog HDL數(shù)字設(shè)計(jì)教程(賀敬凱)第7章_第5頁(yè)
已閱讀5頁(yè),還剩232頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

7.1跑馬燈控制器的設(shè)計(jì)7.28位數(shù)碼掃描顯示電路的設(shè)計(jì)

7.3數(shù)控分頻器的設(shè)計(jì)

7.4樂(lè)曲硬件演奏電路的設(shè)計(jì)

7.5數(shù)字跑表和數(shù)字鐘的設(shè)計(jì)

7.6用VerilogHDL狀態(tài)機(jī)實(shí)現(xiàn)A/D采樣控制電路

7.7交通控制器的設(shè)計(jì)

7.8空調(diào)控制器的設(shè)計(jì)

7.9飲料自動(dòng)售賣機(jī)的設(shè)計(jì)

7.10小結(jié)

習(xí)題7

7.1跑馬燈控制器的設(shè)計(jì)

1.設(shè)計(jì)要求共8個(gè)LED燈,連成一排。要求實(shí)現(xiàn)幾種燈的組合顯示。具體要求如下:

(1)模式1:先奇數(shù)燈,即第1、3、5、7燈亮0.25s,然后偶數(shù)燈,即第2、4、6、8燈亮0.25s,依次循環(huán)。

(2)模式2:按照1、2、3、4、5、6、7、8的順序依次點(diǎn)亮所有燈,間隔時(shí)間為0.25s;然后再按1/2/3/4/5/6/7/8的順序依次熄滅所有燈,間隔時(shí)間為0.25s。

(3)模式3:按照1/8、2/7、3/6、4/5的順序依次點(diǎn)亮所有燈,間隔時(shí)間為0.25s,每次同時(shí)點(diǎn)亮兩個(gè)燈;然后再按照1/8、2/7、3/6、4/5的順序依次熄滅所有燈,間隔時(shí)間為0.25s,每次同時(shí)熄滅兩個(gè)燈。

(4)以上模式可以選擇。

2.設(shè)計(jì)說(shuō)明

LED燈與FPGA的連接如圖7-1所示,設(shè)計(jì)要求很容易實(shí)現(xiàn),在此不再說(shuō)明。圖7-18個(gè)LED燈與FPGA的連接圖使用兩個(gè)鍵進(jìn)行模式選擇,兩個(gè)鍵有00、01、10、11四種組合,使用其中的三種組合,分別對(duì)應(yīng)設(shè)計(jì)要求的三種情況。

3.設(shè)計(jì)模塊(包含模塊劃分)該設(shè)計(jì)比較簡(jiǎn)單,僅用一個(gè)模塊即可,輸入端口為rst、clk、sel[1..0],輸出端口為led[7..0],其中sel用于模式選擇,led用于控制8個(gè)LED燈,如圖7-2所示。圖7-2跑馬燈模塊端口框圖4.代碼分析【例7-1】設(shè)計(jì)源碼。modulepaomadeng(rst,clk,sel,led);inputrst,clk;input[1:0]sel;output[7:0]led;reg[7:0]led;reg[7:0]led_r,led_r1;regcnt1,dir;reg[2:0]cnt2;reg[1:0]cnt3;always@(posedge

clk) begin

if(rst)begincnt1<=0;cnt2<=0;cnt3<=0;dir<=0;end else

case(sel) 2'b00: begin

led_r=8'b01010101; if(cnt1==0)led<=led_r; elseled<=led_r<<1; cnt1<=cnt1+1; end

2'b01: begin

if(!dir) begin if(cnt2==0)beginled_r=8'b00000001;led<=led_r;end elsebeginled<=(led<<1)+led_r;end if(cnt2==7)begindir<=~dir;end cnt2<=cnt2+1; endelse begin if(cnt2==0)beginled_r=8'b11111110;led<=led_r;end elsebeginled<=led<<1;end if(cnt2==7)begindir<=~dir;end cnt2<=cnt2+1; end end2'b11: begin

if(!dir) begin if(cnt3==0)beginled_r=8'b00000001;led_r1=8'b10000000;end elsebeginled_r=(led_r<<1)|led_r;led_r1=(led_r1>>1)|led_r1;end led<=led_r|led_r1; if(cnt3==3)begindir<=~dir;end cnt3<=cnt3+1; end else

begin if(cnt3==0)beginled_r=8'b11111110;led_r1=8'b01111111;end elsebeginled_r=led_r<<1;led_r1=led_r1>>1;end led<=led_r&led_r1; if(cnt3==3)begindir<=~dir;end cnt3<=cnt3+1;

end end default:;

endcase endendmodule程序說(shuō)明:

(1)?case語(yǔ)句用于選擇三種模式。當(dāng)case表達(dá)式中的sel為2'b00時(shí)選擇模式1,為2'b01時(shí)選擇模式2,為2'b11時(shí)選擇模式3。

(2)?cnt1、cnt2、cnt3分別為三種模式下的計(jì)數(shù)器,用于控制流水燈的轉(zhuǎn)換節(jié)奏。

(3)?dir用于方向控制,與cnt1、cnt2、cnt3的具體數(shù)值相關(guān)。

5.仿真分析仿真波形如圖7-3所示。該仿真波形僅列出了sel為2'b11時(shí)跑馬燈的運(yùn)行情況。從圖中可以看出,燈的運(yùn)行與模式3一致,說(shuō)明程序代碼實(shí)現(xiàn)了模式3。讀者也可以通過(guò)修改sel的值對(duì)模式1和模式2進(jìn)行驗(yàn)證。圖7-3跑馬燈仿真波形

6.引腳鎖定下載硬件驗(yàn)證選擇GW48-PK2系統(tǒng)中的實(shí)驗(yàn)電路5,引腳鎖定情況如圖7-4所示。將設(shè)計(jì)下載到實(shí)驗(yàn)開(kāi)發(fā)系統(tǒng)中,觀察實(shí)際運(yùn)行情況。clk接FPGA的93引腳,頻率選擇4Hz,然后通過(guò)按鍵選擇跑馬燈的運(yùn)行模式,觀察跑馬燈的實(shí)際運(yùn)行情況。圖7-4引腳鎖定情況

7.擴(kuò)展部分請(qǐng)讀者思考其他LED顯示方式,并實(shí)現(xiàn)之。例如:先循環(huán)左移,再循環(huán)右移(任一時(shí)刻只有一個(gè)LED燈亮),然后從兩頭至中間依次點(diǎn)亮(任一時(shí)刻只有兩個(gè)LED燈亮),之后不斷重復(fù)以上顯示方式。7.28位數(shù)碼掃描顯示電路的設(shè)計(jì)

1.設(shè)計(jì)要求共8個(gè)數(shù)碼管,連成一排,要求可以任意顯示其中一個(gè)或多個(gè)數(shù)碼管。具體要求如下:

(1)依次選通8個(gè)數(shù)碼管,并讓每個(gè)數(shù)碼管顯示相應(yīng)的值,比如讓每個(gè)數(shù)碼管依次顯示13579BDF。

(2)要求能在實(shí)驗(yàn)臺(tái)上演示出數(shù)碼管的動(dòng)態(tài)顯示過(guò)程。

2.設(shè)計(jì)說(shuō)明下面對(duì)實(shí)驗(yàn)原理作簡(jiǎn)單介紹。

(1)數(shù)碼管分共陰極和共陽(yáng)極兩類。7段共陰極數(shù)碼管如圖7-5所示。當(dāng)數(shù)碼管的輸入為“1101101”時(shí),數(shù)碼管的7個(gè)段g、f、e、d、c、b、a分別接1、1、0、1、1、0、1;由于接有高電平的段發(fā)亮,因此數(shù)碼管顯示“5”。注意,這里沒(méi)有考慮表示小數(shù)點(diǎn)的發(fā)光管,如果要考慮,需要增加段h。圖7-5共陰極數(shù)碼管及其電路

(2)圖7-6所示的是8位數(shù)碼掃描顯示電路,其中每個(gè)數(shù)碼管的8個(gè)段h、g、f、e、d、c、b、a(h是小數(shù)點(diǎn))都分別連在一起,8個(gè)數(shù)碼管分別由8個(gè)選通信號(hào)K1、K2、…、K8來(lái)選擇。被選通的數(shù)碼管顯示數(shù)據(jù),其余關(guān)閉。如在某一時(shí)刻,k1為高電平,其余選通信號(hào)為低電平,這時(shí)僅K1對(duì)應(yīng)的數(shù)碼管顯示來(lái)自段信號(hào)端的數(shù)據(jù),而其他7個(gè)數(shù)碼管均不顯示。因此,如果希望在8個(gè)數(shù)碼管顯示不同的數(shù)據(jù),就必須使得8個(gè)選通信號(hào)K1、K2、…、K8輪流被單獨(dú)選通,同時(shí),在段信號(hào)輸入口加上希望在對(duì)應(yīng)數(shù)碼管上顯示的數(shù)據(jù),這樣隨著選通信號(hào)的變化,才能實(shí)現(xiàn)掃描顯示的目的。圖7-68位數(shù)碼掃描顯示電路

3.設(shè)計(jì)模塊(包含模塊劃分)該設(shè)計(jì)使用了2個(gè)模塊,如圖7-7所示。該設(shè)計(jì)的輸入為clk,輸出為SM_7S[6..0]、SM_B[7..0]。其中SM_7S為段選信號(hào),對(duì)數(shù)碼管的每一段進(jìn)行控制;SM_B為位選信號(hào),用于在8個(gè)數(shù)碼管中選擇。圖7-7數(shù)碼管頂層模塊框圖

4.代碼分析例7-2的Dec7S模塊為7段譯碼器,輸入信號(hào)SM_in可取十六進(jìn)制數(shù)0~F,輸出信號(hào)SM_7S的7位分別接數(shù)碼管的7個(gè)段,高位在左,低位在右。【例7-2】7段數(shù)碼顯示譯碼器設(shè)計(jì)。

moduleDec7S(SM_in,SM_7S);//七段譯碼電路

input[3:0]SM_in;

outputreg[6:0]SM_7S;

always@(SM_in)

begin

case(SM_in)

4'd0:SM_7S=7'b0111111; 4'd1:SM_7S=7'b0000110; 4'd2:SM_7S=7'b1011011; 4'd3:SM_7S=7'b1001111; 4'd4:SM_7S=7'b1100110; 4'd5:SM_7S=7'b1101101; 4'd6:SM_7S=7'b1111101; 4'd7:SM_7S=7'b0000111; 4'd8:SM_7S=7'b1111111;

4'd9:SM_7S=7'b1101111; 4'd10:SM_7S=7'b1110111; 4'd11:SM_7S=7'b1111100; 4'd12:SM_7S=7'b0111001; 4'd13:SM_7S=7'b1011110; 4'd14:SM_7S=7'b1111001; 4'd15:SM_7S=7'b1110001; default:;

endcaseendendmodule例7-3的GenBS模塊用于生成位選信號(hào)和待顯示數(shù)據(jù)。程序中的cnt8是一個(gè)3位計(jì)數(shù)器,產(chǎn)生掃描計(jì)數(shù)信號(hào),SM_B=1<<cnt8;用于對(duì)8個(gè)數(shù)碼管掃描選通,SM_in<=2*cnt8+1;用于生成待顯示數(shù)據(jù)。例如當(dāng)cnt8等于1時(shí),K2對(duì)應(yīng)的數(shù)碼管被選通,同時(shí),A被賦值3,當(dāng)cnt8不斷加1后,將能在8個(gè)數(shù)碼管上分別顯示數(shù)據(jù)1、3、5、7、9、B、D、F。【例7-3】位選和待顯示數(shù)據(jù)生成電路。moduleGenBS(clk,SM_in,SM_B);inputclk;outputreg[3:0]SM_in;outputreg[7:0]SM_B;reg[2:0]cnt8;always@(posedge

clk)begin

if(cnt8>=7)cnt8<=0; elsecnt8<=cnt8+1;

SM_in<=2*cnt8+1;//生成待顯示數(shù)據(jù)為1,3,5,... SM_B=1<<cnt8;//生成位選信號(hào)

endendmodule例7-4是掃描顯示的頂層模塊。其中:clk是掃描時(shí)鐘;SM_7S為7段控制信號(hào),由高位至低位分別接g、f、e、d、c、b、a7個(gè)段;SM_B是位選控制信號(hào),接圖7-6中的8個(gè)選通信號(hào)K1、K2、…、K8。

【例7-4】8位數(shù)碼掃描顯示電路頂層模塊。

moduleshumaguan(clk,SM_7S,SM_B);

inputclk;

output[6:0]SM_7S;//段控制信號(hào)輸出

output[7:0]SM_B;//位控制信號(hào)輸出

wire[3:0]SM_in;

GenBSinst1(clk,SM_in,SM_B);//調(diào)用位選和待顯示數(shù)據(jù)生成電路

Dec7Sinst2(SM_in,SM_7S);//調(diào)用譯碼電路

endmodule

5.仿真分析仿真波形如圖7-8所示。從圖中可以看出,在每一個(gè)時(shí)鐘上升沿選中下一個(gè)數(shù)碼管,同時(shí)送相應(yīng)的數(shù)據(jù)給該數(shù)碼管顯示。圖7-8數(shù)碼管仿真波形

6.引腳鎖定下載硬件驗(yàn)證將設(shè)計(jì)下載到實(shí)驗(yàn)開(kāi)發(fā)系統(tǒng)中,觀察實(shí)際運(yùn)行情況。實(shí)驗(yàn)方式:若考慮小數(shù)點(diǎn),則SM_7S的8個(gè)段分別與PIO49、PIO48、…、PIO42(高位在左)連接、SM_B的8個(gè)位分別與PIO34、PIO35、…、PIO41(高位在左)連接。在GW48EDA系統(tǒng)數(shù)碼管左邊有一個(gè)跳線冒,將其跳下端“CLOSE”(平時(shí)跳上端“ENAB”),這時(shí)實(shí)驗(yàn)系統(tǒng)的8個(gè)數(shù)碼管構(gòu)成圖7-6所示的電路結(jié)構(gòu),時(shí)鐘clk可選擇clock0,通過(guò)跳線選擇16384Hz信號(hào)。引腳鎖定后進(jìn)行編譯、下載和硬件測(cè)試實(shí)驗(yàn)。引腳鎖定如圖7-9所示。圖7-9引腳鎖定情況時(shí)鐘clk選擇clock0,通過(guò)跳線選擇4Hz信號(hào),可演示數(shù)碼管的動(dòng)態(tài)掃描過(guò)程。

7.擴(kuò)展部分請(qǐng)讀者嘗試完成以下幾種顯示方式:

(1)?8個(gè)數(shù)碼管同時(shí)顯示,每個(gè)數(shù)碼管的8個(gè)段,即a、b、c、d、e、f、g、dp依次顯示,每個(gè)段持續(xù)顯示時(shí)間為0.25s。

(2)?8個(gè)段和8個(gè)數(shù)碼管依次顯示,a段顯示在第1個(gè)數(shù)碼管上,b段顯示在第2個(gè)數(shù)碼管上,……,dp段顯示在第8個(gè)數(shù)碼管上,顯示持續(xù)時(shí)間為0.25s。

(3)將0~F這16個(gè)十六制數(shù)依次顯示在數(shù)碼管中,每個(gè)時(shí)刻只有一個(gè)數(shù)碼管顯示,持續(xù)時(shí)間為0.25s,即0顯示在第1個(gè)數(shù)碼管、1顯示在第2個(gè)數(shù)碼管、……、7顯示在第8個(gè)數(shù)碼管、8顯示在第1個(gè)數(shù)碼管、……、F顯示在第8個(gè)數(shù)碼管。7.3數(shù)控分頻器的設(shè)計(jì)

1.設(shè)計(jì)要求

(1)對(duì)于任意頻率,均可以對(duì)其進(jìn)行數(shù)控分頻,以得較低的頻率。

(2)對(duì)于預(yù)定頻率,均可以通過(guò)對(duì)較高頻率分頻得到。

2.設(shè)計(jì)說(shuō)明數(shù)控分頻器的功能是:當(dāng)在輸入端給定不同輸入數(shù)據(jù)時(shí),對(duì)輸入的時(shí)鐘信號(hào)有不同的分頻比。數(shù)控分頻器是用計(jì)數(shù)值可并行預(yù)置的加法計(jì)數(shù)器設(shè)計(jì)完成的,方法是將計(jì)數(shù)溢出位與預(yù)置數(shù)加載輸入信號(hào)相接,詳細(xì)設(shè)計(jì)程序如例7-5所示。

3.設(shè)計(jì)模塊(包含模塊劃分)本例僅有一個(gè)模塊,圖7-10給出了分頻器模塊的端口框圖。其中,CLK為時(shí)鐘信號(hào);D為輸入數(shù)據(jù),根據(jù)這個(gè)數(shù)據(jù)進(jìn)行分頻;FOUT為分頻后的輸出。圖7-10分頻器模塊的端口框圖

4.代碼分析

【例7-5】數(shù)控分頻器的設(shè)計(jì)。

moduleDVF_v(CLK,D,FOUT);

inputCLK;

input[7:0]D;

outputregFOUT;

reg[7:0]FULL;

always@(posedgeCLK)

begin:P_REG

reg[7:0]CNT8;

if(CNT8==8'b11111111)beginCNT8=D;//當(dāng)CNT8計(jì)數(shù)計(jì)滿時(shí),輸入數(shù)據(jù)D被同步預(yù)置給計(jì)數(shù)器CNT8FULL<=1'b1;//同時(shí)使溢出標(biāo)志信號(hào)FULL輸出為高電平

end else beginCNT8=CNT8+1;//否則繼續(xù)作加1計(jì)數(shù)

FULL<=1'b0;//且輸出溢出標(biāo)志信號(hào)FULL為低電平

end

endalways@(posedgeFULL)

begin:P_DIV

regCNT2; CNT2=~CNT2;//如果溢出標(biāo)志信號(hào)FULL為高電平,則D觸發(fā)器輸出取反

if(CNT2==1'b1)FOUT=1'b1;elseFOUT=1'b0;endendmodule

5.仿真分析圖7-11為數(shù)控分頻器的仿真結(jié)果。從圖中可以看出,F(xiàn)OUT的輸出頻率隨D的變化而變化,實(shí)現(xiàn)了數(shù)控分頻。圖7-11數(shù)控分頻器的仿真結(jié)果

6.引腳鎖定下載硬件驗(yàn)證將設(shè)計(jì)下載到實(shí)驗(yàn)開(kāi)發(fā)系統(tǒng)中,觀察實(shí)際運(yùn)行情況。選實(shí)驗(yàn)電路模式1,鍵2/鍵1負(fù)責(zé)輸入8位預(yù)置數(shù)D(PIO7~PIO0),CLK由clock0輸入,頻率選65536Hz或更高(確保分頻后落在音頻范圍);輸出FOUT接揚(yáng)聲器(SPKER)。編譯下載后進(jìn)行硬件測(cè)試:改變鍵2/鍵1的輸入值,可聽(tīng)到不同音調(diào)的聲音。引腳鎖定如圖7-12所示。圖7-12引腳鎖定

7.擴(kuò)展部分

(1)利用本節(jié)的數(shù)控分頻器得到的頻率,其占空比為50%。若占空比可調(diào),比如占空比為30%,如何實(shí)現(xiàn)?提示:可使用兩個(gè)8位輸入數(shù)據(jù)控制輸出脈沖的高低電平持續(xù)時(shí)間。

(2)嘗試使用其他分頻器的設(shè)計(jì)方法,例如第4章提出的方法,并比較這些方法的異同。7.4樂(lè)曲硬件演奏電路的設(shè)計(jì)

1.設(shè)計(jì)要求

(1)利用7.3節(jié)的數(shù)控分頻器設(shè)計(jì)硬件樂(lè)曲演奏電路。

(2)了解樂(lè)譜的一些基本知識(shí),可以將樂(lè)譜轉(zhuǎn)換為相應(yīng)的QuartusⅡ文件,掌握其演奏原理。

(3)掌握本設(shè)計(jì)中各模塊的功能,能夠填入并演奏一些新的曲子。

2.設(shè)計(jì)說(shuō)明樂(lè)曲演奏的原理:組成樂(lè)曲的每個(gè)音符的頻率值(音調(diào))及其持續(xù)時(shí)間(音長(zhǎng))是樂(lè)曲能連續(xù)演奏所需的兩個(gè)基本數(shù)據(jù),因此只要控制輸出到揚(yáng)聲器的激勵(lì)信號(hào)頻率的高低和持續(xù)的時(shí)間,就可以使揚(yáng)聲器發(fā)出連續(xù)的樂(lè)曲聲。

(1)音調(diào)的控制。簡(jiǎn)譜中音名與音頻的對(duì)應(yīng)關(guān)系如圖7-13所示。圖7-13簡(jiǎn)譜中音名與音頻的對(duì)應(yīng)關(guān)系圖7-13中僅列出了低音、中音和高音的頻率,對(duì)于比低音低八度或者比高音高八度的音,可依據(jù)2倍規(guī)則很容易地求出。所謂2倍規(guī)則,是指中音1是低音1頻率的2倍,高音1是中音1頻率的2倍,依此類推。簡(jiǎn)譜中音頻與分頻預(yù)置數(shù)的對(duì)應(yīng)關(guān)系如圖7-14所示。圖7-14簡(jiǎn)譜中音頻與分頻預(yù)置數(shù)的對(duì)應(yīng)關(guān)系音名與音頻的對(duì)應(yīng)關(guān)系以及計(jì)算音頻與分頻值、11位計(jì)數(shù)器的預(yù)置數(shù)的對(duì)應(yīng)關(guān)系可由程序計(jì)算得出,相應(yīng)的C語(yǔ)言程序代碼如例7-6所示。

【例7-6】計(jì)算分頻比與分頻預(yù)置數(shù)的程序。

//音名與音調(diào)之間的對(duì)應(yīng)關(guān)系的計(jì)算程序

#include<stdio.h>

#include"math.h"

#defineN3

#defineM7

main(){

int

i,j; doublea[N][M]={0.0},freq_div_ratio[N][M]={0.0},ToneIndex[N][M]={0.0};//頻率,分頻比,預(yù)置數(shù)

doubleratio,counter_11,freq=12000000;//freq為系統(tǒng)頻率,12MHz ratio=pow(2.0,1.0/12);

printf("ratio=%lf\n",ratio); //計(jì)算低音1,2,3,4,5,6,7 a[0][5]=440.0;

a[0][6]=a[0][5]*ratio*ratio;a[0][4]=a[0][5]/ratio/ratio;a[0][3]=a[0][4]/ratio/ratio;a[0][2]=a[0][3]/ratio;a[0][1]=a[0][2]/ratio/ratio;a[0][0]=a[0][1]/ratio/ratio;//計(jì)算中音和高音:1,2,3,4,5,6,7for(i=1;i<=2;i++)

{ for(j=0;j<7;j++) { a[i][j]=a[i-1][j]*2; } } //打印低中高音1,2,3,4,5,6,7 printf("音調(diào)頻率如下:0--低音,1--中音,2--高音\n"); for(i=0;i<=2;i++)

{ for(j=0;j<7;j++)

{

printf("%d音%d:%.0lf",i,j+1,a[i][j]); }

printf("\n"); } //計(jì)算各音調(diào)的分頻值

counter_11=pow(2.0,11);//分頻值對(duì)應(yīng)的位數(shù)應(yīng)為11位,該位數(shù)由系統(tǒng)頻率分頻后的頻率決定

freq=freq/(12*2);//12MHz,12分頻,再2分頻

freq=freq/(12*2);//12MHz,12分頻,再2分頻

printf("音調(diào)分頻比f(wàn)req_div_ratio如下:0--低音,1--中音,2--高音\n");

for(i=0;i<=2;i++) {

for(j=0;j<7;j++) {

freq_div_ratio[i][j]=freq/a[i][j];

printf("%d音%d:%.0lf",i,j+1,freq_div_ratio[i][j]); }

printf("\n"); } //計(jì)算各音調(diào)的分頻值相對(duì)應(yīng)的預(yù)置數(shù)

printf("音調(diào)預(yù)置數(shù)ToneIndex如下:0--低音,1--中音,2--高音\n");

for(i=0;i<=2;i++)

{

for(j=0;j<7;j++) {

ToneIndex[i][j]=counter_11-freq_div_ratio[i][j];

printf("%d音%d:%.0lf",i,j+1,ToneIndex[i][j]); }

printf("\n"); }}

(2)音長(zhǎng)的控制。音樂(lè)中的音除了有高低之分外,還有長(zhǎng)短之分。如何記錄音的長(zhǎng)短呢?簡(jiǎn)譜中用一條橫線“—”在音符的右面或下面來(lái)標(biāo)注音的長(zhǎng)短。表7-1列出了常用音符和它們的長(zhǎng)度標(biāo)記。從表7-1中可以看出橫線有記在音符后面的,也有記在音符下面的,橫線標(biāo)記的位置不同,被標(biāo)記的音符的時(shí)值也不同。從表7-1中可以發(fā)現(xiàn)一個(gè)規(guī)律:要使音符時(shí)值延長(zhǎng),在四分音符右邊加橫線“—”,這時(shí)的橫線叫延時(shí)線。延時(shí)線越多,音持續(xù)的時(shí)間(時(shí)值)越長(zhǎng)。記在音符右邊的小圓點(diǎn)稱為附點(diǎn),表示增加前面音符時(shí)值的一半,帶附點(diǎn)的音符叫附點(diǎn)音符。例如:四分附點(diǎn)音符,八分附點(diǎn)音符:。音樂(lè)中除了有音的高低、長(zhǎng)短之外,也有音的休止。表示聲音休止的符號(hào)叫休止符,用“0”標(biāo)記。每增加一個(gè)0,就增加一個(gè)四分休止符的時(shí)值。

3.設(shè)計(jì)模塊(包含模塊劃分)主系統(tǒng)由3個(gè)模塊組成,例7-7是頂層設(shè)計(jì)文件,其內(nèi)部有3個(gè)功能模塊(如圖7-15所示):ToneTaba、NoteTabs和Speakera。圖7-15硬件樂(lè)曲演奏電路結(jié)構(gòu)與利用微處理器(CPU或MCU)來(lái)實(shí)現(xiàn)樂(lè)曲演奏相比,以純硬件完成樂(lè)曲演奏電路的邏輯要復(fù)雜得多,如果不借助于功能強(qiáng)大的EDA工具和硬件描述語(yǔ)言,僅憑傳統(tǒng)的數(shù)字邏輯技術(shù),即使最簡(jiǎn)單的演奏電路也難以實(shí)現(xiàn)。本例實(shí)現(xiàn)的樂(lè)曲演奏電路結(jié)構(gòu)如圖7-15所示。在圖7-15中,模塊u1類似于彈琴的人的手指;u2類似于琴鍵;u3類似于琴弦或音調(diào)發(fā)聲器。下面首先來(lái)了解圖7-15的工作原理:

(1)音符的頻率可以由圖7-15中的模塊Speakera獲得。它是一個(gè)數(shù)控分頻器,由其clk端輸入一具有較高頻率(這里是12?MHz)的信號(hào),通過(guò)Speakera分頻后由SPKOUT輸出。由于直接從數(shù)控分頻器中出來(lái)的輸出信號(hào)是脈寬極窄的脈沖式信號(hào),為了有利于驅(qū)動(dòng)揚(yáng)聲器,需另加一個(gè)D觸發(fā)器以均衡其占空比,但這時(shí)的頻率將是原來(lái)的1/2。Speakera對(duì)clk輸入信號(hào)的分頻比由11位預(yù)置數(shù)Tone[10..0]決定。?SPKOUT的輸出頻率將決定每一音符的音調(diào)。這樣,分頻計(jì)數(shù)器的預(yù)置值Tone[10..0]與SPKOUT的輸出頻率就有了對(duì)應(yīng)關(guān)系。例如在ToneTaba模塊中若取Tone[10..0]=1036,將發(fā)音符為“3”音的信號(hào)頻率。

(2)音符的持續(xù)時(shí)間須根據(jù)樂(lè)曲的速度及每個(gè)音符的節(jié)拍數(shù)來(lái)確定,圖7-15中模塊ToneTaba的功能首先是為Speakera提供決定所發(fā)音符的分頻預(yù)置數(shù),而此數(shù)在Speakera輸入口停留的時(shí)間即為此音符的節(jié)拍值。模塊ToneTaba是樂(lè)曲簡(jiǎn)譜碼對(duì)應(yīng)的分頻預(yù)置數(shù)查表電路,其中設(shè)置了高音、中音、低音全部音符所對(duì)應(yīng)的分頻預(yù)置數(shù),共13個(gè),每一音符的停留時(shí)間由音樂(lè)節(jié)拍和音調(diào)發(fā)生器模塊NoteTabs的clk的輸入頻率決定,這里為4?Hz。這13個(gè)值的輸出由對(duì)應(yīng)于ToneTaba的4位輸入值Index[3..0]確定,而Index[3..0]最多有16種可選值。ToneIndex[3..0]輸向ToneTaba中的Index[3..0],其值與持續(xù)的時(shí)間由模塊NoteTabs決定。

(3)在NoteTabs中設(shè)置了一個(gè)9位二進(jìn)制計(jì)數(shù)器(計(jì)數(shù)最大值為512),作為音符數(shù)據(jù)ROM的地址發(fā)生器。這個(gè)計(jì)數(shù)器的計(jì)數(shù)頻率選為4Hz,即每一計(jì)數(shù)值的停留時(shí)間為0.25?s,恰為當(dāng)全音符設(shè)為1?s時(shí),四四拍的4分音符的持續(xù)時(shí)間。當(dāng)NoteTabs中的計(jì)數(shù)器按4?Hz的時(shí)鐘速率作加法計(jì)數(shù)(即地址值遞增)時(shí),音符數(shù)據(jù)ROM中的音符數(shù)據(jù)將從ROM中通過(guò)ToneIndex[3..0]端口輸向ToneTaba模塊,樂(lè)曲就開(kāi)始連續(xù)自然地演奏起來(lái)了。需定制例7-10的NoteTabs模塊中的音符數(shù)據(jù)ROM“music”。該ROM中的音符數(shù)據(jù)已列在例7-11中。注意該例數(shù)據(jù)表中的數(shù)據(jù)位寬、深度和數(shù)據(jù)的表達(dá)類型。此外,為了節(jié)省篇幅,例中的數(shù)據(jù)都橫排了,實(shí)用中應(yīng)該以每一分號(hào)為一行來(lái)展開(kāi),否則會(huì)出錯(cuò)。最后對(duì)該ROM進(jìn)行仿真,確認(rèn)例7-11中的音符數(shù)據(jù)已經(jīng)進(jìn)入ROM中。

4.代碼分析樂(lè)曲演奏電路的VerilogHDL描述見(jiàn)例7-7~例7-11。

【例7-7】硬件演奏電路的頂層設(shè)計(jì)。

module

Songer(Song_sel,CLK12MHZ,CLK8HZ,CODE1,HIGH_LOW,SPKOUT);

input[1:0]Song_sel; //對(duì)四首樂(lè)曲進(jìn)行選擇

inputCLK12MHZ; //音調(diào)頻率信號(hào)

inputCLK8HZ; //節(jié)拍頻率信號(hào)

output[3:0]CODE1; //簡(jiǎn)譜碼輸出顯示

output[1:0]HIGH_LOW; //高、中、低8度指示:00—低,01—中,10—高

outputSPKOUT; //聲音輸出

wire[10:0]Tone;

wire[4:0]ToneIndex;

NoteTabsu1(.sel(Song_sel),.clk(CLK8HZ),.ToneIndex(ToneIndex));

ToneTaba

u2(.Index(ToneIndex),.Tone(Tone),.CODE(CODE1),.HIGH(HIGH_LOW));

Speakerau3(.clk(CLK12MHZ),.Tone(Tone),.SpkS(SPKOUT));endmodule【例7-8】Speakera模塊。moduleSpeakera(clk,Tone,SpkS);inputclk;input[10:0]Tone;//分頻預(yù)置數(shù)-----跟音調(diào)相匹配outputreg

SpkS;//聲音輸出reg

PreCLK,FullSpkS;always@(posedge

clk)

begin:DivideCLK

reg[3:0]Count4;

PreCLK<=0;//將CLK進(jìn)行12分頻,PreCLK為CLK的12分頻

if(Count4>11) beginPreCLK<=1;Count4=0;end else Count4=Count4+1;endalways@(posedge

PreCLK)

begin:GenSpkS //11位可預(yù)置計(jì)數(shù)器

reg[10:0]Count11; if(Count11==11'h7FF) //首先進(jìn)行12分頻

beginCount11=Tone;FullSpkS<=1;end else beginCount11=Count11+1;FullSpkS<=0;endendalways@(posedge

FullSpkS)

begin:DelaySpkS //將輸出再2分頻,展寬脈沖,使揚(yáng)聲器有足夠功率發(fā)音

regCount2; Count2=~Count2; if(Count2==1)SpkS<=1; elseSpkS<=0;endendmodule【例7-9】ToneTaba模塊。

moduleToneTaba(Index,CODE,HIGH,Tone);

input[4:0]Index; //音符

outputreg[3:0]CODE; //簡(jiǎn)譜碼輸出

outputreg[1:0]HIGH; //高、中、低8度指示:

00—低,01—中,10—高

outputreg[10:0]Tone; //分頻預(yù)置數(shù)-----跟音調(diào)相匹配always@(Index)

begin:Search

case(Index) 5'b00000: begin Tone<=11'b11111111111; end //2047 5'b00001: begin Tone<=11'd137; end //137; 5'b00010:

begin Tone<=11'd345; end//345; 5'b00011: begin Tone<=11'd531; end//531; 5'b00100: beginTone<=11'd616;end//616;5'b00101:beginTone<=11'd773;end//773;5'b00110:beginTone<=11'd912;end//912;5'b0111:beginTone<=11'd1036;end//1036;5'b1000:beginTone<=11'd1092;end//1092;5'b1001:beginTone<=11'd1197;end//1197;5'b1010:beginTone<=11'd1290;end//1290;5'b1011:beginTone<=11'd1332;end//1332;5'b1100:beginTone<=11'd1410;end//1410;5'b1101:beginTone<=11'd1480;end//1480;5'b1110:beginTone<=11'd1542;end//15425'b1111:beginTone<=11'd1570;end//15705'b10000:beginTone<=11'd1622;end//16225'b10001:beginTone<=11'd1668;end//16685'b10010:beginTone<=11'd1690;end//16905'b10011:beginTone<=11'd1728;end//17285'b10100:beginTone<=11'd1764;end//17645'b10101:beginTone<=11'd1795;end//1795default:;endcaseendalways@(Index)begin:Encodereg[4:0]temp_Index;if(Index>=15)begin

temp_Index<=Index+2; CODE<={1'b0,temp_Index[2:0]}; HIGH<=temp_Index[4:3]; endelseif(Index>=8) begintemp_Index<=Index+1; CODE<={1'b0,temp_Index[2:0]}; HIGH<=temp_Index[4:3]; end else begin

temp_Index=Index; CODE<={1'b0,temp_Index[2:0]}; HIGH<=temp_Index[4:3]; end endendmodule【例7-10】NoteTabs模塊。moduleNoteTabs(sel,clk,ToneIndex);input[1:0]sel; //樂(lè)曲選擇信號(hào)inputclk;output[4:0]ToneIndex; //樂(lè)曲曲譜中的音符輸出reg[9:0]Counter; //計(jì)數(shù)器的位數(shù)應(yīng)該根據(jù)存放音樂(lè)的ROM進(jìn)行調(diào)整always@(posedge

clk)begin:CNT8if(sel==2'b00)//多個(gè)曲子可放在ROM中,通過(guò)按鍵進(jìn)行選擇

if(Counter>=88)Counter<=8'd0;//演奏21個(gè)音調(diào),從低到高

elseCounter<=Counter+1; //此處可通過(guò)sel選擇其他曲目播放

end

musicu1(.address(Counter),.q(ToneIndex),.inclock(clk));

endmodule【例7-11】演奏從低音到高音共21個(gè)音調(diào)的ROM文件。WIDTH=8;DEPTH=88;ADDRESS_RADIX=UNS;DATA_RADIX=UNS;CONTENTBEGIN[0..3]:0; [4..7]:1;[8..11]:2; [12..15]:3;[16..19]:4; [20..23]:5;[24..27]:6; [28..31]:7;[32..35]:8; [36..39]:9;[40..43]:10; [44..47]:11;[48..51]:12; [52..55]:13;[56..59]:14; [60..63]:15;[64..67]:16; [68..71]:17;[72..75]:18; [76..79]:19;[80..83]:20; [84..87]:21;END;

5.仿真分析請(qǐng)讀者自行仿真。

6.引腳鎖定下載硬件驗(yàn)證實(shí)驗(yàn)電路結(jié)構(gòu)圖為No.1。先將引腳鎖定,使CLK12MHZ與clock9相接,接收12MHz時(shí)鐘頻率(用短路帽將clock9接“CLK12MHZ”);CLK8HZ與clock2相接,接收4Hz頻率;發(fā)音輸出SPKOUT接Speaker;與演奏發(fā)音相對(duì)應(yīng)的簡(jiǎn)譜碼輸出顯示可由CODE1在數(shù)碼管5顯示;HIGH_LOW為高、中、低八度音指示,可由發(fā)光管D6/D5指示。最后向目標(biāo)芯片下載適配后的SOF邏輯設(shè)計(jì)文件。引腳鎖定如圖7-16所示。圖7-16引腳鎖定

7.擴(kuò)展部分

(1)填入新的樂(lè)曲,如“梁?!被蚱渌煜さ臉?lè)曲。操作步驟如下:①根據(jù)所填樂(lè)曲可能出現(xiàn)的音符,修改例7-11中的音符數(shù)據(jù),同時(shí)注意每一音符的節(jié)拍長(zhǎng)短。②如果樂(lè)曲比較長(zhǎng),可增加模塊NoteTaba中計(jì)數(shù)器的位數(shù),如設(shè)為9位,則可有512個(gè)基本節(jié)拍。

(2)在一個(gè)ROM中裝入多首歌曲,可手動(dòng)或自動(dòng)選擇歌曲(推薦圖7-17~圖7-19所示的三首)。圖7-17梁祝的簡(jiǎn)譜圖7-18兩只老虎的簡(jiǎn)譜圖7-19難忘今宵的簡(jiǎn)譜提示:仍采用No.1電路,加入多支曲目后的引腳鎖定如圖7-20所示。圖7-20引腳鎖定用鍵8/7控制四首曲目的選擇;與演奏發(fā)音相對(duì)應(yīng)的簡(jiǎn)譜碼輸出由數(shù)碼管5顯示;HIGH_LOW為高、中、低八度音指示,可由發(fā)光管D6/D5指示。

(3)結(jié)合本實(shí)驗(yàn),讀者可以查閱電子琴相關(guān)知識(shí)并設(shè)計(jì)一個(gè)簡(jiǎn)易電子琴。

(4)考慮例7-8中的進(jìn)程DelaySpkS對(duì)揚(yáng)聲器發(fā)聲有什么影響。再考慮在電路上應(yīng)該滿足哪些條件,才能用數(shù)字器件直接輸出的方波驅(qū)動(dòng)揚(yáng)聲器發(fā)聲。7.5數(shù)字跑表和數(shù)字鐘的設(shè)計(jì)

1.設(shè)計(jì)要求

(1)計(jì)時(shí)功能:設(shè)計(jì)一個(gè)具有“百分秒、秒、分、小時(shí)”計(jì)時(shí)功能的數(shù)字跑表,可以實(shí)現(xiàn)一個(gè)小時(shí)以內(nèi)精確至百分之一秒的計(jì)時(shí)。要求具有復(fù)位和暫停功能。復(fù)位后,從00:00:00:00開(kāi)始計(jì)數(shù);暫停后,保持現(xiàn)有計(jì)數(shù)值不變。

(2)校準(zhǔn)功能:根據(jù)當(dāng)前時(shí)間校準(zhǔn)鬧鐘。即增加一個(gè)校時(shí)鍵,增加時(shí)、分預(yù)置初值按鈕,這樣可以對(duì)小時(shí)、分鐘進(jìn)行校準(zhǔn)。

2.設(shè)計(jì)說(shuō)明本例主要實(shí)現(xiàn)了計(jì)數(shù)及進(jìn)位的設(shè)計(jì)。本數(shù)字跑表首先要從最低位的百分秒計(jì)數(shù)器開(kāi)始,按照系統(tǒng)時(shí)鐘進(jìn)行計(jì)數(shù)。計(jì)數(shù)至100后向秒計(jì)數(shù)器進(jìn)位,秒計(jì)數(shù)器以百分秒計(jì)數(shù)器的進(jìn)位位為時(shí)鐘進(jìn)行計(jì)數(shù),計(jì)數(shù)至60后向分計(jì)數(shù)器進(jìn)位,分計(jì)數(shù)器以秒計(jì)數(shù)器的進(jìn)位位為時(shí)鐘進(jìn)行計(jì)數(shù),計(jì)數(shù)至60后向小時(shí)計(jì)數(shù)器進(jìn)位,小時(shí)計(jì)數(shù)器以分計(jì)數(shù)器的進(jìn)位位為時(shí)鐘進(jìn)行計(jì)數(shù),如圖7-21所示。圖7-21設(shè)計(jì)說(shuō)明注意:本設(shè)計(jì)要根據(jù)頻率輸入,將頻率分頻得到0.01Hz的頻率,用于百分秒的計(jì)數(shù)脈沖。

3.設(shè)計(jì)模塊(包含模塊劃分)模塊可劃分為以下幾個(gè)部分:一是分、秒、百分秒實(shí)現(xiàn)模塊;二是小時(shí)實(shí)現(xiàn)模塊;三是顯示譯碼模塊。采用自頂向下的設(shè)計(jì),頂層模塊如圖7-22所示。圖7-22數(shù)字跑表與數(shù)字鐘的頂層模塊設(shè)計(jì)圖7-22中的端口信號(hào)定義如下:CLK_100Hz:時(shí)鐘信號(hào),100Hz。RST:異步復(fù)位信號(hào)。PAUSE:暫停信號(hào)。MSH、MSL:百分秒的高位和低位。SH、SL:秒的高位和低位。MH、ML:分的高位和低位。各模塊說(shuō)明如下:

(1)分、秒、百分秒實(shí)現(xiàn)模塊:可采用十進(jìn)制計(jì)數(shù)器、六進(jìn)制計(jì)數(shù)器完成整個(gè)分、秒和百分秒的設(shè)計(jì)。

(2)小時(shí)實(shí)現(xiàn)模塊:直接采用二十四進(jìn)制計(jì)數(shù)器實(shí)現(xiàn)即可,具體實(shí)現(xiàn)見(jiàn)代碼分析部分。

(3)顯示譯碼模塊:見(jiàn)本章7.2節(jié)。

4.代碼分析本設(shè)計(jì)的代碼如例7-12~7-14所示。

【例7-12】十進(jìn)制計(jì)數(shù)器。

modulepiaobiao_cnt10(reset,clk,count,cout);

inputreset,clk;

outputreg[3:0]count;

outputreg

cout;always@(posedge

reset,posedge

clk)

if(reset)count=0; elseif(count==9)begincount=0;cout=1;end elsebegincount=count+1;cout=0;endendmodule【例7-13】六進(jìn)制計(jì)數(shù)器。

modulepiaobiao_cnt6(reset,clk,count,cout);

inputreset,clk;

outputreg[2:0]count;

outputreg

cout;

always@(posedge

reset,posedge

clk)

if(reset)count=0;

elseif(count==5)begincount=0;cout=1;end elsebegincount=count+1;cout=0;end

endmodule【例7-14】二十四進(jìn)制計(jì)數(shù)器。

modulepiaobiao_cnt24(reset,clk,pause,HL,HH,cout);

inputreset,clk,pause;

output[3:0]HL,HH;

outputreg

cout;

reg[4:0]count;

assignHL=count%10, HH=count/10;

always@(posedge

reset,posedge

clk)if(reset)count=0; elseif(!pause)

if(count==23)begincount=0;cout=1;end elsebegincount=count+1;cout=0;endendmodule

5.仿真分析為了仿真方便,設(shè)定CLK_100Hz的時(shí)鐘周期為10ns(當(dāng)然也可以采用實(shí)際的時(shí)鐘周期10?ms,對(duì)于功能仿真來(lái)說(shuō)沒(méi)有本質(zhì)的區(qū)別)。整個(gè)仿真波形如圖7-23所示。其中能夠說(shuō)明設(shè)計(jì)正確性的部分仿真波形如圖7-24~圖7-26所示。圖7-23仿真波形圖7-24RST功能圖7-25PAUSE功能圖7-26分、秒、百分秒計(jì)時(shí)功能

6.引腳鎖定下載硬件驗(yàn)證采用電路結(jié)構(gòu)No.5,引腳設(shè)置如圖7-27所示:RST接按鍵1,PAUSE接按鍵2,百分秒顯示用數(shù)碼管1和2,秒顯示用數(shù)碼管3和4,分顯示用數(shù)碼管5和6,小時(shí)顯示用數(shù)碼管7和8。

CLK_100Hz接clock0,頻率選擇256?Hz,觀察并驗(yàn)證整個(gè)跑表的設(shè)計(jì)。圖7-27引腳鎖定

7.擴(kuò)展部分

(1)校時(shí)功能。增加一個(gè)校時(shí)鍵,增加4個(gè)時(shí)、分預(yù)置初值按鍵,分別用來(lái)調(diào)整時(shí)、分的各位。這一步由讀者自己完成。

(2)鬧鐘功能。增加一個(gè)鬧鐘功能鍵,同時(shí)使用校時(shí)功能中用到的4個(gè)銨鍵來(lái)設(shè)置鬧鐘時(shí)間。如果當(dāng)前時(shí)間與設(shè)置的鬧鐘時(shí)間相同,則揚(yáng)聲器發(fā)出蜂鳴聲。

(3)思考對(duì)于任意系統(tǒng)頻率,比如6MHz或者256Hz,如何獲得100Hz的百分秒頻率。例7-15給出了將256Hz轉(zhuǎn)換成100Hz的一種實(shí)現(xiàn)代碼,讀者也可以采用其他方法實(shí)現(xiàn)?!纠?-15】輸入256Hz,輸出100Hz。

modulefreq_256_100(rst,clk,en,clk_100Hz);

inputrst,clk,en;//clk為256Hz輸入

outputregclk_100Hz;

reg[7:0]temp;

reg[7:0]temp_1,temp_2;

always@(posedge

clk)

begin

if(rst)temp<=0; elseif(en)

if(temp==255)temp<=0; elsetemp<=temp+1; temp_1<=(200*temp+128)/256; //加128的作用是四舍五入

temp_2<=temp_1; if((temp_1>temp_2)|(temp_2==200))clk_100Hz=~clk_100Hz;endendmodule本例的仿真波形如圖7-28所示。圖7-28256Hz轉(zhuǎn)換為100Hz的仿真波形

(4)試設(shè)計(jì)一萬(wàn)進(jìn)制計(jì)數(shù)器。提示:對(duì)于任意計(jì)數(shù)器,可以采用小位數(shù)計(jì)數(shù)器級(jí)聯(lián)進(jìn)行設(shè)計(jì),這是計(jì)數(shù)器的設(shè)計(jì)技巧之一。比如,對(duì)于一萬(wàn)進(jìn)制計(jì)數(shù)器,可以采用兩個(gè)一百進(jìn)制計(jì)數(shù)器的級(jí)聯(lián),也可以采用四個(gè)十進(jìn)制計(jì)數(shù)器的級(jí)聯(lián)。從設(shè)計(jì)所占的面積和速度而言,采用4個(gè)十進(jìn)制計(jì)數(shù)器級(jí)聯(lián)的效果更好。7.6用VerilogHDL狀態(tài)機(jī)實(shí)現(xiàn)A/D

采樣控制電路

1.設(shè)計(jì)要求(1)理解并掌握ADC0809芯片的工作時(shí)序要求。(2)采用狀態(tài)機(jī)來(lái)設(shè)計(jì)A/D轉(zhuǎn)換器ADC0809的采樣控制電路。

2.設(shè)計(jì)說(shuō)明

ADC0809是CMOS的8位A/D轉(zhuǎn)換器,片內(nèi)有8路模擬開(kāi)關(guān),可控制8個(gè)模擬量中的一個(gè)進(jìn)入轉(zhuǎn)換器。轉(zhuǎn)換時(shí)間約為100μs,ADC0809含鎖存控制的8路開(kāi)關(guān),輸出由三態(tài)緩沖器控制,單5V電源供電。主要控制信號(hào)如圖7-29所示。START是轉(zhuǎn)換啟動(dòng)信號(hào),高電平有效。ALE是3位通道選擇地址信號(hào)(ADDC、ADDB、ADDA)的鎖存信號(hào)。當(dāng)模擬量送至某一輸入端(如IN1或IN2等)時(shí),由3位地址信號(hào)選擇,而地址信號(hào)由ALE鎖存。EOC是轉(zhuǎn)換狀態(tài)信號(hào),轉(zhuǎn)換開(kāi)始后EOC為低電平,當(dāng)啟動(dòng)轉(zhuǎn)換約100μs后,EOC由負(fù)變正,以示轉(zhuǎn)換結(jié)束。在EOC的上升沿后,若使輸出使能信號(hào)OE為高電平,則控制打開(kāi)三態(tài)緩沖器,把轉(zhuǎn)換好的8位數(shù)據(jù)結(jié)果輸至數(shù)據(jù)總線,至此ADC0809的一次轉(zhuǎn)換結(jié)束。圖7-29ADC0809工作時(shí)序根據(jù)圖7-29,我們可以采用圖7-30描述的狀態(tài)圖控制ADC0809進(jìn)行采樣。圖7-30控制ADC0809采樣的狀態(tài)圖

3.設(shè)計(jì)模塊(包含模塊劃分)本設(shè)計(jì)僅涉及一個(gè)狀態(tài)機(jī),采用一個(gè)模塊即可。采樣控制模塊端口框圖如圖7-31所示,端口信號(hào)與圖7-29中的信號(hào)是一致的。圖7-31采樣控制模塊端口框圖其內(nèi)部結(jié)構(gòu)如圖7-32所示。圖7-32采樣控制模塊的內(nèi)部結(jié)構(gòu)

4.代碼分析根據(jù)圖7-30,可以得出由VerilogHDL描述的采樣控制狀態(tài)機(jī),如例7-16所示。

【例7-16】VerilogHDL狀態(tài)機(jī)的A/D采樣控制電路實(shí)現(xiàn)。

module

ADCINT_v(D,CLK,EOC,ALE,START,OE,ADDA,LOCK0,Q);

input[7:0]D; //來(lái)自0809轉(zhuǎn)換好的8位數(shù)據(jù)

inputCLK; //狀態(tài)機(jī)工作時(shí)鐘

inputEOC; //轉(zhuǎn)換狀態(tài)指示,低電平表示正在轉(zhuǎn)換

outputregALE;//8個(gè)模擬信號(hào)通道地址鎖存信號(hào)outputregOE; //數(shù)據(jù)輸出三態(tài)控制信號(hào)outputADDA; //信號(hào)通道最低位控制信號(hào)outputLOCK0; //觀察數(shù)據(jù)鎖存時(shí)鐘output[7:0]Q; //8位數(shù)據(jù)輸出parameterst0=3‘b000, //定義各狀態(tài)子類型

st1=3'b001, st2=3'b010, st3=3'b011, st4=3'b100;reg[2:0]current_state,next_state;reg[7:0]REGL;regLOCK; //轉(zhuǎn)換后數(shù)據(jù)輸出鎖存時(shí)鐘信號(hào)assignADDA=1'b1;//當(dāng)ADDA<=1'b0時(shí),模擬信號(hào)進(jìn)入通道IN0;當(dāng)ADDA<=1'b1時(shí),模擬信//號(hào)進(jìn)入通道IN1assignQ=REGL,LOCK0=LOCK;always@(current_state,EOC)//規(guī)定各狀態(tài)轉(zhuǎn)換方式

begin:COMcase(current_state)st0: begin ALE<=1'b0;START<=1'b0;LOCK<=1'b0;OE<=1'b0;

next_state<=st1; //0809初始化

end st1: begin ALE<=1'b1;START<=1'b1;LOCK<=1'b0;OE<=1'b0;

next_state<=st2; //啟動(dòng)采樣

endst2: begin ALE<=1'b0;START<=1'b0;LOCK<=1'b0;OE<=1'b0;

if(EOC==1)next_state<=st3; //EOC=1表明轉(zhuǎn)換結(jié)束

elsenext_state<=st2; //轉(zhuǎn)換未結(jié)束,繼續(xù)等待

endst3:

begin ALE<=1'b0;START<=1'b0;LOCK<=1'b0;OE<=1'b1;

next_state<=st4; //開(kāi)啟OE,輸出轉(zhuǎn)換好的數(shù)據(jù)

endst4:

begin ALE<=1'b0;START<=1'b0;LOCK<=1'b1;OE<=1'b1;

next_state<=st0;

enddefault:

next_state<=st0;

endcaseendalways@(posedgeCLK)

begin:REG

current_state<=next_state;end//由信號(hào)current_state將當(dāng)前狀態(tài)值帶出此進(jìn)程:REGalways@(posedgeLOCK)begin:LATCH1 ?REGL<=D;end//此進(jìn)程中,在LOCK的上升沿,將轉(zhuǎn)換好的數(shù)據(jù)鎖入endmodule

5.仿真分析請(qǐng)讀者自行仿真。需要說(shuō)明的是,設(shè)置采樣控制的輸入信號(hào)時(shí),其工作時(shí)序要按照?qǐng)D7-29的要求給出,這樣才能得到正確結(jié)果。

6.引腳鎖定下載硬件驗(yàn)證用硬件驗(yàn)證例7-16電路對(duì)ADC0809的控制功能。測(cè)試步驟:建議選擇電路模式No.5,ADC0809的轉(zhuǎn)換時(shí)鐘CLK已經(jīng)事先接有750?kHz的頻率,引腳鎖定為:START接PIO34,OE(ENABLE)接PIO35,EOC接PIO8,ALE接PIO33,狀態(tài)機(jī)時(shí)鐘CLK接clock0,ADDA接PIO32(ADDB和ADDC都接GND),ADC0809的8位輸出數(shù)據(jù)線接PIO23~PIO16,鎖存輸出Q顯示于數(shù)碼管8/數(shù)碼管7(PIO47~PIO40)。實(shí)驗(yàn)操作:將GW48EDA系統(tǒng)左下角的撥碼開(kāi)關(guān)的4、6、7向下?lián)?,其余向上,即?809工作使能,并且使FPGA能接受來(lái)自0809轉(zhuǎn)換結(jié)束的信號(hào)。下載ADC0809中的ADCINT.sof到實(shí)驗(yàn)板的FPGA中;clock0的短路帽可選12MHz、6MHz、65536Hz等頻率;按動(dòng)一次右側(cè)的復(fù)位鍵;用螺絲刀旋轉(zhuǎn)GW48系統(tǒng)左下角的精密電位器,以便為ADC0809提供變化的待測(cè)模擬信號(hào)(注意,這時(shí)必須在例7-16中賦值:ADDA=1'b1,這樣就能通過(guò)實(shí)驗(yàn)系統(tǒng)左下的AIN1輸入端與電位器相接,并將信號(hào)輸入0809的IN1端)。這時(shí)數(shù)碼管8和7將顯示ADC0809采樣的數(shù)字值(十六進(jìn)制),數(shù)據(jù)來(lái)自FPGA的輸出。數(shù)碼管2和1也將顯示同樣的數(shù)據(jù),此數(shù)據(jù)直接來(lái)自0809的數(shù)據(jù)口。實(shí)驗(yàn)結(jié)束后注意將撥碼開(kāi)關(guān)撥向默認(rèn)狀態(tài),即僅“4”向下,其余向上。注意:可變電阻順時(shí)針旋轉(zhuǎn)可使采樣值變小,逆時(shí)針旋轉(zhuǎn)可使采樣值變大。引腳鎖定如圖7-33所示。圖7-33引腳鎖定

7.擴(kuò)展部分

(1)在本實(shí)驗(yàn)的基礎(chǔ)上增加存儲(chǔ)器,用于存儲(chǔ)A/D轉(zhuǎn)換后的數(shù)據(jù),設(shè)計(jì)一個(gè)簡(jiǎn)易存儲(chǔ)示波器。

(2)若不采用集成電路芯片ADC0809,可否采用比較器和D/A器件實(shí)現(xiàn)A/D轉(zhuǎn)換功能。請(qǐng)查閱相關(guān)資料,并給出電路設(shè)計(jì)。7.7交通控制器的設(shè)計(jì)

1.設(shè)計(jì)要求實(shí)現(xiàn)一個(gè)常見(jiàn)的十字路口交通燈控制功能。一個(gè)十字路口的交通燈一般分為兩個(gè)方向,每個(gè)方向具有紅燈、綠燈和黃燈3種。具體要求如下:

(1)十字路口包含A、B兩個(gè)方向的車道。A方向放行1分鐘(綠55s,黃5s),同時(shí)B方向禁行(紅60s);然后A方向禁行1分鐘(紅60s),同時(shí)B方向放行(綠燈55s,黃燈5s)。依此類推,循環(huán)往復(fù)。

(2)實(shí)現(xiàn)正常的倒計(jì)時(shí)功能,用2組數(shù)碼管作為A和B兩個(gè)方向的倒計(jì)時(shí)顯示。

(3)當(dāng)遇特殊情況時(shí),可通過(guò)按hold鍵來(lái)實(shí)現(xiàn)特殊的功能。使A、B方向的紅燈亮并且警告燈不停閃爍;計(jì)數(shù)器停止計(jì)數(shù)并保持在原來(lái)的狀態(tài);特殊情況處理完畢后可通過(guò)按hold鍵使交通燈正常運(yùn)行,并正常計(jì)數(shù)。

(4)系統(tǒng)已有時(shí)鐘為64?Hz。

2.設(shè)計(jì)說(shuō)明本設(shè)計(jì)的重點(diǎn)在于:

(1)分頻器設(shè)計(jì),根據(jù)已有時(shí)鐘頻率獲得需要的時(shí)鐘頻率。

(2)交通控制器設(shè)計(jì),根據(jù)計(jì)時(shí)時(shí)間來(lái)控制交通燈與數(shù)碼管。

3.設(shè)計(jì)模塊(包含模塊劃分)本設(shè)計(jì)可劃分為三個(gè)模塊:一是分頻器模塊;二是交通燈控制器模塊;三是顯示譯碼模塊。圖7-34為整體設(shè)計(jì)框圖,圖中未包含顯示譯碼模塊,僅顯示了前兩個(gè)模塊。圖7-34交通控制器模塊框圖圖7-34中:

Clk64Hz:64Hz系統(tǒng)時(shí)鐘;

reset:系統(tǒng)復(fù)位信號(hào);

HOLD:人工按鈕,用于特殊狀態(tài),此時(shí)兩組路燈都顯示紅燈并且閃爍;

RedA、GreenA、YellowA、RedB、GreenB、YellowB:分別為A、B車道的紅、綠、黃燈信號(hào);

DispA:用于A方向燈的時(shí)間顯示,8位,可驅(qū)動(dòng)兩個(gè)數(shù)碼管;

DispB:用于B方向燈的時(shí)間顯示,8位,可驅(qū)動(dòng)兩個(gè)數(shù)碼管。對(duì)圖7-34中兩個(gè)模塊的說(shuō)明:

(1)分頻器模塊。分頻器模塊的作用是將現(xiàn)實(shí)可用的時(shí)鐘分頻至1Hz,以供交通控制器模塊使用。本例中可用的輸入時(shí)鐘頻率為64Hz。

(2)交通燈控制器模塊。交通燈控制器模塊是本設(shè)計(jì)的核心,它使交通燈按既定要求變化。

4.代碼分析

【例7-17】分頻器模塊。

moduletraffic_cnt64_v(clk64Hz,clk1Hz);

inputclk64Hz;

outputclk1Hz;

reg[5:0]count;

always@(posedgeclk64Hz)

count=count+1;

assignclk1Hz=count[5];

endmodule

【例7-18】交通燈控制器模塊。

module

traffic_control_v(clk,reset,hold,RedA,GreenA,YellowA,RedB,GreenB,YellowB,Flash,DispA,DispB);

inputclk,reset,hold; //本clk頻率為1Hz

outputreg

RedA,GreenA,YellowA,RedB,GreenB,YellowB,Flash;

output[7:0]DispA,DispB;

reg[5:0]NumA,NumB;

//中間變量用于計(jì)數(shù)

integercount;

assignDispA[7:4]=NumA/10, //用于向數(shù)碼管送顯示數(shù)據(jù),A方向十位

DispA[3:0]=NumA%10; //用于向數(shù)碼管送顯示數(shù)據(jù),A方向個(gè)位

assignDispB[7:4]=NumB/10, //用于向數(shù)碼管送顯示數(shù)據(jù),B方向十位

DispB[3:0]=NumB%10; //用于向數(shù)碼管送顯示數(shù)據(jù),B方向個(gè)位

always@(posedge

reset,posedge

clk)

beginif(reset)count=0; //復(fù)位信號(hào),將計(jì)數(shù)器清零

elseif(hold)Flash=~Flash; else begin Flash=0;

if(count==119)count=0; elsecount=count+1; endendalways@(posedge

clk)begin

if(hold) //hold信號(hào)有效期間,交通燈閃爍

begin

RedA<=1'b1;GreenA<=1'b0;YellowA<=1'b0;

RedB<=1'b1;GreenB<=1'b0;YellowB<=1'b0; endelse//hold無(wú)效期間,系統(tǒng)行為,交通燈按既定方式循環(huán)運(yùn)行

if(count<55) //前55s,A燈為綠,B燈為紅

begin

NumA<=55-count;

NumB<=60-count;

RedA<=1'b0;GreenA<=1'b1;YellowA<=1'b0;

RedB<=1'b1;GreenB<=1'b0;YellowB<=1'b0; endelseif(count<60) //55~60s,A燈為黃,B燈為紅

begin

NumA<=60-count;

NumB<=60-count;

RedA<=1'b0;GreenA<=1'b0;YellowA<=1'b1;

RedB<=1'b1;GreenB<=1'b0;YellowB<=1'b0; end

elseif(count<115) //60~115s,A燈為紅,B燈為綠

begin

NumA<=120-count;

NumB<=115-count;

RedA<=1'b1;GreenA<=1'b0;YellowA<=1'b0;

RedB<=1'b0;GreenB<=1'b1;YellowB<=1'b0; en

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論