生活随笔
收集整理的這篇文章主要介紹了
串行通信原理及实验仿真
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1. 處理器與外部設備通信的兩種方式:
并行通信和串行通信
并行通信是指數據的各個位用多條數據線同時進行傳輸
優點:傳輸速度快
缺點:占用引腳資源多
串行通信是將數據分成一位一位的形式在一條傳輸線上逐個傳輸
優點:通信線路簡單,占用引腳資源少
缺點:傳輸速度慢
2. 串行通信的通信方式:
同步通信和異步通信
同步通信:帶有時鐘同步信號的數據傳輸;發送方和接收方在同一時鐘的控制下,同步傳輸數據。
異步通信:不同時鐘同步信號的數據傳輸。發送方和接收方使用各自的時鐘控制數據的發送和接收過程。
3. 串行通信的傳輸方向
單工:數據只能沿一個方向傳輸
半雙工:數據傳輸可以沿兩個方向,但需要分時進行
全雙工:數據可以同時進行雙向傳輸
4. 常見的串行通信接口
5. UART
是一種采用異步串行通信方式的通用異步收發傳輸器
功能:
它在發送數據時將并行數據轉換成串行數據來輸出,在接收數據時將接收到的串行數據轉換成并行數據
a. 協議層:通信協議(包括數據格式、數據速率等)
UART串口通信需要兩根信號線來實現,一根用于串口發送,另外一根負責串口接收
串口通信常用的波特率有9600/19200/38400/115200等
b. 物理層:接口類型,電平標準等
針對異步串行通信的接口標準有RS232、RS422、RS485
接口定義:
6. 串口通信實驗
module
uart_top(input sys_clk
,input sys_rst_n
,input uart_rxd
,output uart_txd
);parameter CLK_FREQ
= 50000000;parameter UART_BPS
= 115200;wire uart_en_w
;wire
[7:0] uart_data_w
;uart_recv #
(.CLK_FREQ
(CLK_FREQ
),.UART_BPS
(UART_BPS
))u_uart_recv(.sys_clk
(sys_clk
),.sys_rst_n
(sys_rst_n
),.uart_rxd
(uart_rxd
),.uart_done
(uart_en_w
),.uart_data
(uart_data_w
));uart_send #
(.CLK_FREQ
(CLK_FREQ
),.UART_BPS
(UART_BPS
))u_uart_send(.sys_clk
(sys_clk
),.sys_rst_n
(sys_rst_n
),.uart_en
(uart_en_w
),.uart_din
(uart_data_w
),.uart_data
(uart_txd
));
endmodulemodule
uart_recv(input sys_clk
,input sys_rst_n
,input uart_rxd
,output reg uart_done
,output reg
[7:0] uart_data
);parameter CLK_FREQ
= 50000000;parameter UART_BPS
= 9600;localparam BPS_CNT
= CLK_FREQ
/UART_BPS
;reg uart_rxd_d0
;reg uart_rxd_d1
;reg
[15:0] clk_cnt
;reg
[3:0] rx_cnt
;reg
[7:0] rxdata
;reg rx_flag
;wire start_flag
;assign start_flag
= uart_rxd_d1
& (~uart_rxd_d0
);always @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) beginuart_rxd_d0
<= 1'b0
;uart_rxd_d1
<= 1'b0
;end
else beginuart_rxd_d0
<= uart_rxd
;uart_rxd_d1
<= uart_rxd_d0
; endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
)rx_flag
<= 1'b0
;else begin
if(start_flag
)rx_flag
<= 1'b1
;else if((rx_cnt
== 4'd9
) && (clk_cnt
== BPS_CNT
/2))rx_flag
<= 1'b0
;elserx_flag
<= rx_flag
;endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) beginclk_cnt
<= 16'd0
;rx_cnt
<= 4'd0
;end
else if(rx_flag
) begin
if(clk_cnt
< BPS_CNT
-1) beginclk_cnt
<= clk_cnt
+ 1'b1
;rx_cnt
<= rx_cnt
;end
else beginclk_cnt
<= 16'd0
;rx_cnt
<= rx_cnt
+ 1'b1
; endend
else beginclk_cnt
<= 16'd0
;rx_cnt
<= 4'd0
; endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
)rxdata
<= 8'd0
;else if(rx_flag
) begin
if(clk_cnt
== BPS_CNT
/2) begin
case(rx_cnt
)4'd1
:rxdata
[0] <= uart_rxd_d1
;4'd2
:rxdata
[1] <= uart_rxd_d1
;4'd3
:rxdata
[2] <= uart_rxd_d1
;4'd4
:rxdata
[3] <= uart_rxd_d1
;4'd5
:rxdata
[4] <= uart_rxd_d1
;4'd6
:rxdata
[5] <= uart_rxd_d1
;4'd7
:rxdata
[6] <= uart_rxd_d1
;4'd8
:rxdata
[7] <= uart_rxd_d1
;default:;endcaseend
else rxdata
<= rxdata
;end
elserxdata
<= 8'd0
;always @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) beginuart_data
<= 8'd0
;uart_done
<= 1'b0
;end
else if(rx_cnt
== 4'd9
) beginuart_data
<= rxdata
;uart_done
<= 1'b1
; end
else beginuart_data
<= 8'd0
;uart_done
<= 1'b0
;endend
endmodulemodule
uart_send(input sys_clk
,input sys_rst_n
,input uart_en
,output reg uart_txd
,output reg
[7:0] uart_din
);parameter CLK_FREQ
= 50000000;parameter UART_BPS
= 9600;localparam BPS_CNT
= CLK_FREQ
/UART_BPS
;reg uart_en_d0
;reg uart_en_d1
;reg
[15:0] clk_cnt
;reg
[3:0] tx_cnt
;reg
[7:0] tx_data
;reg tx_flag
;wire en_flag
;assign en_flag
= ~uart_en_d1
& uart_en_d0
;always @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) beginuart_en_d0
<= 1'b0
;uart_en_d1
<= 1'b0
;end
else beginuart_en_d0
<= uart_en
;uart_en_d1
<= uart_en_d0
; endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) begintx_flag
<= 1'b0
;tx_data
<= 8'd0
;end
else if(en_flag
) begintx_flag
<= 1'b1
;tx_data
<= uart_din
;end
else if((tx_cnt
== 4'd9
) && (clk_cnt
== BPS_CNT
/2)) begintx_flag
<= 1'b0
;tx_data
<= 8'd0
;end
else begintx_flag
<= tx_flag
;tx_data
<= tx_data
;endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
) beginclk_cnt
<= 16'd0
;tx_cnt
<= 4'd0
;end
else if(tx_flag
) begin
if(clk_cnt
< BPS_CNT
-1) beginclk_cnt
<= clk_cnt
+ 1'b1
;tx_cnt
<= tx_cnt
;end
else beginclk_cnt
<= 16'd0
;tx_cnt
<= tx_cnt
+ 1'b1
; endend
else beginclk_cnt
<= 16'd0
;tx_cnt
<= 4'd0
; endendalways @
(posedge sys_clk or negedge sys_rst_n
) begin
if(!sys_rst_n
)uart_txd
<= 1'b1
;else if(tx_flag
) begin
case(tx_cnt
)4'd0:uart_txd <= 1'b0
;4'd1
:uart_txd
<= tx_data
[0];4'd2
:uart_txd
<= tx_data
[1];4'd3
:uart_txd
<= tx_data
[2];4'd4
:uart_txd
<= tx_data
[3];4'd5
:uart_txd
<= tx_data
[4];4'd6
:uart_txd
<= tx_data
[5];4'd7
:uart_txd
<= tx_data
[6];4'd8
:uart_txd
<= tx_data
[7];4'd9:uart_txd <= 1'b1
;default:;endcaseend
elserxdata
<= 8'd0
;endendmoduleendmodule
總結
以上是生活随笔為你收集整理的串行通信原理及实验仿真的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。