日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

串行通信原理及实验仿真

發布時間:2023/12/31 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 串行通信原理及实验仿真 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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) beginif(!sys_rst_n) beginuart_rxd_d0 <= 1'b0;uart_rxd_d1 <= 1'b0;endelse beginuart_rxd_d0 <= uart_rxd;uart_rxd_d1 <= uart_rxd_d0; endendalways @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)rx_flag <= 1'b0;else beginif(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) beginif(!sys_rst_n) beginclk_cnt <= 16'd0;rx_cnt <= 4'd0;end else if(rx_flag) beginif(clk_cnt < BPS_CNT -1) beginclk_cnt <= clk_cnt + 1'b1;rx_cnt <= rx_cnt;endelse beginclk_cnt <= 16'd0;rx_cnt <= rx_cnt + 1'b1; endendelse beginclk_cnt <= 16'd0;rx_cnt <= 4'd0; endend//根據接收數據技術來寄存uart接收端口數據always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)rxdata <= 8'd0;else if(rx_flag) beginif(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:;endcaseendelse rxdata <= rxdata;endelserxdata <= 8'd0;always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n) beginuart_data <= 8'd0;uart_done <= 1'b0;endelse if(rx_cnt == 4'd9) beginuart_data <= rxdata;uart_done <= 1'b1; endelse 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) beginif(!sys_rst_n) beginuart_en_d0 <= 1'b0;uart_en_d1 <= 1'b0;endelse beginuart_en_d0 <= uart_en;uart_en_d1 <= uart_en_d0; endendalways @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n) begintx_flag <= 1'b0;tx_data <= 8'd0;endelse if(en_flag) begintx_flag <= 1'b1;tx_data <= uart_din;endelse if((tx_cnt == 4'd9) && (clk_cnt == BPS_CNT/2)) begintx_flag <= 1'b0;tx_data <= 8'd0;endelse begintx_flag <= tx_flag;tx_data <= tx_data;endendalways @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n) beginclk_cnt <= 16'd0;tx_cnt <= 4'd0;end else if(tx_flag) beginif(clk_cnt < BPS_CNT -1) beginclk_cnt <= clk_cnt + 1'b1;tx_cnt <= tx_cnt;endelse beginclk_cnt <= 16'd0;tx_cnt <= tx_cnt + 1'b1; endendelse beginclk_cnt <= 16'd0;tx_cnt <= 4'd0; endendalways @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)uart_txd <= 1'b1;else if(tx_flag) begincase(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:;endcaseendelserxdata <= 8'd0;endendmoduleendmodule

總結

以上是生活随笔為你收集整理的串行通信原理及实验仿真的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。