【黑金原創教程】【FPGA那些事兒-驅動篇I 】實驗十二:串口模塊① — 發送


實驗十二:串口模塊① — 發送

串口固然是典型的實驗,想必許多同學已經作爛,不過筆者還要循例介紹一下。我們知道串口有發送與接收之分,實驗十二的實驗目的就是實現串口發送,然而不同的是 ... 筆者會用另一種思路去實現串口發送。

clip_image002

圖12.1 PS/2發送時序與串口發送時序。

如圖12.1所示,串口發送時序相較PS/2發送時序,串口發送時序就像斷了翅膀的小鳥般,沒有時鍾信號控制整個傳輸協議。除此之外,串口發送時序與PS/2發送時序近似的地方也非常驚人 ... 默認下,一幀PS/2數據有11位,對此一幀串口數據也有11位,其中位分配如表12.1所示:

表12.1 一幀串口數據的位分配。

位分配

位定義

[0]

起始位

[8:1]

數據位

[9]

校驗位

[10]

停止位

如表12.1所示,[0]為拉低的起始位,[8:1]為任意填充的數據位,[9]為任意填充的校驗位,[10]為拉高的停止位。

clip_image004

圖12.2 FPGA發送一幀串口數據(無視波特率)。

假設我們無視波特率,並且利用FPGA發送一幀串口數據的話 ... 如圖12.2所示,一幀有11位的串口數據,一共使用了11個上升沿發送出去,為此Verilog則可以這樣表示,結果如代碼12.1所示:

      reg [10:0]D1;
     always @(posedge CLOCK)
         case(i)
            0,1,2,3,4,5,6,7,8,9,10:      
            begin TXD <= D1[i]; i <= i + 1'b1; end
            ......
         endcase

代碼12.1

如代碼12.1所示,寄存器D為11位寬的寄存器,並且驅動TXD輸出口,期間步驟0~11公按照i的位尋址,將D1的內容逐個發送出去。

雖然串口傳輸協議極為類似PS/2傳輸協議,但是串口傳輸協議也有區別的地方。其一串口傳輸協議有波特率的概念,而且串口協議有各種各樣的波特率,常用的波特率有9600 bps或者115200 bps,波特率最低為 110 bps,最高為 256000 bps(目前暫定)。所謂波特率就是一秒內,串口可以發送多少位數據,此外波特率也是一位數據的周期,或者說是一位數據的保持時間,就拿115200 bps為例:

1/115200 = 8.68E-6

115200波特率的一位數據周期為 8.68us,如果用50Mhz 的時鍾頻率去量化的話:

( 1/115200 ) / (1/50E+6) = 8.68E-6 / 20E-9

= 434

clip_image006

圖12.3 FPGA發送一幀串口數據(考慮波特率)。

如果圖12.3考慮115200的波特率,結果如圖12.3所示,每一位數據都保持434個時鍾

,為此Verilog可以這樣表示,如代碼12.2所示:

      reg [10:0]D1;
      reg [8:0]C1;
     always @(posedge CLOCK)
         case(i)
            0,1,2,3,4,5,6,7,8,9,10:    
             if( C1 == 9’d434 -1 ) begin C1 <= 9’d0; i <= i + 1’b1; end  
            else begin TXD <= D1[i]; C1 <= C1 + 1'b1; end
            ......
         endcase

代碼12.1

如代碼12.1所示,步驟0~10不再保持一個時鍾,換之每個步驟都保持434個時鍾,因此每位TXD的發送數據也保持 8.68us。

除此此外,串口傳輸協議不僅可以自定義波特率,串口傳輸協議也可以自定義一幀數據的位寬,自定義內容如表12.2所示:

表12.2 自定義一幀數據。

自定義數據位

自定義內容

數據位

5~9

校驗位

有/無

停止位

1~2

如表12.2所示,可以自定義的數據其中便包含數據位,默認下為1字節,自定義內容則是5~9位,校驗位也可以設置為有或者無(默認下是有),停止位也可以增至2位(默認下是1位)。不管怎么樣,表12.2是比較官方的自定義內容 ... 只要讀者歡喜,任何畸形的自定義內容也有可能實現。

理解完畢以后,我們便可以開始建模了。

clip_image008

圖12.4 實驗十二的建模圖。

圖12.4是實驗十二的建模圖,不過內容較為寒酸 ... 組合模塊 tx_demo 內容包括一段核心操作,還有一只TX功能模塊。核心操作負責TX功能模塊的調用,亦即控制溝通信號還有Data的輸入。TX功能模塊被使能以后,便將iData經由TXD輸出端發送出去

,完后便反饋完成信號以示一次性的操作已經完畢。

tx_funcmod.v

clip_image010

圖12.5 TX功能模塊的建模圖。

如圖12.5所示,該模塊的左方有問答信號,還有8位的iData,至於右方則是 TXD 頂層信號。此外,一幀數據的波特率為 115200 bps。

1.    module tx_funcmod
2.    (
3.         input CLOCK, RESET,
4.         output TXD,
5.         input iCall,
6.         output oDone,
7.         input [7:0]iData
8.    );
9.         parameter B115K2 = 9'd434; // formula : ( 1/115200 )/( 1/50E+6 )     

以上內容為相關的出入端聲明,第9行則是波特率為115200的常量聲明。

11.         reg [3:0]i;
12.         reg [8:0]C1;
13.         reg [10:0]D1;
14.         reg rTXD;
15.         reg isDone;
16.         
17.         always @( posedge CLOCK or negedge RESET )
18.             if( !RESET )
19.                  begin
20.                         i <= 4'd0;
21.                         C1 <= 9'd0;
22.                         D1 <= 11'd0;
23.                         rTXD <= 1'b1; 
24.                         isDone <= 1'b0;
25.                  end

以上內容為相關的寄存器聲明以及復位操作。

26.              else if( iCall )
27.                  case( i )
28.                    
29.                         0:
30.                         begin D1 <= { 2'b11 , iData , 1'b0 }; i <= i + 1'b1; end
31.                         
32.                         1,2,3,4,5,6,7,8,9,10,11:      
33.                         if( C1 == B115K2 -1 ) begin C1 <= 8'd0; i <= i + 1'b1; end
34.                         else begin rTXD <= D1[i - 1]; C1 <= C1 + 1'b1; end
35.    
36.                         12:
37.                         begin isDone <= 1'b1; i <= i + 1'b1; end
38.                         
39.                         13:
40.                         begin isDone <= 1'b0; i <= 4'd0; end
41.                    
42.                    endcase
43.                        

以上內容為部分核心操作。第26行的if( iCall ) 表示該模塊不使能就不工作。步驟0用來准備發送數據,其中 2’b11 是停止位與校驗位(隨便填),1’b0則是起始位。步驟1~11用來發送一幀數據。步驟12~13用來反饋完成信號並返回步驟。

44.        assign TXD = rTXD;
45.        assign oDone = isDone;           
46.    
47.    endmodule

以上內容為驅動輸出的聲明。

tx_demo.v

連線部署直接看代碼比較具體一點。

1.    module tx_demo
2.    (
3.         input CLOCK, RESET,
4.         output TXD
5.    );
6.        wire DoneU1;

以上內容是相關的出入端聲明。

8.        tx_funcmod U1
9.         (
10.              .CLOCK( CLOCK ),
11.              .RESET( RESET ),
12.              .TXD( TXD ),
13.              .iCall( isTX ),
14.              .oDone( DoneU1 ),
15.             .iData( D1 )
16.         );

以上內容是TX功能模塊的實例化,其中isCall由isTX驅動,iData由D驅動。

18.         reg [3:0]i;
19.         reg [7:0]D1;
20.         reg isTX;
21.         
22.         always @ ( posedge CLOCK or negedge RESET )
23.             if( !RESET )
24.                  begin
25.                         i <= 4'd0;
26.                         D1 <= 8'd0;
27.                         isTX <= 1'b0;
28.                    end

以上內容是相關的寄存器聲明,第23~28行則是這些寄存器的復位操作。

29.              else
30.                  case( i )
31.                    
32.                        0:
33.                         if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
34.                         else begin isTX <= 1'b1; D1 <= 8'hA1; end
35.                         
36.                         1:
37.                         if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
38.                         else begin isTX <= 1'b1; D1 <= 8'hA2; end
39.                         
40.                         2:
41.                         if( DoneU1 ) begin isTX <= 1'b0; i <= i + 1'b1; end
42.                         else begin isTX <= 1'b1; D1 <= 8'hA3; end
43.                         
44.                         3: // Stop
45.                         i <= i;
46.                    
47.                    endcase
48.    
49.    endmodule

以上內容是核心操作的內容,步驟0發送數據 8’hA1,步驟1發送數據8’hA2,步驟2發送數據 8’hA3。

編譯完畢便下載程序,並且將串口線連接至電腦與開發板。打開串口調試助手,波特率設為115200,數據位為8,校驗位隨便,停止位為1位 ... 事后,顯示方式設置為HEX(十六進制)。當程序下載完畢以后,串口調試助手便會出現 A1,A2與A3。

細節一: 完整的個體模塊

實驗十二的TX功能模塊已經是完整的個體,可以直接拿來調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM