生活随笔
收集整理的這篇文章主要介紹了
串行通信原理及实验仿真
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1. 處理器與外部設(shè)備通信的兩種方式:
并行通信和串行通信
并行通信是指數(shù)據(jù)的各個(gè)位用多條數(shù)據(jù)線同時(shí)進(jìn)行傳輸
優(yōu)點(diǎn):傳輸速度快
缺點(diǎn):占用引腳資源多
串行通信是將數(shù)據(jù)分成一位一位的形式在一條傳輸線上逐個(gè)傳輸
優(yōu)點(diǎn):通信線路簡(jiǎn)單,占用引腳資源少
缺點(diǎn):傳輸速度慢
2. 串行通信的通信方式:
同步通信和異步通信
同步通信:帶有時(shí)鐘同步信號(hào)的數(shù)據(jù)傳輸;發(fā)送方和接收方在同一時(shí)鐘的控制下,同步傳輸數(shù)據(jù)。
異步通信:不同時(shí)鐘同步信號(hào)的數(shù)據(jù)傳輸。發(fā)送方和接收方使用各自的時(shí)鐘控制數(shù)據(jù)的發(fā)送和接收過(guò)程。
3. 串行通信的傳輸方向
單工:數(shù)據(jù)只能沿一個(gè)方向傳輸
半雙工:數(shù)據(jù)傳輸可以沿兩個(gè)方向,但需要分時(shí)進(jìn)行
全雙工:數(shù)據(jù)可以同時(shí)進(jìn)行雙向傳輸
4. 常見的串行通信接口
5. UART
是一種采用異步串行通信方式的通用異步收發(fā)傳輸器
功能:
它在發(fā)送數(shù)據(jù)時(shí)將并行數(shù)據(jù)轉(zhuǎn)換成串行數(shù)據(jù)來(lái)輸出,在接收數(shù)據(jù)時(shí)將接收到的串行數(shù)據(jù)轉(zhuǎn)換成并行數(shù)據(jù)
a. 協(xié)議層:通信協(xié)議(包括數(shù)據(jù)格式、數(shù)據(jù)速率等)
UART串口通信需要兩根信號(hào)線來(lái)實(shí)現(xiàn),一根用于串口發(fā)送,另外一根負(fù)責(zé)串口接收
串口通信常用的波特率有9600/19200/38400/115200等
b. 物理層:接口類型,電平標(biāo)準(zhǔn)等
針對(duì)異步串行通信的接口標(biāo)準(zhǔn)有RS232、RS422、RS485
接口定義:
6. 串口通信實(shí)驗(yàn)
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
總結(jié)
以上是生活随笔為你收集整理的串行通信原理及实验仿真的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。