2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩28頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p><b>  模擬信號處理</b></p><p><b>  一、實驗題目2</b></p><p><b>  二、實驗?zāi)康?</b></p><p><b>  三、設(shè)計內(nèi)容2</b></p><p><b>  四、

2、實驗原理2</b></p><p>  4.1 ADC0804芯片介紹2</p><p>  4.1.1 ADC0804工作過程4</p><p>  4.1.2 ADC0804 轉(zhuǎn)換器的工作時序圖及轉(zhuǎn)換步驟6</p><p>  4.1.3 ADC0804的轉(zhuǎn)換精度7</p><p>  

3、4.1.4 AD轉(zhuǎn)換的轉(zhuǎn)換公式7</p><p>  4.2 矩陣鍵盤原理8</p><p>  4.3 報警電路原理9</p><p><b>  五、實驗思路10</b></p><p>  5.1 ADC0804模塊10</p><p>  5.2 鍵盤模塊11</p&g

4、t;<p>  六、實驗流程圖13</p><p>  6.1 AD轉(zhuǎn)換過程13</p><p>  6.2 鍵盤實現(xiàn)過程13</p><p>  七、實驗收獲及心得體會14</p><p><b>  八、附錄15</b></p><p><b>  一、實驗題

5、目</b></p><p><b>  模擬信號處理</b></p><p><b>  二、實驗?zāi)康?lt;/b></p><p>  1、學(xué)習(xí)Verilog HDL的設(shè)計技巧</p><p>  2、學(xué)習(xí)ADC0804模塊工作原理</p><p>  3、掌握ADC

6、0804控制邏輯設(shè)計技術(shù)</p><p><b>  三、設(shè)計內(nèi)容</b></p><p>  學(xué)習(xí)ADC0804模塊的工作原理,利用ADC0804對外部輸入的模擬信號進行采用獲取當(dāng)前電壓值,在數(shù)碼管上顯示。</p><p><b>  四、實驗原理</b></p><p>  4.1 ADC080

7、4芯片介紹 </p><p><b>  1功能:</b></p><p>  A/D轉(zhuǎn)換器就是模擬/數(shù)字轉(zhuǎn)換器(ADC),是將輸入的模擬信號轉(zhuǎn)換成數(shù)字信號。信號輸入端可以是傳感器或轉(zhuǎn)換器的輸出,而ADC的數(shù)字信號也可能提供給微處理器,以便更廣泛的應(yīng)用。</p><p>  2 ADC0804的規(guī)格及引腳圖:</p><p

8、>  8位CMOS依次逼近型的A/D轉(zhuǎn)換器。</p><p><b>  三態(tài)鎖定輸出</b></p><p>  存取時間:135us</p><p><b>  分辨率:8位</b></p><p>  轉(zhuǎn)換時間:100us</p><p>  總誤差:正負1LSB

9、</p><p>  工作溫度:ADC0804LCN—0_70度</p><p>  引腳圖及說明圖如圖4.1.1所示:</p><p>  圖4.1.1 ADC0804的引腳圖</p><p>  /CS:芯片選擇信號。</p><p>  /RD:外部讀取轉(zhuǎn)換結(jié)果的控制輸出信號。/RD為高電平,8個數(shù)字輸出口處理高

10、阻抗,/RD為低電平時數(shù)字數(shù)據(jù)才會輸出。</p><p>  /WR:用來啟動轉(zhuǎn)換的控制輸入,相當(dāng)于ADC轉(zhuǎn)換的開始(CS=0時),/WR由高電平變?yōu)榈碗娖剑D(zhuǎn)換器被清除,/WR回到高電平時,轉(zhuǎn)換正式開始。</p><p>  CLK_IN和CLK_R:時鐘輸入或接振蕩元件(R.C),頻率限制在100KHZ~1460KHZ,如果使用RC電路,振蕩頻率為1/(1.1RC)。</p>

11、;<p>  /INTR:中斷請求信號輸出,低電平動作。INTR 是轉(zhuǎn)換結(jié)束信號輸出端,輸出跳轉(zhuǎn)為低電平表示本次轉(zhuǎn)換已經(jīng)完成,可作為微處理器的中斷或查詢信號。如果將/CS 和/WR 端與/INTR 端相連,則ADC0804 就處于自動循環(huán)轉(zhuǎn)換狀態(tài)。</p><p>  VIN(+)和VIN(-):差動模擬電壓輸入,輸入單端正電壓時,VIN(-)接地。差動輸入時直接接VIN(+) VIN(-)。&l

12、t;/p><p>  AGND:模擬信號接地。</p><p>  DGND:數(shù)字信號接地。</p><p>  VREF/2:輔助參考電壓。</p><p>  DB0~DB7:8位的數(shù)字輸出。</p><p>  VCC:電源供應(yīng)以及作為電路的參考電壓。</p><p>  引腳功能及應(yīng)用特性如

13、下: /CS 、/RD 、/WR (引腳1、2、3):是數(shù)字控制輸入端,滿足標準TTL 邏輯電平。其中/CS 和/WR用來控制A/D 轉(zhuǎn)換的啟動信號。/CS 、/RD 用來讀A/D 轉(zhuǎn)換的結(jié)果,當(dāng)它們同時為低電平時,輸出數(shù)據(jù)鎖存器DB0~DB7 各端上出現(xiàn)8位并行二進制數(shù)碼。</p><p>  CLKIN(引腳4)和CLKR(引腳19):ADC0801~0805片內(nèi)有時鐘電路,只要在外部“CLKI”和“CLKR

14、”兩端外接一對電阻電容即可產(chǎn)生A/D轉(zhuǎn)換所要求的時鐘,其振蕩頻率為fclk≈1/1.1RC。其典型應(yīng)用參數(shù)為:R=10kΩ,C=150pF,fclk≈640kHz轉(zhuǎn)換時間為100us。若采用外部時鐘,則外部fclk可從CLKIN端送入,此時不接R、C允許的時鐘頻率范圍為100kHz~1460kHz。</p><p>  CS=0時,允許進行A/D轉(zhuǎn)換。WR由低跳高時A/D轉(zhuǎn)換開始,8位逐次比較需8×8=

15、64個時鐘周期,再加上控制邏輯操作,一次轉(zhuǎn)換需要66~73個時鐘周期。在典型應(yīng)用fclk=640kHz時,轉(zhuǎn)換時間約為103us~114us。當(dāng)fclk 超過640kHz,轉(zhuǎn)換精度下降,超過極限值1460kHz 時便不能正常工作。本次實驗中,選擇clk=40MHz,經(jīng)過200分頻之后,使時鐘頻率為fclk=200kHz。</p><p>  實驗箱上ADC0804的原理圖如圖4.1.2:</p>&

16、lt;p>  圖4.1.2 ADC0804原理圖</p><p>  由原理圖上可以看出ADC0804部分的各種參數(shù)設(shè)置。</p><p>  4.1.1 ADC0804工作過程</p><p>  控制ADC0804進行模擬/數(shù)字的轉(zhuǎn)換時使用的信號為CS、WD、RD三個。DB0~DB7代表轉(zhuǎn)換后的數(shù)字資料??梢苑譃槿缦虏襟E:</p><

17、p>  (1)、置CS=WR=0,RD=1,要求ADC0804開始進行模擬/數(shù)字轉(zhuǎn)換;</p><p>  (2)、置CS=WR=RD=1,此時ADC0804進行轉(zhuǎn)換動作,轉(zhuǎn)換時間>100us,INIT下降沿表示完成;</p><p>  (3)、置CS=RD=0,WD=1,向ADC0804請求讀取轉(zhuǎn)換后數(shù)據(jù);</p><p>  (4)、讀取DB0~D

18、B7的數(shù)據(jù),置CS=WR=RD=1。</p><p>  狀態(tài)轉(zhuǎn)換圖分析如下:</p><p>  我們把state作為狀態(tài)標志,共有4個值:00,01,10,11.當(dāng)state=00時,片選信號CS=寫信號WR=0,而讀信號RD=1,此時執(zhí)行寫操作,完成后延時一段時間,轉(zhuǎn)入state=01狀態(tài)。</p><p>  進入state=01狀態(tài)后,CS=WR=RD=1

19、,即0804不工作,這樣把寫入的數(shù)值存住,當(dāng)存完畢,發(fā)出INT=0信號,轉(zhuǎn)入state=10狀態(tài),若未存住,則發(fā)出INT=1,繼續(xù)第二步。</p><p>  進入state=10狀態(tài),CS=RD=0,WR=1,進行讀操作,完成后延時一段時間,轉(zhuǎn)入state=11狀態(tài)。</p><p>  進入最后一個狀態(tài)后,依然CS=RD=WR=1,這樣實現(xiàn)AD804的復(fù)位工作,再自動轉(zhuǎn)回state=0

20、0狀態(tài)。</p><p>  設(shè)s0、s1、s2、s3對應(yīng)上面所說的四種狀態(tài),轉(zhuǎn)換圖如下:</p><p>  4.1.2 ADC0804 轉(zhuǎn)換器的工作時序圖及轉(zhuǎn)換步驟</p><p>  ADC0804的工作時序圖(Timing Diagrams)如圖4.1.2所示:</p><p>  圖4.1.2:ADC0804手冊給出的ADC轉(zhuǎn)換時

21、序圖</p><p>  圖4.1.2給出的其實就是使ADC0804正確工作的軟件編程模型。由圖可見,實現(xiàn)一次ADC轉(zhuǎn)換主要包含下面三個步驟:</p><p>  1.啟動轉(zhuǎn)換:由圖4.1.2中的上部“FIGURE 10A”可知,在/CS信號為低電平的情況下,將/WR引腳先由高電平變成低電平,經(jīng)過至少tW(WR)I延時后,再將/WR引腳拉成高電平,即啟動了一次AD轉(zhuǎn)換。</p>

22、<p>  注:手冊中給出了要正常啟動AD轉(zhuǎn)換/WR的低電平保持時間tW(WR)I的最小值為100ns,即/WR拉低后延時大于100ns即可,不用太精確,只要估計插入的延時大于100ns即可。</p><p>  2.延時等待轉(zhuǎn)換結(jié)束:依然由圖4.1.2中的上部“FIGURE 10A”可知,由拉低/WR信號啟動AD采樣后,經(jīng)過1到8個Tclk+INTERNAL Tc延時后,AD轉(zhuǎn)換結(jié)束,因此,啟動轉(zhuǎn)

23、換后必須加入一個延時以等待AD采樣結(jié)束。</p><p>  注:手冊中給出了內(nèi)部轉(zhuǎn)換時間“INTERNAL Tc”的時間范圍為62~73個時鐘周期,因此延時等待時間應(yīng)該至少為8+73=81個時鐘周期。本次實驗采用外部時鐘,外部fclk可從CLKIN端送入,此時不接R、C允許的時鐘頻率范圍為100kHz~1460kHz。本實驗時鐘頻率約為fclk=200kHz,因此時鐘周期約為Tclk=1/fclk=5us。所以

24、該步驟至少應(yīng)延時81*Tclk≈405us。不用太精確,只要估計插入的延時大于405us即可。</p><p>  3.讀取轉(zhuǎn)換結(jié)果:由圖4.1.2的下部“FIGURE 10B”可知,采樣轉(zhuǎn)換完畢后,再/CS信號為低的前提下,將/RD腳由高電平拉成低電平后,經(jīng)過tACC的延時即可從DB腳讀出有效的采樣結(jié)果。</p><p>  注:手冊中給出了tACC的典型值和最大值分別為135ns和20

25、0ns,因此將/RD引腳拉低后,等待大于200ns后即可從DB0~DB7讀出有效的轉(zhuǎn)換結(jié)果。不用太精確,只要估計插入的延時大于200ns即可。</p><p>  4.1.3 ADC0804的轉(zhuǎn)換精度</p><p>  關(guān)于轉(zhuǎn)換器的轉(zhuǎn)換精度問題,用分辨率和轉(zhuǎn)換誤差來描述其轉(zhuǎn)換精度。 </p><p>  所謂分辨率,就是電路所能分辨的最小輸出電壓U(L

26、SB)與滿刻度輸出電壓U(omax)之比: </p><p>  分辨率=U(LSB)/U(omax)=1/(2^n-1) </p><p>  轉(zhuǎn)換誤差:指輸入端加滿刻度的數(shù)字量時,ADC輸出電壓的理論值與實際值之差。轉(zhuǎn)換誤差一般<0.5U(LSB) </p><p>  最小分辨電壓:U(LSB)=分辨率*U(omax)=U(oma

27、x)/(2^n-1)。由于ADC0804是個8位CMOS依次逼近型的A/D轉(zhuǎn)換器,而且原理上來說U(omax)=5V(為參考電壓),但是經(jīng)過實際測量芯片的9號管腳(Vref/2),其電壓值為2.96V,因此,根據(jù)實際情況,將參考電壓值由5V修改為Vref=5.92V。因此最小分辨電壓為5.92V/255=0.023V。</p><p>  4.1.4 AD轉(zhuǎn)換的轉(zhuǎn)換公式 </p><p>

28、;  對采樣值進行運算變換,換算出實際的滑動變阻器輸入電壓值。</p><p>  對于任何一個A/D采樣器而言,其轉(zhuǎn)換公式如下:</p><p><b>  其中:</b></p><p>  :輸入ADC的模擬電壓值。</p><p> ?。篈DC轉(zhuǎn)換后的二進制值。本試驗的ADC0804為八位。</p>

29、<p> ?。篈DC能夠表示的刻度總數(shù)。ADC0804為八位ADC,因此</p><p> ?。篈DC參考電壓值,本試驗ADC0804經(jīng)過測量后所得=5.92V。因此,對于本試驗,轉(zhuǎn)換公式為:</p><p>  4.2 矩陣鍵盤原理</p><p>  在鍵盤中按鍵數(shù)量較多時,為了減少I/O口的占用,通常將按鍵排列成矩陣形式。在矩陣式鍵盤中,每條水平線

30、和垂直線在交叉處不直接連通,而是通過一個按鍵加以連接。這樣,一個端口就可以構(gòu)成4*4=16個按鍵,比之直接將端口線用于鍵盤多出了一倍,而且線數(shù)越多,區(qū)別越明顯,比如再多加一條線就可以構(gòu)成20鍵的鍵盤,而直接用端口線則只能多出一鍵(8鍵)。由此可見,在需要的鍵數(shù)比較多時,采用矩陣法來做鍵盤是合理的。矩陣式結(jié)構(gòu)的鍵盤顯然比直接法要復(fù)雜一些,識別也要復(fù)雜一些,列線通過電阻接正電源,x[3..0]為列掃描輸出,y[3..0]為行掃描輸入。這樣,

31、當(dāng)按鍵沒有按下時,所有的輸出端都是高電平,代表無鍵按下。列線輸出是低電平,一旦有鍵按下,則輸入線就會被拉低,這樣,通過讀入輸入線的狀態(tài)就可得知是否有鍵按下了。本次實驗中,clk信號采用與AD轉(zhuǎn)換所用的時鐘信號相同,均為200kHz。</p><p>  行列式鍵盤的電路原理如圖4.2.1所示。(為了說明問題以4*4為例)</p><p>  圖4.2.1 行列式鍵盤的電路原理如圖</

32、p><p>  設(shè)置掃描信號為x[3]~x[0],行線按鍵輸入信號y[3]~y[0]與鍵值關(guān)系如表4-2所示。</p><p>  表4-1 掃描信號和行線按鍵輸入信號與按鍵之間的關(guān)系表</p><p>  4.3 報警電路原理</p><p>  由于ADC0804芯片有電壓限制,為了避免在進行AD轉(zhuǎn)換的過程中,由于操作不當(dāng)引起芯片燒毀這種

33、情況的發(fā)生,本次實驗增加了一個報警電路,當(dāng)電壓大于所設(shè)的閾值時,蜂鳴器報警。報警原理是:給PAin引腳一個方波,則蜂鳴器響,否則,蜂鳴器不報警。當(dāng)設(shè)置撥碼開關(guān)為高電平時(本次實驗設(shè)置的是第九個撥碼開關(guān)),關(guān)閉蜂鳴器報警。具體實現(xiàn)可以看附錄代碼。</p><p>  報警電路的原理圖如圖4.3所示:</p><p><b>  圖4.3 報警電路</b></p&g

34、t;<p><b>  五、實驗思路</b></p><p>  5.1 ADC0804模塊</p><p>  最初,我們想借鑒學(xué)長的程序,建立查找表的方法;但是,這種方法的弊端很多:比如,大大增加了代碼量,直接導(dǎo)致程序編譯時間過久,效率低下;而且如果要換一個長度范圍,則要完全新建一個查找表,而且這種方法會耗費大量的計算。所以,思考前后,我們決定根據(jù)A

35、DC0804的轉(zhuǎn)換公式用除法和取余的方式進行處理,即用二進制的模擬電壓值通過數(shù)制計算轉(zhuǎn)換為十進制數(shù),然后再用該數(shù)除以(255/5.92)(注:因為測得實驗箱上ADC0804芯片9號管腳的電壓為Vref/2=2.96V,因此,參考電壓Vref=5.92V)。把各個位賦值到cntq(cntq4代表個位數(shù),cntq3代表第一位小數(shù),cntq2代表第二位小數(shù),cntq1代表第三位小數(shù),cntq的顯示是在8為數(shù)碼管的后四位)。我們還將8位數(shù)碼管的

36、前三位用來顯示ADC轉(zhuǎn)換后的8位二進制值(DB0~DB7),將二進制轉(zhuǎn)換為十進制,即0~255的范圍;將各個位賦給a(a1代表百位,a2代表十位,a3代表個位)。</p><p><b>  具體實現(xiàn)如下:</b></p><p>  接著就是數(shù)碼管的顯示了。在數(shù)碼管輪換顯示的模塊當(dāng)中,最初我們只是按順序賦值于各個數(shù)碼管,但在硬件調(diào)試過程中出現(xiàn)中大量問題,比如數(shù)碼管閃

37、爍強烈,和部分不能顯示和顯示亂碼問題,后來加上了case語句,以cnt的變化做周期循環(huán),小數(shù)點直接賦值,這樣問題就消失了。</p><p>  在AD讀寫狀態(tài)的轉(zhuǎn)換中,要設(shè)定延時,來保證指令的執(zhí)行。</p><p>  但是,用除法也有不足之處,數(shù)碼管一直在閃爍,即電壓不穩(wěn)定。因為模擬量肯定不像數(shù)字量一樣穩(wěn)定,所以可以對模擬量進行濾波處理或者是通過多次采樣取平均來減小誤差,提高精度。本次實

38、驗采用的就是100次采樣取平均來減少數(shù)碼管閃爍,實驗結(jié)果證明效果很好。而且大大降低了實驗誤差(沒取平均時,誤差為0.04~0.05V,采用100次采樣取平均后,誤差縮小為0.005V)。</p><p><b>  具體實現(xiàn)過程如下:</b></p><p><b>  5.2 鍵盤模塊</b></p><p>  由于8

39、個數(shù)碼管中后4個用于顯示電壓值,前3個用于顯示ADC轉(zhuǎn)換后的8位二進制值;所以只剩下第四個數(shù)碼管。我們的思路是:</p><p>  用第四個數(shù)碼管顯示鍵盤的鍵值(只需顯示0~9即可,A~F的鍵值用不到,可以不顯示),一方面可以測試一下鍵盤電路是否準確;另一方面可以清晰的看到按鍵是否正常按下,方便后面的程序檢驗。本次實驗除了用到了數(shù)字鍵之外,只用到了A這個功能鍵,當(dāng)按下A鍵之后,可以設(shè)定一個三位數(shù)的閾值(0~25

40、5)每個數(shù)都在第四個數(shù)碼管上依次顯示,當(dāng)ADC轉(zhuǎn)換后的8位二進制值(前三個數(shù)碼管上顯示;同時前8個LED燈對應(yīng)這8個二進制數(shù),亮表示對應(yīng)位為1,不亮表示對應(yīng)位為0)大于設(shè)定的三位數(shù)的閾值之后,蜂鳴器報警。A設(shè)置鍵可以多次設(shè)置。</p><p>  由于只有一個數(shù)碼管可用,所以必須要在A鍵按下之后開始存儲接下來按下的數(shù)字鍵,并且按照順序存儲。我們通過設(shè)置3個4位的寄存器threshold來存儲鍵值。同時設(shè)置cnt2

41、來判斷按鍵次數(shù)(鍵盤程序必須有消抖功能),每按下一個鍵cnt2+1;通過判斷cnt2的值來判斷按下數(shù)字鍵的順序;同時,由于是在A鍵按下之后才開始存儲數(shù)字鍵的鍵值,因此當(dāng)判斷是A鍵按下之后,cnt2清零。</p><p>  因為設(shè)定的是一個三位數(shù),因此還需要設(shè)定一個寄存器hh用來限制存儲的數(shù)值個數(shù),當(dāng)A鍵按下之后,hh=1,然后進行存儲后面按下的三個數(shù)字鍵的鍵值,而當(dāng)按下三個數(shù)字鍵之后,即cnt2>3時,h

42、h=0;不再對后面的數(shù)字鍵值進行存儲。</p><p><b>  下面是具體實現(xiàn):</b></p><p><b>  六、實驗流程圖</b></p><p>  6.1 AD轉(zhuǎn)換過程</p><p>  6.2 鍵盤實現(xiàn)過程</p><p>  七、實驗收獲及心得體會&l

43、t;/p><p>  本次課程設(shè)計收獲良多,由于很多次實驗都有接觸過AD轉(zhuǎn)換,所以這個題目對我們來說并不陌生。雖然不陌生,但是要系統(tǒng)的實現(xiàn)一個功能的工作量也是很大的;而且本次的課程設(shè)計時間是從周二開始的,時間相對來說比較緊,所以我們充分利用了晚上的時間,每天晚上都到實驗室去調(diào)代碼。</p><p>  回顧這一周的課程設(shè)計,我們選定題目后,就上網(wǎng)去搜集相關(guān)的資料,分析ADC0804的工作原理,

44、然后針對ADC0804芯片的特點做相應(yīng)的設(shè)計。只要了解了A/D轉(zhuǎn)換的四個狀態(tài),A/D轉(zhuǎn)換部分的問題也就迎刃而解了;但是,關(guān)鍵問題是只去一次數(shù)值,用除法來做,無論怎么調(diào)節(jié)頻率,在數(shù)碼管上顯示的數(shù)值都會閃的很厲害,影響對對應(yīng)電壓的讀?。欢抑蝗∫粋€值的話,實驗誤差必然會比較大。針對這些問題,我們采取了采樣100次,然后取平均,將處理過的數(shù)據(jù)作為A/D轉(zhuǎn)換的數(shù)據(jù)輸出,這樣閃爍問題也就解決了,而且取平均也順帶解決了實驗誤差的問題,可謂一舉兩得。

45、</p><p>  完成A/D轉(zhuǎn)換的主題部分之后,我們就想在此基礎(chǔ)上添加一些附加功能:采用鍵盤程序和蜂鳴器報警電路??紤]到滑動變阻器阻值的改變會導(dǎo)致輸出電壓的改變,為了避免因調(diào)節(jié)滑動變阻器導(dǎo)致電壓過高燒毀芯片這種情況的發(fā)生,我們決定通過鍵盤設(shè)定一個閾值,當(dāng)輸出電壓高于這個閾值之后,蜂鳴器報警。由于之前有做過鍵盤程序的實驗,因此,鍵盤部分就節(jié)省了不少時間;但是設(shè)定閾值部分因為要存儲設(shè)定的數(shù)值的順序,實現(xiàn)起來相對麻

46、煩了一點;所幸的是,在同學(xué)的幫助下,我們終于調(diào)試成功了。</p><p>  總體來講,本次實驗由于是兩個人一組,兩個人的智慧肯定大于一個人的;所以,當(dāng)我們遇到什么難題的時候,經(jīng)過討論、總結(jié),最終我們都把這些困難一一解決了。這應(yīng)該算是團隊合作的精髓所在吧。這一周基本上都在實驗室待者,我個人比較享受在實驗室的時光,看大家都忙著自己的課程設(shè)計,還有調(diào)試成功時候露出欣慰的笑容,再看看自己一步一步調(diào)程序到最后成功實現(xiàn)希望

47、實現(xiàn)的功能時,這種感覺真的是非常奇妙。</p><p>  最后,感謝我的搭檔,正是因為我們兩個相互合作才有最后這個成品的誕生;同時還感謝那些在實驗室?guī)臀艺{(diào)試代碼,找出程序BUG,并給我們很多建議的同學(xué)。如果沒有他們的幫助,我們估計還得走不少彎路。</p><p><b>  八、附錄</b></p><p><b>  程序代碼如下

48、:</b></p><p>  module adc(cs,wr,rd,intr,dati,clk,scan,seg,PAin,din0,reset,y,x,out,keypress);</p><p>  output cs,wr,rd; //片選、讀、寫,控制AD轉(zhuǎn)換的</p><p>  output[7:0] scan,seg;

49、//位選、段選</p><p>  output PAin; //接蜂鳴器的,控制發(fā)聲</p><p>  output[3:0] x; //鍵盤列掃描輸出</p><p>  output [3:0]out; //存儲鍵盤鍵值</p><p>  output keypress;

50、//判斷是否有鍵按下,有鍵按下高電平輸出</p><p>  input clk,intr; //時鐘(40MHz),intr為下降沿表示AD轉(zhuǎn)換完成</p><p>  input[7:0] dati; //ADC0804DB7~DB0輸出作為CPLD的輸入</p><p>  input din0,reset; //di

51、n0接第9個撥碼開關(guān),控制蜂鳴器</p><p>  input [3:0] y; //鍵盤行掃描輸入</p><p>  reg[7:0]sm=8'b11111111; //8位的閾值初始化為255</p><p>  reg hh; //A鍵按下,hh=1,開始控制存儲按下的數(shù)字鍵鍵值</p>

52、;<p>  reg[3:0] threshold[2:0]; //用于存儲A鍵按下之后按的三個數(shù)字鍵的鍵值</p><p>  reg[2:0] cnt2; //用于判斷按下數(shù)字鍵的順序</p><p>  reg keypress; //判斷按鍵是否按下,按鍵輸出上升沿</p><p>  reg

53、[4:0] count; //消抖累加到30,合約10ms左右</p><p>  reg[3:0] x;</p><p>  reg[7:0] dato,scan; //AD轉(zhuǎn)換的輸出dato</p><p>  wire[7:0] seg;</p><p>  reg cs,wr,rd;</p>

54、;<p>  reg clk1,clk3; //分頻</p><p>  reg[7:0] fenpinclk1,fenpinclk; //用于分頻計數(shù)</p><p>  reg[15:0] fenpinclk3;</p><p>  reg[3:0] cntq1,cntq2,cntq3,cntq4,Dat; //用于存儲A

55、D轉(zhuǎn)換輸出電壓的各個位</p><p>  reg[3:0] a1,a2,a3; //用于存儲AD轉(zhuǎn)換輸出的二進制轉(zhuǎn)化為十進制值各個位</p><p>  reg[3:0] cnt; //cnt不同狀態(tài)選通不同的數(shù)碼管</p><p>  reg[1:0] state; //AD轉(zhuǎn)換

56、的四個不同的狀態(tài)之間的變換</p><p>  reg[3:0] state1,out; //鍵盤的幾個狀態(tài)</p><p><b>  reg PAin;</b></p><p>  reg[7:0]i=0; //i為采樣100次的計數(shù)器</p><

57、;p>  reg[20:0]datismt=0; //存儲采樣100次的數(shù)據(jù)之和</p><p>  parameter[1:0]s0=0,s1=1,s2=2,s3=3; //AD轉(zhuǎn)換的四個狀態(tài)</p><p>  always @(posedge clk3) //經(jīng)過分頻后,clk3=5kHz</p><

58、p><b>  begin</b></p><p>  if(dato >= sm) //超過設(shè)定的閾值之后,蜂鳴器報警</p><p><b>  begin</b></p><p>  PAin = ~PAin; //給蜂鳴器一個方波,發(fā)聲</p><

59、;p>  if(din0==1) //撥碼開關(guān)為高電平時,蜂鳴器不叫</p><p><b>  PAin=0;</b></p><p><b>  end</b></p><p><b>  end</b></p><p>  always@(pos

60、edge clk) //分頻,clk3=5kHz</p><p><b>  begin</b></p><p>  if(fenpinclk3==3999) //每4000次翻轉(zhuǎn),8000分頻,clk為40MHz,</p><p><b>  begin </b></p

61、><p>  fenpinclk3<=8'h00;</p><p>  clk3=~clk3; //clk3=5kHz</p><p><b>  end</b></p><p><b>  else</b></p><p><b&

62、gt;  begin</b></p><p>  fenpinclk3<=fenpinclk3+1;</p><p><b>  end</b></p><p><b>  end</b></p><p>  always@(posedge clk) //clk經(jīng)

63、過分頻后,變?yōu)锳D轉(zhuǎn)換所需的頻率clk1</p><p><b>  begin</b></p><p>  if(fenpinclk1==8'b0110_0011) //每100次翻轉(zhuǎn),200分頻,clk1=200kHz</p><p><b>  begin</b></p><p>

64、  fenpinclk1<=8'h00;</p><p>  clk1=~clk1; </p><p><b>  end</b></p><p><b>  else</b></p><p><b>  begin</b></p><p>

65、;  fenpinclk1<=fenpinclk1+1;</p><p><b>  end</b></p><p><b>  end</b></p><p>  ///////////////////////////////////////////////控制ADC0804轉(zhuǎn)換//////////////////

66、/////////////////////////////</p><p>  always @(posedge clk1) </p><p><b>  begin</b></p><p>  case(state)</p><p>  s0:begin //開始AD轉(zhuǎn)換<

67、;/p><p><b>  cs<=0;</b></p><p><b>  wr<=0;</b></p><p><b>  rd<=1;</b></p><p>  if(fenpinclk==8'b0110_0011) //s0->s1,延

68、時</p><p><b>  begin</b></p><p>  state<=s1;</p><p>  fenpinclk<=0;</p><p><b>  end</b></p><p><b>  else</b></p

69、><p>  fenpinclk<=fenpinclk+1;</p><p><b>  end</b></p><p>  s1:begin //ADC0804轉(zhuǎn)換中</p><p><b>  wr<=1;</b></p><p

70、><b>  cs<=1;</b></p><p><b>  rd<=1;</b></p><p>  if(intr==0) // intr=0表示轉(zhuǎn)換完成,進入下一個狀態(tài)</p><p><b>  begin</b></p><

71、;p>  state<=s2;</p><p><b>  end </b></p><p><b>  els </b></p><p>  begin state<=s1; end</p><p><b>  end </b></p><

72、;p>  s2:begin //向ADC0804請求轉(zhuǎn)換后的數(shù)據(jù)</p><p><b>  cs<=0;</b></p><p><b>  wr<=1;</b></p><p><b>  rd<=0; </b></p>

73、<p>  if(fenpinclk==8'b0110_0011) //s2->s3,延時</p><p><b>  begin</b></p><p>  state<=s3;</p><p>  fenpinclk<=0; </p><p><b>  end<

74、/b></p><p><b>  else</b></p><p>  fenpinclk<=fenpinclk+1; </p><p><b>  end </b></p><p>  s3:begin //讀取轉(zhuǎn)換后的數(shù)據(jù)(DB7~DB0)

75、</p><p><b>  cs<=1;</b></p><p><b>  wr<=1;</b></p><p><b>  rd<=1;</b></p><p>  if(i<100) //采樣100次,將所采的數(shù)據(jù)

76、求和 </p><p>  begin //值存在datismt中</p><p>  datismt=datismt+dati; </p><p><b>  i=i+1;</b></p><p>  state<=s0; //每取完一個數(shù)據(jù)之后,重新進行一次&l

77、t;/p><p>  end // AD轉(zhuǎn)換,故跳轉(zhuǎn)到s0</p><p><b>  else</b></p><p><b>  begin</b></p><p>  i=0; //取滿100個數(shù)據(jù),計數(shù)器i清零</p>

78、<p>  datismt=datismt/100; //對所采數(shù)據(jù)求和之后再取平均</p><p>  dato=datismt; //平均值賦給dato進行后面的操作</p><p>  datismt=0; //取完平均后,存儲器清零</p><p>  state<=s0; //重新進行下一輪

79、的AD轉(zhuǎn)換</p><p><b>  end</b></p><p><b>  end</b></p><p><b>  endcase</b></p><p><b>  end</b></p><p>  ///////

80、//////////////////////////數(shù)碼管后四位和前三位各個位的算法/////////////////////////////////</p><p>  // cntq4代表個位數(shù),cntq3代表第一位小數(shù),cntq2代表第二位小數(shù),cntq1代表//第三位小數(shù)。a1代表百位,a2代表十位,a3代表個位</p><p>  always@(dato)</p>

81、<p><b>  begin</b></p><p>  cntq4=dato/(25500/592); </p><p>  cntq3=((dato%(25500/592))*10)/(25500/592);</p><p>  cntq2=((((dato%(25500/592))*10)%(25500/592))*10)/

82、(25500/592); cntq1=(((((dato%(25500/592))*10)%(25500/592))*10)%(25500/592))*10/(25500/592);</p><p>  a1=dato/100;</p><p>  a2=(dato%100)/10;</p><p>  a3=(dato%100)%10;</p>

83、<p><b>  end</b></p><p>  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////</p><p>  always @(posedge

84、 clk1)</p><p><b>  begin</b></p><p>  if(cnt==4'b1000) //cnt選通數(shù)碼管并顯示</p><p>  begin //當(dāng)達到第9個狀態(tài)時返回第一個狀態(tài), </p><p>  cnt<=4

85、'b0000; //輪流掃描8個數(shù)碼管</p><p><b>  end</b></p><p><b>  else</b></p><p><b>  begin </b></p><p>  cnt<=cnt+1'b1; <

86、/p><p><b>  end </b></p><p><b>  case(cnt)</b></p><p>  4'b0000: //選通第一個數(shù)碼管,顯示百位a1</p><p><b>  begin</b></p>&

87、lt;p>  scan<=8'b10000000;</p><p><b>  Dat<=a1;</b></p><p><b>  end</b></p><p>  4'b0001: //選通第二個數(shù)碼管,顯示百位a2</p><p>

88、<b>  begin</b></p><p>  scan<=8'b01000000;</p><p><b>  Dat<=a2;</b></p><p><b>  end</b></p><p>  4'b0010:

89、 //選通第三個數(shù)碼管,顯示百位a3</p><p><b>  begin</b></p><p>  scan<=8'b00100000;</p><p><b>  Dat<=a3;</b></p><p><b>  end</b></p&g

90、t;<p>  4'b0011: //選通第5個數(shù)碼管,顯示小數(shù)點前一位cntq4</p><p><b>  begin</b></p><p>  scan<=8'b00001000; </p><p>  Dat<=cntq4;</p><p&g

91、t;<b>  end</b></p><p>  4'b0100: //選通第5個數(shù)碼管,顯示小數(shù)點</p><p><b>  begin</b></p><p>  scan<=8'B00001000; </p><p>  Dat<=

92、4'B1010; </p><p><b>  end</b></p><p>  4'b0101: //選通第6個數(shù)碼管,顯示第一位小數(shù)cntq3</p><p><b>  begin</b></p><p>  scan<=8'B00

93、000100; </p><p>  Dat<=cntq3;</p><p><b>  end </b></p><p>  4'b0110: //選通第7個數(shù)碼管,顯示第二位小數(shù)cntq2</p><p><b>  begin</b></p&g

94、t;<p>  scan<=8'B00000010;</p><p>  Dat<=cntq2;</p><p><b>  end</b></p><p>  4'b0111: //選通第8個數(shù)碼管,顯示第三位小數(shù)cntq1</p><p><

95、;b>  begin</b></p><p>  scan<=8'B00000001; </p><p>  Dat<=cntq1; </p><p><b>  end</b></p><p>  4'b1000: //這個狀態(tài)和鍵盤有關(guān)<

96、/p><p><b>  begin</b></p><p>  scan<=8'b00010000; //鍵盤的鍵值都在第四個數(shù)碼管顯示</p><p>  if((out <= 9) && (out >= 0))</p><p><b>  begin</b&

97、gt;</p><p>  Dat<=out; //顯示數(shù)字鍵的鍵值</p><p>  if(hh==1) //代表A鍵按下去且數(shù)字鍵按下的次數(shù)少于3</p><p><b>  begin</b></p><p>  case(cnt2) //A鍵按下后按數(shù)字鍵的順序</p><p&g

98、t;  1:threshold[2]<=out; //存儲第一個數(shù)字鍵</p><p>  2:threshold[1]<=out; //存儲第二個數(shù)字鍵</p><p>  3:threshold[0]<=out; //存儲第三個數(shù)字鍵</p><p><b>  endcase</b></p><p&g

99、t;  if(cnt2==3) //當(dāng)按下三個數(shù)字鍵之后,</p><p>  //計算出閾值,存儲到sm中,</p><p>  begin //與當(dāng)前輸出值比較</p><p>  sm=threshold[2]*100+threshold[1]*10+threshold[0];</p><p><b>

100、;  end</b></p><p><b>  end</b></p><p><b>  end</b></p><p><b>  end</b></p><p><b>  default:</b></p><p&g

101、t;<b>  begin</b></p><p>  scan<=8'B11111111; </p><p>  Dat<=4'B0000;</p><p><b>  end </b></p><p><b>  endcase</b><

102、/p><p><b>  end</b></p><p>  ///////////////////////////////////////////////////////鍵盤部分//////////////////////////////////////////////////////</p><p>  always@ (posedge clk

103、1)</p><p>  if(!reset) //reset鍵連接的是第一個撥碼開關(guān)</p><p>  begin //當(dāng)reset鍵為低電平時,初始化</p><p><b>  state1=0;</b></p><p>&

104、lt;b>  cnt2=0;</b></p><p><b>  end</b></p><p>  else //初始化之后,將撥碼開關(guān)設(shè)為高電平,則程序往下</p><p>  case(state1) //執(zhí)行,否則一直都在初始化,鍵盤部分就是小了</p><

105、;p>  0:begin //判斷是否所有的鍵都松開了,是則轉(zhuǎn)向1, </p><p>  x = 4'b0000; //否則循環(huán)檢測</p><p>  if(y != 4'b1111) state1 = 0;</p><p><b>  else </b></p><p&

106、gt;<b>  begin</b></p><p>  keypress = 0; </p><p>  count = 0;</p><p>  state1 = 1;</p><p><b>  end</b></p><p><b>  end</b&

107、gt;</p><p><b>  1:begin</b></p><p>  x = 4'b0000; //向四列輸出低電平,掃描是否有鍵按下</p><p>  if(y == 4'b1111) state1 = 1;</p><p><b>  else</b><

108、/p><p><b>  begin</b></p><p>  keypress = 1;</p><p>  count = count + 1;</p><p>  if(count == 30) //掃描到有鍵按下,消抖30ms, </p><p><b>  begin &

109、lt;/b></p><p>  state1 = 2; //確認有鍵按下之后轉(zhuǎn)向2,</p><p>  cnt2=cnt2+1; //按鍵計數(shù)器cnt2+1</p><p>  if(cnt2 > 3) //按鍵次數(shù)大于3次之后,</p><p>  hh=0; //不存儲之后的鍵值</p>

110、;<p><b>  end</b></p><p><b>  else</b></p><p>  state1 = 1; //如果沒鍵按下,循環(huán)掃描</p><p><b>  end</b></p><p><b>  end&

111、lt;/b></p><p><b>  2:begin </b></p><p>  x=4'b0111; //掃描第一列,轉(zhuǎn)向3</p><p><b>  state1=3;</b></p><p><b>  end</b></p&

112、gt;<p><b>  3:begin</b></p><p>  case(y) //用來判斷第一列是否有鍵按下</p><p>  4'b1111: //第一列沒鍵按下,轉(zhuǎn)向4,掃描第二列</p><p><b>  begin</b></p>

113、<p><b>  state1=4;</b></p><p><b>  end </b></p><p><b>  4'b1110:</b></p><p><b>  begin</b></p><p>  state1=0;

114、 //0</p><p><b>  out=0; </b></p><p><b>  end</b></p><p><b>  4'b1101:</b></p><p><b>  begin</b></p><p&g

115、t;  state1=0; //4</p><p><b>  out=4; </b></p><p><b>  end </b></p><p><b>  4'b1011:</b></p><p><b>  begin</b><

116、/p><p>  state1=0; //8</p><p><b>  out=8; </b></p><p><b>  end </b></p><p><b>  4'b0111: </b></p><p><b>  beg

117、in</b></p><p>  state1=0; //C</p><p><b>  out=12; </b></p><p><b>  end </b></p><p><b>  endcase</b></p><p><

118、;b>  end</b></p><p><b>  4:begin </b></p><p>  x=4'b1011; //掃描第二列 </p><p><b>  state1=5;</b></p><p><b>  end </b&

119、gt;</p><p><b>  5:begin</b></p><p><b>  case(y)</b></p><p>  4'b1111: //第二列沒鍵按下,轉(zhuǎn)向6,掃描第三列</p><p><b>  begin</b></p>

120、;<p>  state1=6; </p><p><b>  end</b></p><p><b>  4'b1110: </b></p><p><b>  begin</b></p><p>  state1=0; //1 </p>

121、<p><b>  out=1; </b></p><p><b>  end</b></p><p><b>  4'b1101: </b></p><p><b>  begin</b></p><p>  state1=0;

122、 //5</p><p><b>  out=5; </b></p><p><b>  end</b></p><p><b>  4'b1011:</b></p><p><b>  begin</b></p><p>

123、  state1=0; //9</p><p><b>  out=9; </b></p><p><b>  end </b></p><p><b>  4'b0111:</b></p><p><b>  begin</b></p&

124、gt;<p>  state1=0; //D</p><p>  //out=13; //非數(shù)字鍵,鍵值不用顯示</p><p><b>  end</b></p><p><b>  endcase</b></p><p><b>  end </b>&

125、lt;/p><p><b>  6:begin </b></p><p>  x=4'b1101; //掃描第三列,轉(zhuǎn)向7</p><p><b>  state1=7;</b></p><p><b>  end </b></p><

126、p><b>  7: begin</b></p><p><b>  case(y)</b></p><p>  4'b1111: //第三列沒鍵按下,轉(zhuǎn)向8,掃描第四列</p><p><b>  begin</b></p><p><b>

127、;  state1=8;</b></p><p><b>  end </b></p><p><b>  4'b1110:</b></p><p><b>  begin</b></p><p>  state1=0; //2</p>&

128、lt;p><b>  out=2;</b></p><p><b>  end</b></p><p><b>  4'b1101:</b></p><p><b>  begin</b></p><p>  state1=0; //6&l

129、t;/p><p><b>  out=6;</b></p><p><b>  end</b></p><p><b>  4'b1011: </b></p><p><b>  begin</b></p><p>  stat

130、e1=0; //A鍵按下之后</p><p>  hh=1; //可以開始存儲之后的數(shù)字鍵鍵值</p><p>  cnt2=0; //A鍵之前的按鍵數(shù)清零</p><p><b>  end </b></p><p><b>  4'b0111:</b></p>

131、<p><b>  begin</b></p><p>  state1=0; //E</p><p>  //out=14; //非數(shù)字鍵,不用顯示鍵值</p><p><b>  end </b></p><p><b>  endcase</b><

132、/p><p><b>  end</b></p><p><b>  8:begin </b></p><p>  x=4'b1110; //掃描第四列</p><p><b>  state1=9;</b></p><p>&

133、lt;b>  end </b></p><p><b>  9: begin</b></p><p><b>  case(y)</b></p><p>  4'b1111: //第四列也沒按鍵按下,返回</p><p><b>  begin&

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論