久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5532|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

學(xué)習(xí)FPGA信號消抖的一點(diǎn)心得 附源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:388050 發(fā)表于 2018-8-20 11:08 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
學(xué)習(xí)FPGA的一點(diǎn)心得
VHDL作業(yè)
1、寫出消抖的程序,通過仿真或下載得出對應(yīng)的波形,并分析。

FPGA對于輸入的信號一般都要經(jīng)過消抖處理,以消除干擾信號。對于兩個(gè)設(shè)備之間的數(shù)據(jù)傳輸,這一點(diǎn)顯得尤為重要。

消抖一般通過記錄脈沖的個(gè)數(shù),對輸入信號的尖峰寬度進(jìn)行限制,達(dá)不到預(yù)定的寬度,即認(rèn)為是干擾,必須加以濾除,部分代碼如下。因此,信號經(jīng)過消抖去除干擾信號以后,必然產(chǎn)生延遲,延遲時(shí)間與系統(tǒng)晶振頻率以及計(jì)數(shù)脈沖個(gè)數(shù)有關(guān)。

例如:設(shè)系統(tǒng)晶振為40MHz,消抖時(shí)間為4個(gè)CLK,一個(gè)脈沖時(shí)間為1/40M=25ns,所以信號延時(shí)為25*4=100ns,如圖1所示。

  

圖1 信號消抖示意圖

代碼示例:

(a)延時(shí)4clk

  1.        process (gclk,rst)                                            --群信號消抖
  2.               begin                           
  3.                             if rst='1' then
  4.                                sig_out<='0';
  5.                             elsif gclk'event and gclk = '1' then
  6.                                           sig_0 <= sig_in;
  7.                                           sig_1 <= sig_0;
  8.                                           sig_2 <= sig_1;
  9.                                           sig_3 <= sig_2;
  10. if ((sig_3 = sig_2) and  (sig_2 = sig_1) and (sig_1 = sig_0) and (sig_0 = sig_in)) then   
  11.                                                         sig_out <=  sig_3;
  12.                                           end if;
  13.                             end if;
  14. end process;
復(fù)制代碼


仿真結(jié)果如圖2:

圖2消抖程序仿真圖

(b) 延時(shí)4ms

  1.               process (gclk)                                    
  2.               begin
  3.                    if rst='1'  then
  4.                                signal_out<='0';
  5.                                psignal<='0';
  6.                                ppsignal<='0';
  7.                                signal_cnt<=0;            
  8.                             elsif (gclk='1') and (gclk'event) then
  9.                                 ppsignal <= psignal;
  10.                                 psignal <= signal_in;
  11.                                 if psignal /= ppsignal then
  12.                                             signal_cnt <= 0;
  13.                                 else
  14.                                             signal_cnt <= signal_cnt + 1;
  15.                                             if signal_cnt > 159999 then              ------消抖時(shí)間為4ms------
  16.                                               --if signal_cnt > 99 then
  17.                                                         signal_out <= psignal;
  18.                                             end if;                             
  19.                                 end if;
  20.                    end if;
  21.               end process;
復(fù)制代碼

仿真結(jié)果;

圖3延時(shí)仿真圖

2、測試在不同主頻、分頻下邏輯處理上的不同,并分析。
              分頻器是數(shù)字系統(tǒng)設(shè)計(jì)中的基本電路,根據(jù)不同設(shè)計(jì)的需要,我們會遇到偶數(shù)分頻、奇數(shù)分頻、半整數(shù)分頻等,有時(shí)要求等占空比,有時(shí)要求非等占空比。在同一個(gè)設(shè)計(jì)中有時(shí)要求多種形式的分頻。通常由計(jì)數(shù)器或計(jì)數(shù)器的級聯(lián)構(gòu)成各種形式的偶數(shù)分頻及非等占空比的奇數(shù)分頻,實(shí)現(xiàn)較為簡單。但對半整數(shù)分頻及等占空比的奇數(shù)分頻實(shí)現(xiàn)較為困難。本文利用VHDL硬件描述語言,可設(shè)計(jì)了一種能夠滿足上述各種要求的較為通用的分頻器。

              現(xiàn)通過設(shè)計(jì)一個(gè)可以實(shí)現(xiàn)8.5分頻,等占空比的17分頻,2、4、8、16、32分頻,及占空比為1∶8和4∶5的9分頻等多種形式分頻的分頻器。分頻器由帶使能端的異或門、模N計(jì)數(shù)器和一個(gè)2分頻器組成,本設(shè)計(jì)用D觸發(fā)器來完成2分頻的功能,實(shí)現(xiàn)方法是:將觸發(fā)器的Q反輸出端反饋回輸入端D,將計(jì)數(shù)器的一個(gè)計(jì)數(shù)輸出端作為D觸發(fā)器的時(shí)鐘輸入端。各功能模塊的VHDL語言實(shí)現(xiàn)如下。

1).模N計(jì)數(shù)器的實(shí)現(xiàn)

  一般設(shè)計(jì)中用到計(jì)數(shù)器時(shí),我們可以調(diào)用lpm庫中的計(jì)數(shù)器模塊,也可以采用VHDL語言自己設(shè)計(jì)一個(gè)模N計(jì)數(shù)器。本設(shè)計(jì)采用VHDL語言設(shè)計(jì)一個(gè)最大模值為16的計(jì)數(shù)器。輸入端口為:使能信號en,復(fù)位信號clr和時(shí)鐘信號clk;輸出端口為:qa、qb、qc、qd。其VHDL語言描述略。

 2).帶使能控制的異或門的實(shí)現(xiàn)

  輸入端為:xor_en:異或使能,a和b:異或輸入;輸出端為:c:異或輸出。當(dāng)xor_en為高電平時(shí),c輸出a和b的異或值。當(dāng)xor_en為低電平時(shí),c輸出信號b。其VHDL語言略。

3).分頻(觸發(fā)器)的實(shí)現(xiàn)

  輸入端為:時(shí)鐘信號clk,輸入信號d;輸出端為:q:輸出信號a,q1:輸出信號a反。其VHDL語言略。

以下是幾種分頻器的分析:

偶數(shù)分頻器

頻最易于實(shí)現(xiàn),欲實(shí)現(xiàn)占空比為50%的偶數(shù)N分頻,一般來說有兩種方案:,分頻器的基礎(chǔ)是計(jì)數(shù)器,設(shè)計(jì)分頻偶數(shù)分N/2-1時(shí),將輸出電平進(jìn)行一次翻轉(zhuǎn),同時(shí)給計(jì)數(shù)器一個(gè)復(fù)位信號,如此循環(huán)下去;二是當(dāng)計(jì)數(shù)器輸出為0到N/2-1時(shí),時(shí)鐘輸出為0或1,計(jì)數(shù)器輸出為N/2到N-1時(shí),時(shí)鐘輸出為0或1,計(jì)數(shù)器輸出為N/2到N-1時(shí),時(shí)鐘輸出為0或1,計(jì)數(shù)器輸出為N-1時(shí),復(fù)位計(jì)數(shù)器,如此循環(huán)下去。

                                                                                    圖4  偶數(shù)分頻仿真結(jié)果圖
                                                                                    圖 5 偶數(shù)分頻仿真結(jié)果圖
奇數(shù)分頻器

              實(shí)現(xiàn)非50%占空比的奇數(shù)分頻,如占空比為20%、40%、60%、80%的5分頻器,可以采用類似偶數(shù)分頻的第二種方案;但如果實(shí)現(xiàn)占空比為50%的奇數(shù)分頻,就不能使用偶數(shù)分頻中所采用的方案了。

下面就以實(shí)現(xiàn)占空比40%的5分頻分頻器為例,說明非50%占空比的奇數(shù)分頻器的實(shí)現(xiàn)。該分頻器的實(shí)現(xiàn)對于我們實(shí)現(xiàn)50%占空比的分頻器有一定的借鑒意義。一下是奇數(shù)分頻仿真結(jié)果圖。

                                                                      圖6  占空比為40%的5分頻仿真波形

半整數(shù)分頻器

僅僅采用數(shù)字分頻,不可能獲得占空比為50%的N+0.5分頻,我們只可以設(shè)計(jì)出占空比為(M+0.5)/(N+0.5)或者M(jìn)/(N+0.5)的分頻器,M小于N。這種半整數(shù)分頻方法是對輸入時(shí)鐘進(jìn)行操作,讓計(jì)數(shù)器計(jì)數(shù)到某一個(gè)數(shù)值時(shí),將輸入時(shí)鐘電平進(jìn)行一次反轉(zhuǎn),這樣,該計(jì)數(shù)值只保持了半個(gè)時(shí)鐘周期,因此實(shí)現(xiàn)半整數(shù)分頻。

              如上所述,占空比為50%的奇數(shù)分頻可以幫助我們實(shí)現(xiàn)半整數(shù)分頻,將占空比為50%的奇數(shù)分頻與待分頻時(shí)鐘異或得到計(jì)數(shù)脈沖,下面的代碼就是依靠占空比為50%的5分頻實(shí)現(xiàn)2.5分頻器的。仿真結(jié)果如圖所示。

                                                                                    圖7 2.5分頻仿真波形

小數(shù)分頻器

小數(shù)分頻是通過可變分頻和多次平均的方法實(shí)現(xiàn)的。例如要實(shí)現(xiàn)4.7分頻,只要在10次分頻中,做7次5分頻,3次4分頻就可以得到。再如要實(shí)現(xiàn)5.67分頻,只要在100次分頻中,做67 6分頻,33次5分頻即可?紤]到小數(shù)分頻器要進(jìn)行多次兩種頻率的分頻,必須設(shè)法將兩種分頻均勻。表1以2.7分頻為例,小數(shù)部分進(jìn)行累加,如果大于等于10,則進(jìn)行3分頻,如果小于10,進(jìn)行2分頻。

              仿真波形如圖 所示,我們可以清楚的看到2.7分頻的實(shí)現(xiàn)。按照占空比的定義,該分頻器的占空比應(yīng)為10/27。

圖8 2.7分頻仿真波形

分?jǐn)?shù)分頻器

將小數(shù)分頻的方法進(jìn)行擴(kuò)展,可以得到形如M*(L/N) 的分?jǐn)?shù)分頻的方法,例如,2*(7/13)等于分母的,進(jìn)行分頻,只要在13次分頻中,進(jìn)行7次3分頻,6次2分頻就可以得到。同樣,為了將兩種分頻均勻,將分子部分累加,小于分母的,進(jìn)行M分頻,大于(M+1)分頻。表2顯示了2*(7/13) 的分頻次序。

仿真波形如圖11所示。顯然,該分頻器的占空比為13/33。

圖9 33/13分頻器仿真波形
積分分頻器

積分分頻器用于實(shí)現(xiàn)形如的分頻,例如8/3分頻。我們當(dāng)然可以使用上面提到的分?jǐn)?shù)分頻的方法,但對于這種形式的分頻,使用積分分頻的方法綜合往往占用更少的FPGA資源。

積分分頻法基于下述原理:一個(gè)m位的二進(jìn)制數(shù)字每次累加N,假定累加x次累加值最低m位回到0,同時(shí)超過次,那么,當(dāng)前累加的數(shù)字應(yīng)該是;每越過一次,最高位變化 2 次,所以,累加 x 次,最高位變化 2y次,得到分頻的分頻器,例如,取m為4,N為3,當(dāng)累加16次時(shí),累加值為48,最低m位變回到0,同時(shí)越過16三次,最高位變化6次,由此得到16/6=8/3分頻的分頻器。

分頻仿真結(jié)果如圖所示。

圖10 積分分頻仿真波形
3、寫出異步串行通信的發(fā)送與接收程序,并分析。

異步串行數(shù)據(jù)傳輸具有設(shè)計(jì)簡單、傳輸穩(wěn)定等優(yōu)點(diǎn)。其兩個(gè)主要參數(shù)是波特率和數(shù)據(jù)位格式。數(shù)據(jù)位格式又稱幀格式,一般包含一個(gè)起始位(邏輯0),一個(gè)終止位(邏輯1)以及校驗(yàn)位。在發(fā)送空閑時(shí),總線一般處于邏輯1狀態(tài)。這樣當(dāng)接收端檢測到總線上由高到低的電平跳變,即認(rèn)為是數(shù)據(jù)開始傳輸。波特率是用來約定通信雙方的通信速率,一般通過對系統(tǒng)時(shí)鐘進(jìn)行分頻來實(shí)現(xiàn),RS-232協(xié)議中,常用的波特率有115200、9600等,RS-422與RS-232原理基本相同,只是在傳輸線路上,為了抗干擾,采用了差分方式。

在FPGA應(yīng)用領(lǐng)域 ,串行數(shù)據(jù)傳輸一般采用422總線。通過對系統(tǒng)晶振分頻,得到對應(yīng)的波特率,比如對40MHz經(jīng)行4分頻,得到10MBit的傳輸速率。解碼端會根據(jù)預(yù)先設(shè)定的波特率,對時(shí)鐘進(jìn)行分頻,每隔相等時(shí)間讀取總線上的一位數(shù)據(jù)。流程如下:在檢測到起始位低電平之后,接收端(即解碼端)每隔一位時(shí)間,采集總線上的電平,并寫入移位寄存器中,直到將一幀數(shù)據(jù)全部接收,然后判斷校驗(yàn)位,如果正確,則接收、編幀,否則,丟棄。

由于受溫度等因素的影響,晶振會產(chǎn)生誤差,串行數(shù)據(jù)在傳輸過程中,可能會受到干擾而產(chǎn)生毛刺。所以在一些對數(shù)據(jù)準(zhǔn)確度要求比較高的場合,就得考慮串行數(shù)據(jù)傳輸?shù)娜蒎e(cuò)能力。對于這種情況,第一種方法通常會采取對總線上的一位分別采集三次,比較得到的三個(gè)電平,進(jìn)而得到該位可信度更高的值,如圖2所示;第二種方法則會將電平的采集點(diǎn)放在每一位的靠近中間的位置,通過計(jì)算晶振的最大誤差,則可以計(jì)算出系統(tǒng)的最大容錯(cuò)能力。設(shè)晶振誤差5%,頻率為40MHz,1/40MHz=25ns,25*0.05=1.25ns,設(shè)波特率為4Mbit/s,所以對于40bit一幀的串行數(shù)據(jù),累積誤差最大會有1.25*40*4*50%=100ns,而比特位寬只有100ns,所以有可能會發(fā)生錯(cuò)位。

圖11 多次采樣減小誤差示意圖

部分代碼如下

(a)422串行發(fā)送



  1. process (pClock, pReset)                 --慣組信號源控制主進(jìn)程
  2.     begin
  3.         if pReset = '1' then
  4.             ch_ClearBusyFlag <= '1';
  5.             ch_tx <= '1';
  6.             ch_send_reg  <= "0000000000000000000000000000000000000000";
  7.             ch_st <= 0;
  8.             ch_clock_fp <= 0;
  9.         elsif (pClock='1') and (pClock'event) then
  10.             if    ch_st = 0 then    --監(jiān)測有無數(shù)據(jù)發(fā)送                                                                          
  11.                 if (ch_s_busy_flag = '1') then
  12.            ch_send_reg  <= ch_send_buf;   --讀取要發(fā)送的數(shù)到寄存器
  13.                     ch_ClearBusyFlag <= '0';  --置忙標(biāo)志清零                       
  14.                     ch_bit_counter <= 0;
  15.                     ch_clock_fp <= 0;
  16.                     ch_st <= 1;
  17.                 else
  18.                     ch_st <= 0;
  19.                 end if;   
  20.             elsif  ch_st = 1 then     --串行發(fā)送                                    
  21.                 ch_clock_fp <= ch_clock_fp + 1;      --0 - 57, 每位57個(gè)時(shí)鐘,共12位,1起始,1停止,2空閑
  22.                 if ch_clock_fp = 1 then
  23.                         ch_tx <= ch_send_reg(39 - ch_bit_counter);
  24.                 elsif ch_clock_fp = 2 then                  
  25.                     if ch_bit_counter = 39 then
  26.                         ch_tx <= '1';
  27.                         ch_st <= 0;                                        --跳轉(zhuǎn)到監(jiān)測busy標(biāo)志,等待發(fā)送下一個(gè)數(shù)
  28.                     else
  29.                         ch_bit_counter <= ch_bit_counter + 1;
  30.                     end if;
  31.                 elsif ch_clock_fp = 3 then
  32.                                                         if   ch_bit_counter = 5 then                           
  33.                                                ch_ClearBusyFlag <= '1';                          --忙標(biāo)志清零結(jié)束,4個(gè)clk,希望前一進(jìn)程不會監(jiān)測丟失
  34.                               end if;
  35.                                             end if;
  36.             end if;
  37.         end if;
  38.     end process;
復(fù)制代碼


(b) 422串行接收
******************************************************************
--命令接收主控制進(jìn)程**異步接收,40位

  1.     process (gClock_160, g_reset)      --flag=1 時(shí),串并轉(zhuǎn)換完成,
  2.     begin
  3.         if g_reset = '1' then
  4.             flag <= '1';
  5.         elsif (gClock_160='1') and (gClock_160'event) then
  6.             if cnt = 180 then  --161到180等待發(fā)送進(jìn)程取走send_buf中的數(shù)去發(fā)送
  7.                 flag <= '1';               
  8.             elsif rx = '0'  then
  9.                 flag <= '0';
  10.             end if;
  11.         end if;
  12.     end process;
  13.     process (gClock_160, g_reset)            --160MHz采樣40Mbps,每個(gè)位采樣4個(gè)點(diǎn),40個(gè)位cnt計(jì)數(shù)達(dá)到160
  14.     begin
  15.         if g_reset = '1' then
  16.             soft_reset <= '0';
  17.             cnt <= 0;
  18.            RcvBuf <= "0000000000000000000000000000000000000000";
  19.             tmp_data <= "0000000000000000000000000000000000000000";
  20.             REG_WR_PIPE_ADD <= "1111111111111111";
  21.             REG_ID <= "1111111100000001";
  22.                               led_show<='1';
  23.         elsif (gClock_160='1') and (gClock_160'event) then     
  24.                             -- led_show<= not led_show;
  25.             if flag = '1' then
  26.                 cnt <= 0;
  27.                 verify <= '0';
  28.             elsif flag = '0' then
  29.                 cnt <= cnt + 1;
  30.             end if;
  31.             if cnt =  1 then
  32.                 tmp_data(0)<=rx;
  33.             elsif cnt =  5 or cnt =  9 or cnt =  13 or cnt =  17 or
  34. cnt = 21 or cnt = 25 or cnt = 29 or cnt =  33 or cnt = 37 or  cnt = 41 or cnt = 45 or cnt = 49 or cnt = 53 or cnt =  57 or cnt = 61 or cnt = 65 or cnt = 69 or cnt = 73 or cnt = 77 or cnt = 81 or cnt = 85 or cnt = 89 or cnt = 93 or cnt = 97 or cnt = 101 or cnt =105 or cnt =109 or cnt =113 or cnt = 117 or cnt =121 or cnt =125 or cnt =129 or cnt =133 or cnt = 137 or cnt = 141 or cnt = 145 or cnt = 149 or cnt = 153 or cnt = 157 then               --先發(fā)高位
  35.                 verify <= verify xor rx;
  36.                 tmp_data(0)<=rx;
  37. for I in 1 to 39 loop
  38.                     tmp_data(I)<= tmp_data(I-1);
  39.                 end loop;
  40.             elsif (cnt = 160) and (tmp_data(39) = '0') and (tmp_data(1) = '1') and (tmp_data(0) = '1') then         --判斷起始停止位
  41.                 RcvBuf <= tmp_data;
  42.              wr_ch_add <= CONV_INTEGER(REG_WR_PIPE_ADD(2 downto 0));
  43.                 FCA <= CONV_INTEGER(tmp_data(36 downto 29));
  44.                 CA <= CONV_INTEGER(tmp_data(31 downto 29));
  45.                 RW <= tmp_data(28);
  46.                 RA <= CONV_INTEGER(tmp_data(27 downto 21));
  47.                 CMD <= tmp_data(20 downto 5);
  48.             elsif (cnt = 161) and (verify = '0') and (RcvBuf(38) = not RcvBuf(4)) and (RcvBuf(37) = not RcvBuf(3)) then
  49.                             ---------------------■■■■接收數(shù)據(jù)測試用后刪除-----------
  50.                                           RcvFlag_change  <= not RcvFlag_change;
  51.                                           RcvFlag              <=  RcvFlag_change;                                                        --接收數(shù)據(jù)翻轉(zhuǎn)
  52.                                           testch              <=              tmp_data(31 downto 29);              --接收數(shù)據(jù)通道顯示
  53.                             ---------------------■■■■------------------------------            
  54.                                           led_show<= not led_show;
  55.                                           if RcvBuf(38) = '0' then                                    --數(shù)據(jù)流,轉(zhuǎn)發(fā)對應(yīng)管道
  56.         if (CONV_INTEGER(REG_WR_PIPE_ADD) < 16) and (REG_WR_CH_BUSY(wr_ch_add) = '0') then
  57.                         send_buf(wr_ch_add) <= RcvBuf;   
  58.                         REG_WR_CH_BUSY(wr_ch_add) <= '1';                   --相應(yīng)通道置忙,不允許再寫入
  59.                     end if;
  60.                 elsif RcvBuf(38 downto 37) = "11" then                     
  61. --解析命令
  62.                     if FCA /= 255 then                                   --發(fā)送給16個(gè)通道的命令
  63.                 if (CA < 16) and (REG_WR_CH_BUSY(CA) = '0') then     --如果忙,將丟失此包,否則送給某個(gè)端口
  64.                             send_buf(CA) <= RcvBuf;        
  65.                             REG_WR_CH_BUSY(CA) <= '1';                      --置忙,不允許再寫入,
  66.                         end if;
  67.                     else                                                    --發(fā)送給背板本身的命令
  68.                         if RW = '1' then
  69.                             case RA is
  70.                             --when 0 =>
  71.                             when 1 =>                                       --立即執(zhí)行
  72.                    if CMD="0000000011000000" then    --reset
  73.                          soft_reset <= '1';      
  74.                                 end if;
  75. when 2 =>
  76.               REG_WR_PIPE_ADD <= CMD;
  77.   when 3 =>
  78.                 REG_RD_PIPE_ADD <= CMD;
  79. when others =>
  80.                  if (port_busy = '0') then
  81.             port_send_buf <= "010111111111" & RcvBuf(27 downto 21) & "111100000000111101011";    --失敗
  82.                       port_busy <= '1';
  83.                           end if;
  84.                         end case;
  85.              else
  86.                   case RA is
  87.                       when 0 =>         -- read id
  88.                            if (port_busy = '0') then
  89.           port_send_buf <= "0101111111100000000" & REG_ID & "01011";
  90.                            port_busy <= '1';
  91.                              end if;
  92.                             --when 1 =>
  93.                         when 2 =>
  94.                           if (port_busy = '0') then
  95.   port_send_buf <= "0101111111100000010" & REG_WR_PIPE_ADD & "01011";
  96.                            port_busy <= '1';
  97.                              end if;
  98.                           when 3 =>
  99.                          if (port_busy = '0') then
  100.   port_send_buf <= "0101111111100000011" & REG_RD_PIPE_ADD & "01011";
  101.                           port_busy <= '1';
  102.                             end if;
  103.                          when 4 =>
  104.                       if (port_busy = '0') then
  105.    port_send_buf <= "0101111111100000100" & REG_WR_CH_BUSY & "01011";
  106.                         port_busy <= '1';
  107.                            end if;
  108.                         when others =>
  109.                      if (port_busy = '0') then
  110.    port_send_buf <= "010111111110" & RcvBuf(27 downto 21) & "111101010000101001011";                       --失敗
  111.                          port_busy <= '1';
  112.                             end if;
  113.                             end case;
  114.                         end if;
  115.                        end if;
  116.                     --解析命令完成*****************************************************************
  117.                 end if;
  118.             elsif cnt < 160 then
  119.          REG_WR_CH_BUSY <= REG_WR_CH_BUSY and ("00000000" & ClearSndFlag_16ch);     --清除16個(gè)通道忙標(biāo)志
  120.         port_busy <= port_busy and port_ClearBusyFlag;               --清除主通道忙標(biāo)志
  121.             end if;
  122.         end if;
  123.     end process;
復(fù)制代碼

仿真結(jié)果:

圖12異步串行通信的發(fā)送與接收

4、寫出PCM通信的發(fā)送與接收程序,并分析。

PCM脈沖編碼調(diào)制是將模擬信號轉(zhuǎn)換成二進(jìn)制數(shù)字信號的編碼過程。在無線遙測系統(tǒng)中,遙測采編器對多路模擬信號通過特定的順序(幀結(jié)構(gòu))進(jìn)行模數(shù)轉(zhuǎn)換采樣,然后再將采得的PCM碼并串轉(zhuǎn)換,串行送至無線發(fā)射機(jī)發(fā)射。地面站通過無線接收機(jī)接收。解碼后的PCM碼是一個(gè)由二進(jìn)制數(shù)構(gòu)成的串行序列。地面接收設(shè)備的主要任務(wù)是將串行PCM碼中的數(shù)據(jù)解調(diào)出來,這就需要根據(jù)PCM碼流中特定的同步碼確定數(shù)據(jù)的起始位,在位信號變化時(shí)的上升沿(或下降沿)把PCM碼流的位同步信號分離出來,再通過串行數(shù)據(jù)到并行數(shù)據(jù)的轉(zhuǎn)換把數(shù)據(jù)并行輸出。

    PCM碼的串并轉(zhuǎn)換分為三步,第一步是提取同步信號,第二步是提取幀同步信號,第三步是根據(jù)已得到的位同步和幀同步完成字同步和串并轉(zhuǎn)換。

PCM碼在發(fā)送以及接收(解碼)過程中,都會用幀同步和碼同步對PCM碼進(jìn)行同步,有些還會用到路同步信號,如圖13所示。一般是PCM碼接收端發(fā)送同步信號(即幀同步、碼同步和路同步)。PCM碼發(fā)送端根據(jù)接收到的同步信號輸出PCM碼,比如在碼同步的上升沿或者下降沿給出數(shù)據(jù),接收端則根據(jù)自己發(fā)出的同步信號接收PCM碼。在實(shí)際數(shù)據(jù)傳輸過程中,考慮到信號的延時(shí),一般發(fā)送端在碼同步上升沿給出PCM數(shù)據(jù),接收端在碼同步下降沿讀取PCM數(shù)據(jù),而幀同步一般用作幀復(fù)位,路同步用作字節(jié)復(fù)位,如圖14所示。

接收端接收到PCM數(shù)據(jù)后,一般要經(jīng)過編幀,加上幀頭、幀尾以及幀計(jì)數(shù),然后上傳給計(jì)算機(jī)。計(jì)算機(jī)則將數(shù)據(jù)解包,提取出有用的信息。

圖13  PCM碼接收發(fā)送過程中的信號示意圖

圖14 同步信號示意圖

部分參考代碼:

(a)幀同步、路同步、碼同步信號的產(chǎn)生



  1.     process(gclk, rst)------ 分頻得到碼同步時(shí)鐘,3.05008us x 2=6.10016us ,要求是6.1035us
  2.               begin
  3.                  if rst = '1' then
  4.                             gclk_cnt<=0;
  5.                             gclk_3us<='0';
  6.               elsif gclk'event and gclk = '1'  then
  7.                             if gclk_cnt>=60 then
  8.                                           gclk_cnt<=0;
  9.                                           gclk_3us<= not gclk_3us;
  10.                             else
  11.                                           gclk_cnt<=gclk_cnt+1;
  12.                             end if;
  13.      end if;  
  14. end process;
  15. process(gclk_3us, rst)                ----幀同步、碼同步、路同步信號產(chǎn)生
  16.     begin
  17.               if rst='1' then
  18.                               f_ztb<='0';            
  19.                                   f_ltb<='1';
  20.                               f_mtb<='0';
  21.                               cnt2<=0;
  22.                               cnt1<=0;
  23.                               pcm_state<=pst0;                                                                                                               
  24.                 elsif  gclk_3us='1' and gclk_3us'event then   ----時(shí)鐘頻率為1/2碼同步
  25.                             case pcm_state is
  26.               when pst0=>                                     ----ztb上升沿與mtb下降沿對齊,路同步延遲一個(gè)周期后,開始發(fā)送碼同步
  27.                                               f_ztb<='1';
  28.                                             f_ltb<='0';
  29.                                             if cnt1=4 then
  30.                                                cnt1<=0;
  31.                              pcm_state<=pst1;            
  32.                                             else
  33.                                                         cnt1<=cnt1+1;
  34.                                                         pcm_state<=pst0;
  35.                                             end if;            
  36.                                           when pst1=>                           
  37.                                                    f_ztb<='0';
  38.                                              if cnt1=2 then
  39.                                       pcm_state<=pst2;
  40.                                                         cnt1<=0;
  41.                                              else
  42.                                                         cnt1<=cnt1+1;
  43.                                                         pcm_state<=pst1;
  44.                                              end if;
  45.                                           when pst2=>
  46.                                                    f_ltb<='1';
  47.                                              if cnt1=7 then
  48.                               pcm_state<=pst3;
  49.                                                 cnt1<=0;
  50.                                              else
  51.                                                 cnt1<=cnt1+1;
  52.                                                         pcm_state<=pst2;
  53.                                              end if;
  54.                                                                                       
  55.                                  when pst3=>
  56.                                                f_ltb<='0';
  57.                                                f_mtb<='1';                            -------1            
  58.                                                pcm_state<=pst4;
  59.                         when pst4=>
  60.                                                f_mtb<='0';
  61.                              pcm_state<=pst5;
  62.                                  when pst5=>            
  63.                                                f_mtb<='1';                            -------2
  64.                              pcm_state<=pst6;
  65.                                           when pst6=>
  66.                                                f_mtb<='0';
  67.                              pcm_state<=pst7;
  68.                                           when pst7=>                                         
  69.                                                f_mtb<='1';                            -------3
  70.                              pcm_state<=pst8;
  71.                                           when pst8=>            
  72.                                                f_mtb<='0';
  73.                              pcm_state<=pst9;
  74.                                           when pst9=>            
  75.                                                f_mtb<='1';                            ------4
  76.                              pcm_state<=pst10;
  77.                                           when pst10=>            
  78.                                                f_mtb<='0';
  79.                              pcm_state<=pst11;
  80.                                             when pst11=>            
  81.                                       f_ltb<='1';
  82.                                                f_mtb<='1';                    ------5
  83.                              pcm_state<=pst12;
  84.                                           when pst12=>
  85.                                                f_mtb<='0';
  86.                              pcm_state<=pst13;
  87.                                           when pst13=>
  88.                                                f_mtb<='1';                            ------6
  89.                              pcm_state<=pst14;
  90.                                           when pst14=>
  91.                                                f_mtb<='0';
  92.                              pcm_state<=pst15;
  93.                                           when pst15=>
  94.                                                f_mtb<='1';                            ------7
  95.                              pcm_state<=pst16;
  96.                                           when pst16=>
  97.                                                f_mtb<='0';
  98.                              pcm_state<=pst17;
  99.                                           when pst17=>
  100.                                                f_mtb<='1';                            ------8
  101.                              pcm_state<=pst18;
  102.                                           when pst18=>
  103.                                                f_mtb<='0';
  104.                              pcm_state<=pst19;
  105.                                           when pst19=>         --------f_mtb保持低,再產(chǎn)生3個(gè)周期的f_ltb
  106.                                       f_ltb<='0';                    ----------第2個(gè)f_ltb
  107.                                                         if cnt1=7 then
  108.                                                            cnt1<=0;
  109.                                                            pcm_state<=pst20;
  110.                                                         else
  111.                                                            cnt1<=cnt1+1;
  112.                                                            pcm_state<=pst19;
  113.                                                         end if;
  114.                                           when pst20=>                           
  115.                                       f_ltb<='1';
  116.                                                         if cnt1=7 then
  117.                                                            cnt1<=0;
  118.                                                            pcm_state<=pst21;
  119.                                                         else
  120.                                                            cnt1<=cnt1+1;
  121.                                                            pcm_state<=pst20;
  122.                                                         end if;
  123.                                           when pst21=>
  124.                                       f_ltb<='0';                                  -------第3個(gè)f_ltb
  125.                                                         if cnt1=7 then
  126.                                                            cnt1<=0;
  127.                                                            pcm_state<=pst22;
  128.                                                         else
  129.                                                           cnt1<=cnt1+1;
  130.                                                           pcm_state<=pst21;
  131.                                                         end if;
  132.                                           when pst22=>            
  133.                                       f_ltb<='1';
  134.                                                         if cnt1=7 then
  135.                                                            cnt1<=0;
  136.                                                            if cnt2=127 then                   ------循環(huán)128次,產(chǎn)生128路f_mtb
  137.                                                                          cnt2<=0;
  138.                                                                       pcm_state<=pst0;
  139.                                                            else
  140.                                                               cnt2<=cnt2+1;
  141.                                                                       pcm_state<=pst23;
  142.                                 end if;
  143.                                                         else
  144.                                                                       cnt1<=cnt1+1;
  145.                                                                       pcm_state<=pst22;
  146.                                                         end if;
  147.                                           when pst23=>            
  148.                                       f_ltb<='0';                                          --------第4個(gè)f_ltb
  149.                                                         if cnt1=7 then
  150.                                                            cnt1<=0;
  151.                                                            pcm_state<=pst24;
  152.                                                         else
  153.                                                            cnt1<=cnt1+1;
  154.                                                            pcm_state<=pst23;
  155.                                                         end if;
  156.                                           when pst24=>
  157.                                       f_ltb<='1';
  158.                                                         if cnt1=7 then
  159.                                                            cnt1<=0;     
  160.                                                      pcm_state<=pst3;
  161.                                                         else
  162.                                                            cnt1<=cnt1+1;
  163.                                                            pcm_state<=pst24;
  164.                                                         end if;
  165.                                when others =>
  166.                                      pcm_state<=pst0;
  167.                  end case;
  168.     end if;
  169.   end  process;
復(fù)制代碼


(b) PCM碼接收
  1.   process (f_mtb, rst, f_ztb)                                          
  2.     begin
  3.         if rst = '1' or f_ztb='1' then
  4.                               q_state<=q0;
  5.                               f_data<="00000000";
  6.                               f_flag<='0';                                                           
  7.          elsif f_mtb'event and f_mtb = '0' and f_ztb='0' then
  8.                                              case q_state  is
  9.                                               when q0 =>
  10.                                                 f_data(7)<=not qun_afxd;
  11.                                                         f_flag<='0';
  12.                                                         q_state<=q1;
  13.                             when q1 =>
  14.                                                 f_data(6)<=not qun_afxd;
  15.                                                         q_state<=q2;
  16.                                               when q2 =>
  17.                                                 f_data(5)<=not qun_afxd;
  18.                                                   q_state<=q3;
  19.                                               when q3 =>
  20.                                                 f_data(4)<=not qun_afxd;
  21.                                                         q_state<=q4;
  22.                                               when q4 =>
  23.                                                 f_data(3)<=not qun_afxd;
  24.                                                         q_state<=q5;
  25.                                               when q5 =>
  26.                                                 f_data(2)<=not qun_afxd;
  27.                                                         q_state<=q6;
  28.                                               when q6 =>
  29.                                                 f_data(1)<=not qun_afxd;
  30.                                                         q_state<=q7;
  31.                                               when q7 =>
  32.                                                 f_data(0)<=not qun_afxd;
  33.                                                         f_flag<='1';
  34.                                                         q_state<=q0;
  35.                                               when others =>
  36.                                                         q_state<=q0;
  37.                             end case;

  38.          end if;
  39.    end process ;
復(fù)制代碼



(c) PCM碼編幀
  1. process (gclk, rst)                            ---數(shù)據(jù)編幀,128 Byte群信號 + 2Byte轉(zhuǎn)發(fā)信號(前11位,后5位為0) + 2Byte幀計(jì)數(shù) + 2Byte幀標(biāo)志
  2.     begin
  3.         if rst = '1' then
  4.                     fifo_data <= "00000000";
  5.                             b_state<=b0;
  6.                             z_cnt<=X"0000";
  7.                             cnt3<=0;
  8.                             f_flag_tmp<='0';
  9.          elsif gclk'event and gclk = '1' then
  10.                       case b_state is
  11.                                 when b0=>
  12.                                              f_flag_tmp<=f_flag;
  13.                                     if  f_flag_tmp='0' and f_flag='1' then
  14.                                        b_state<=b1;
  15.                                              else
  16.                                                 b_state<=b0;
  17.                                     end if;
  18.                                 when b1=>                                            
  19.                                             fifo_data<=f_data;
  20.                                             fifo_wr<='0';
  21.                                             b_state<=b2;
  22.               when b2 =>
  23.                                    if cnt4=10 then
  24.                                                cnt4<=0;
  25.                                                b_state<=b3;
  26.                  else
  27.                                                cnt4<=cnt4+1;
  28.                                                b_state<=b2;
  29.                  end if;
  30.               when b3=>
  31.                                             fifo_wr<='1';
  32.                                             b_state<=b41;            
  33.                                 when b41=>
  34.                                             if cnt3=127 then                                                      
  35.                                                             cnt3<=0;                                         
  36.                                                         b_state<=b4;
  37.                                             else                                                      
  38.                                                         cnt3<=cnt3+1;
  39.                                       b_state<=b0;
  40.                                             end if;                                                                                                
  41.               when b4 =>
  42.                                    fifo_data<= not zf1out & not zf2out  & not zf3out  & zf4out  & zf5out  & zf6out  & zf7out & zf8out;          --前8路轉(zhuǎn)發(fā)信號
  43.                                             fifo_wr<='0';                   --前3路轉(zhuǎn)發(fā)信號正端輸入負(fù)端接地,由于通過管夠接收,所以要取反            
  44.                                    b_state<=b5;                            --后8路信號負(fù)端輸入正端接5V,所以不需要取反
  45.               when b5 =>
  46.                                    if cnt4=200 then
  47.                                                cnt4<=0;
  48.                                                b_state<=b6;
  49.                  else
  50.                                                cnt4<=cnt4+1;
  51.                                                b_state<=b5;
  52.                  end if;
  53.               when b6 =>
  54.                                    fifo_wr<='1';
  55.                              b_state<=b7;
  56.               when b7=>
  57.                                    b_state<=b8;
  58.               when b8=>
  59.                                    fifo_data<= zf9out & zf10out & zf11out  & "00000" ;                 --后3路轉(zhuǎn)發(fā)信號
  60.                                             fifo_wr<='0';                                                                                                   
  61.                                    b_state<=b9;
  62.               when b9 =>
  63.                                    if cnt4=200 then
  64.                                                cnt4<=0;
  65.                                                b_state<=b10;
  66.                  else
  67.                                                cnt4<=cnt4+1;
  68.                                                b_state<=b9;
  69.                  end if;
  70.               when b10 =>
  71.                                    fifo_wr<='1';
  72.                               b_state<=b11;
  73.               when b11=>
  74.                                    b_state<=b12;
  75.               when b12=>
  76.                                    fifo_data<= z_cnt(15 downto 8) ;                                          --幀計(jì)數(shù)高字節(jié)
  77.                                             fifo_wr<='0';
  78.                                    b_state<=b13;
  79.               when b13 =>
  80.                                    if cnt4=200 then
  81.                                                cnt4<=0;
  82.                                                b_state<=b14;
  83.                  else
  84.                                                cnt4<=cnt4+1;
  85.                                                b_state<=b13;
  86.                  end if;
  87.               when b14 =>
  88.                                    fifo_wr<='1';
  89.                               b_state<=b15;
  90.                                 when b15=>
  91.                                    b_state<=b16;
  92.                                 when b16=>
  93.                                    fifo_data<= z_cnt(7 downto 0) ;
  94.                                             fifo_wr<='0';                                                                           --幀計(jì)數(shù)低字節(jié)
  95.                                    b_state<=b17;
  96.               when b17 =>
  97.                                    if cnt4=200 then
  98.                                                cnt4<=0;
  99.                                                b_state<=b18;
  100.                  else
  101.                                                cnt4<=cnt4+1;
  102.                                                b_state<=b17;
  103.                  end if;
  104.               when b18 =>
  105.                                    fifo_wr<='1';
  106.                                             z_cnt<=z_cnt+1;
  107.                               b_state<=b19;  
  108.                                 when b19=>
  109.                                    b_state<=b20;
  110.                                 when b20=>
  111.                                    fifo_data<= X"EB" ;                                                            --幀結(jié)束標(biāo)志
  112.                                             fifo_wr<='0';
  113.                                    b_state<=b21;
  114.               when b21=>
  115.                                    if cnt4=200 then
  116.                                                cnt4<=0;
  117.                                                b_state<=b22;
  118.                  else
  119.                                                cnt4<=cnt4+1;
  120.                                                b_state<=b21;
  121.                  end if;
  122.               when b22=>
  123.                                    fifo_wr<='1';
  124.                               b_state<=b23;
  125.                                 when b23=>
  126.                                    b_state<=b24;
  127.                                 when b24=>                                                                                                      --幀結(jié)束標(biāo)志
  128.                                    fifo_data<= X"90" ;
  129.                                             fifo_wr<='0';
  130.                                             b_state<=b25;
  131.                                 when b25 =>
  132.                  if cnt4=200 then
  133.                                                cnt4<=0;
  134.                                                b_state<=b26;
  135.                  else
  136.                                                cnt4<=cnt4+1;
  137.                                                b_state<=b25;
  138.                  end if;
  139.               when b26 =>
  140.                                    fifo_wr<='1';
  141.                               b_state<=b27;
  142.                                 when b27=>
  143.                                    b_state<=b0;
  144.                                 when others =>
  145.                                             b_state<=b0;
  146.              end case;
  147.            end if;
  148.      end process;
復(fù)制代碼

仿真結(jié)果:

圖15PCM通信的發(fā)送與接收仿真圖


完整的Word格式文檔51黑下載地址:
VHDL信號消抖.doc (749.5 KB, 下載次數(shù): 10)


評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日本一区二区高清不卡 | 日韩1区 | 色婷婷综合久久久中字幕精品久久 | 国产一区91精品张津瑜 | 日韩精品免费播放 | 国产精品福利在线观看 | 91社区在线高清 | 久久精品亚洲精品国产欧美 | 九九精品在线 | 亚洲欧美在线视频 | 性一交一乱一透一a级 | 欧美午夜剧场 | 久久久久一区二区 | 亚洲网在线 | 一级毛片免费 | 在线一区 | 做a视频 | 麻豆av免费观看 | 亚洲国产中文在线 | 麻豆一区一区三区四区 | 国产一二三视频在线观看 | 国产免费视频 | 九九热这里只有精品在线观看 | www国产成人免费观看视频,深夜成人网 | 国产一区二区在线免费播放 | 日韩国产欧美在线观看 | 在线观看欧美日韩视频 | 日韩欧美国产精品 | 中文字幕色站 | 播放一级毛片 | 欧美日韩成人影院 | 国产高清视频在线观看播放 | 黄色网址免费看 | 国产黄色在线 | 97久久久久久久久 | 精品国产99 | 99视频在线免费观看 | 欧洲妇女成人淫片aaa视频 | 久久久久久中文字幕 | 日本精品视频 | 亚洲日本一区二区 |