中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
基于Verilog下的串口通信實驗

基于Verilog下的串口通信實驗

(2010-08-15 17:13:10)

   串口通信是目前比較重要的一種通信方式,主要是用于計算機和外部的通信。首先簡單的介紹一下串口通信的原理:

串口用于ASCII碼字符的傳輸。通信使用3根線完成:(1)地線,(2)發(fā)送,(3)接收。由于串口通信是異步的,端口能夠在一根線上發(fā)送數(shù)據(jù)同時在另一根線上接收數(shù)據(jù)。其他線用于握手,但是不是必須的。串口通信最重要的參數(shù)是波特率、數(shù)據(jù)位、停止位和奇偶校驗。對于兩個進行通行的端口,這些參數(shù)必須匹配: a,波特率:這是一個衡量通信速度的參數(shù)。它表示每秒鐘傳送的bit的個數(shù)。例如300波特表示每秒鐘發(fā)送300個bit。當我們提到時鐘周期時,我們就是指波特率例如如果協(xié)議需要4800波特率,那么時鐘是4800Hz。這意味著串口通信在數(shù)據(jù)線上的采樣率為4800Hz。通常電話線的波特率為14400,28800和36600。波特率可以遠遠大于這些值,但是波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信。 b,數(shù)據(jù)位:這是衡量通信中實際數(shù)據(jù)位的參數(shù)。當計算機發(fā)送一個信息包,實際的數(shù)據(jù)不會是8位的,標準的值是5、7和8位。如何設(shè)置取決于你想傳送的信息。比如,標準的ASCII碼是0~127(7位)。擴展的ASCII碼是0~255(8位)。如果數(shù)據(jù)使用簡單的文本(標準 ASCII碼),那么每個數(shù)據(jù)包使用7位數(shù)據(jù)。每個包是指一個字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗位。由于實際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語“包”指任何通信的情況。 c,停止位:用于表示單個包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時的,并且每一個設(shè)備有其自己的時鐘,很可能在通信中兩臺設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計算機校正時鐘同步的機會。適用于停止位的位數(shù)越多,不同時鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時也越慢。 d,奇偶校驗位:在串口通信中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。當然沒有校驗位也是可以的。對于偶和奇校驗的情況,串口會設(shè)置校驗位(數(shù)據(jù)位后面的一位),用一個值確保傳輸?shù)臄?shù)據(jù)有偶個或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對于偶校驗,校驗位為0,保證邏輯高的位數(shù)是偶數(shù)個。如果是奇校驗,校驗位位1,這樣就有3個邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡單置位邏輯高或者邏輯低校驗。這樣使得接收設(shè)備能夠知道一個位的狀態(tài),有機會判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步 

串口通信的數(shù)據(jù)傳輸時序如圖:



下面簡單的介紹一下本實驗所實現(xiàn)的功能以及相應(yīng)的程序思想:

     驗實現(xiàn)的功能有上位機向開發(fā)板發(fā)送數(shù)據(jù),開發(fā)板接收以后通過數(shù)碼管顯示,并且將接收到的數(shù)據(jù)傳回給上位機,通過串口調(diào)試助手將返回的數(shù)據(jù)顯示出來。

其模塊圖如下:

    程序思想:(本程序主要是采用特權(quán)同學(xué)視頻教程的程序,本人只是做一個簡單的思路總結(jié))

           1.通過ISE開發(fā)工具,新建4個模塊,分別為串口接收波特率產(chǎn)生模塊,串口接收模塊,串口發(fā)送波特率產(chǎn)生模塊,串口接收模塊,另外再加一個頂層模塊。

         2. 頂層模塊中只是做模塊的聲明和端口聲明,不做任何的邏輯處理。 

         3.波特率產(chǎn)生模塊(兩個模塊都一樣):主要是通過計數(shù)來實現(xiàn)波特率產(chǎn)生,并對數(shù)據(jù)進行采樣。此處采用9600bps,由于1s中有104166個us,系統(tǒng)時鐘為50M,即20us,即需要計數(shù)為104166/20=5208,因此循環(huán)計數(shù)0~5207,并且在計數(shù)到2603時對數(shù)據(jù)進行采樣。

         4.串口接收模塊:當接收到接收信號置位時,對數(shù)據(jù)進行采集。

         5.串口發(fā)送模塊:當接收到發(fā)送信號置位時,對數(shù)據(jù)進行發(fā)送。

   具體程序如下:

/=============================頂層模塊=====================================

module uart_top(clk,,rst_n,rs232_rx,rs232_tx,led);

 inputclk;    //時鐘信號50M
 inputrst_n;   //復(fù)位信號,低有效
 inputrs232_rx;  //數(shù)據(jù)輸入信號
 outputrs232_tx;  //數(shù)據(jù)輸出信號
 output [7:0] led;
 
 wire bps_start1,bps_start2;//
 wire clk_bps1,clk_bps2;
 wire [7:0]rx_data;   //接收數(shù)據(jù)存儲器,用來存儲接收到的數(shù)據(jù),直到下一個數(shù)據(jù)接收
 wirerx_int;     //接收數(shù)據(jù)中斷信號,接收過程中一直為高,
 
///////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////子模塊端口申明///////////////////////////////////
speed_select_rx    speed_rx(   //數(shù)據(jù)接收波特率選擇模塊
         .clk(clk),
         .rst_n(rst_n),
         .bps_start(bps_start1),
         .clk_bps(clk_bps1)
         );
        
uart_rx    uart_rx(    //數(shù)據(jù)接收模塊
         .clk(clk),
         .rst_n(rst_n),
         .bps_start(bps_start1),
         .clk_bps(clk_bps1),
         .rs232_rx(rs232_rx),
         .rx_data(rx_data),
         .rx_int(rx_int),
         .led(led)
        );

speed_select_tx  speed_tx(   //數(shù)據(jù)發(fā)送波特率控制模塊
         .clk(clk),
         .rst_n(rst_n),
         .bps_start(bps_start2),
         .clk_bps(clk_bps2)         
         );
         
uart_tx    uart_tx(
         .clk(clk),
         .rst_n(rst_n),
         .bps_start(bps_start2),
         .clk_bps(clk_bps2),
         .rs232_tx(rs232_tx),
         .rx_data(rx_data),
         .rx_int(rx_int)        
        );

endmodule
/=================================波特率產(chǎn)生模塊=====================================

module speed_select_rx(clk,rst_n,bps_start,clk_bps);//波特率設(shè)定

 inputclk;   //50M時鐘
 inputrst_n;  //復(fù)位信號
 inputbps_start; //接收到信號以后,波特率時鐘信號置位,當接收到uart_rx傳來的信號以后,模塊開始運行
 outputclk_bps; //接收數(shù)據(jù)中間采樣點,
 
// `defineBPS_PARA 5207;//9600波特率分頻計數(shù)值
// `define BPS_PARA_2 2603;//計數(shù)一半時采樣
 
 reg[12:0] cnt;//分頻計數(shù)器
 reg clk_bps_r;//波特率時鐘寄存器
 
 reg[2:0] uart_ctrl;//波特率選擇寄存器
 
 always @(posedge clk or negedge rst_n)
  if(!rst_n)
   cnt<=13'd0;
  else if((cnt==5207)||!bps_start)//判斷計數(shù)是否達到1個脈寬
   cnt<=13'd0;
  else
   cnt<=cnt+1'b1;//波特率時鐘啟動
   
 always @(posedge clk or negedge rst_n)begin
  if(!rst_n)
   clk_bps_r<=1'b0;
  else if(cnt==2603)//當波特率計數(shù)到一半時,進行采樣存儲
   clk_bps_r<=1'b1;
  else
   clk_bps_r<=1'b0;
 end
 assign clk_bps =clk_bps_r;//將采樣數(shù)據(jù)輸出給uart_rx模塊
endmodule
//================================數(shù)據(jù)接收模塊==========================================

module uart_rx(
     clk,
     rst_n,
     bps_start,
     clk_bps,
     rs232_rx,
     rx_data,
     rx_int,
     led
     );
 inputclk;   //時鐘
 inputrst_n;  //復(fù)位
 input rs232_rx; //接收數(shù)據(jù)信號
 inputclk_bps;  //高電平時為接收信號中間采樣點
 outputbps_start; //接收信號時,波特率時鐘信號置位
 output [7:0] rx_data;//接收數(shù)據(jù)寄存器
 outputrx_int;  //接收數(shù)據(jù)中斷信號,接收過程中為高
 output [7:0] led;
 reg [7:0] led;
 regrs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;//接收數(shù)據(jù)寄存器
 wire neg_rs232_rx;//表示數(shù)據(jù)線接收到下沿
 
 always @(posedge clk or negedge rst_n)begin
  if(!rst_n) begin
   rs232_rx0<= 1'b0;
   rs232_rx1<= 1'b0;
   rs232_rx2<= 1'b0;
   rs232_rx3<= 1'b0;
  end
  
  else begin
   rs232_rx0<= rs232_rx;
   rs232_rx1<= rs232_rx0;
   rs232_rx2<= rs232_rx1;
   rs232_rx3<= rs232_rx2;
  end
 end

 assign neg_rs232_rx = rs232_rx3& rs232_rx2 & ~rs232_rx1& ~rs232_rx0;//串口傳輸線的下沿標志

 reg bps_start_r;
 reg [3:0] num;//移位次數(shù)
 regrx_int;  //接收中斷信號
 
 always @(posedge clk or negedge rst_n)
  if(!rst_n) begin
   bps_start_r<=1'bz;
   rx_int<= 1'b0;
  end
  else if(neg_rs232_rx)begin//
  bps_start_r <=1'b1;  //啟動串口,準備接收數(shù)據(jù)
   rx_int<=1'b1;   //接收數(shù)據(jù)中斷使能
  end
  else if(num==4'd12)begin //接收完有用的信號,
   bps_start_r<=1'b0;  //接收完畢,改變波特率置位,方便下次接收
   rx_int<=1'b0;   //接收信號關(guān)閉
  end
  
  assign bps_start =bps_start_r;
  
  reg [7:0]rx_data_r;//串口數(shù)據(jù)寄存器
  reg [7:0]rx_temp_data;//當前數(shù)據(jù)寄存器
  
  always @(posedge clk or negedgerst_n)
   if(!rst_n)begin
     rx_temp_data<= 8'd0;
     num<= 4'd0;
     rx_data_r<= 8'd0;
   end
   elseif(rx_int) begin //接收數(shù)據(jù)處理
    if(clk_bps)begin
     num<= num+1'b1;
     case(num)
       4'd1:rx_temp_data[0] <= rs232_rx;
       4'd2:rx_temp_data[1] <= rs232_rx;
       4'd3:rx_temp_data[2] <= rs232_rx;
       4'd4:rx_temp_data[3] <= rs232_rx;
       4'd5:rx_temp_data[4] <= rs232_rx;
       4'd6:rx_temp_data[5] <= rs232_rx;
       4'd7:rx_temp_data[6] <= rs232_rx;
       4'd8: rx_temp_data[7]<= rs232_rx;
       default:;
     endcase
     led<= rx_temp_data;
    end
    elseif(num==4'd12) begin
     num<=4'd0;   //數(shù)據(jù)接收完畢
     rx_data_r<= rx_temp_data;
    end          
   end
  assign rx_data =rx_data_r;
endmodule
//=================================數(shù)據(jù)發(fā)送模塊=========================================

module uart_tx(
     clk,
     rst_n,
     bps_start,
     clk_bps,
     rs232_tx,
     rx_data,
     rx_int 
    );


 input clk;
 input rst_n;
 input clk_bps;//中間采樣點
 input [7:0] rx_data;//接收數(shù)據(jù)寄存器
 input rx_int;//數(shù)據(jù)接收中斷信號
 output rs232_tx;//發(fā)送數(shù)據(jù)信號
 output bps_start;//發(fā)送信號置位
 
 reg rx_int0,rx_int1,rx_int2;//信號寄存器,捕捉下降沿
 wireneg_rx_int;    //下降沿標志
 
 always @(posedge clk or negedge rst_n)begin
  if(!rst_n) begin
   rx_int0<= 1'b0;
   rx_int1<= 1'b0;
   rx_int2<= 1'b0;
  end
  else begin
    rx_int0<= rx_int;
    rx_int1<= rx_int0;
    rx_int2<= rx_int1;
  end
 end
 
  assign neg_rx_int = ~rx_int1& rx_int2;//捕捉下沿
  
  reg [7:0] tx_data;//待發(fā)送數(shù)據(jù)
  reg bps_start_r;
  reg tx_en;//發(fā)送信號使能,高有效
  reg [3:0] num;
 
 always @(posedge clk or negedge rst_n)begin
  if(!rst_n) begin
   bps_start_r<= 1'bz;
   tx_en<= 1'b0;
   tx_data<= 8'd0;
  end
  else if(neg_rx_int)begin//當檢測到下沿的時候,數(shù)據(jù)開始傳送
   bps_start_r<= 1'b1;
   tx_data<= rx_data;
   tx_en<= 1'b1;
  end
  else if(num==4'd11) begin
   bps_start_r<= 1'b0;
   tx_en<= 1'b0;
  end 
 end
 
 assign bps_start = bps_start_r;
 
 reg rs232_tx_r;
 always @(posedge clk or negedge rst_n)begin
  if(!rst_n) begin
   num<=4'd0;
   rs232_tx_r<= 1'b1;
  end
  else if(tx_en) begin
   if(clk_bps)begin
    num<=num+1'b1;
    case(num)
      4'd0:rs232_tx_r <= 1'b0;//起始位
      4'd1:rs232_tx_r <= tx_data[0];//數(shù)據(jù)位 開始
      4'd2:rs232_tx_r <= tx_data[1];
      4'd3:rs232_tx_r <= tx_data[2];
      4'd4:rs232_tx_r <= tx_data[3];
      4'd5:rs232_tx_r <= tx_data[4];
      4'd6:rs232_tx_r <= tx_data[5];
      4'd7:rs232_tx_r <= tx_data[6];
      4'd8:rs232_tx_r <= tx_data[7];
      4'd9:rs232_tx_r <= 1'b1;//數(shù)據(jù)結(jié)束位,1位
      default:rs232_tx_r <= 1'b1;
    endcase
   end
   elseif(num==4'd11)
    num<=4'd0;//發(fā)送完成,復(fù)位
  end
 end
 assign rs232_tx =rs232_tx_r;
endmodule

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
小課堂10——基于FPGA 的串口監(jiān)視系統(tǒng)設(shè)計
【接口時序】3、UART串口收發(fā)的原理與Verilog實現(xiàn)
FPGA實現(xiàn)串口UART自收發(fā)
VHDL實驗三:設(shè)計UART串行傳輸模塊 [CPLD/FPGA]
一天一個設(shè)計實例-3萬字講解UART和實例
UART串口收發(fā)控制器設(shè)計詳解
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服