日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于STEP FPGA的UART串口通信模塊驅(qū)動(dòng)

          基于STEP FPGA的UART串口通信模塊驅(qū)動(dòng)

          作者: 時(shí)間:2023-11-29 來(lái)源:電子森林 收藏

          硬件說(shuō)明

          通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),通常稱作UART,是一種通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸和接收。
          異步通信以一個(gè)字符為傳輸單位,通信中兩個(gè)字符間的時(shí)間間隔多少是不固定的,然而在同一個(gè)字符中的兩個(gè)相鄰位間的時(shí)間間隔是固定的。兩個(gè)相鄰位間的時(shí)間間隔與UART通信的波特率有關(guān),波特率用來(lái)表征UART通信中數(shù)據(jù)傳輸?shù)乃俾剩疵棵腌妭魉偷亩M(jìn)制位數(shù)。例如數(shù)據(jù)傳送速率為120字符/秒,而每一個(gè)字符為10位(1個(gè)起始位,7個(gè)數(shù)據(jù)位,1個(gè)校驗(yàn)位,1個(gè)結(jié)束位),則其傳送的波特率為10×120=1200字符/秒=1200波特。

          本文引用地址:http://yuyingmama.com.cn/article/202311/453398.htm

          • 起始位:先發(fā)出一個(gè)邏輯”0”信號(hào),表示傳輸字符的開(kāi)始。
          • 數(shù)據(jù)位:可以是5~8位邏輯”0”或”1”。如ASCII碼(7位),擴(kuò)展BCD碼(8位)。小端傳輸
          • 校驗(yàn)位:數(shù)據(jù)位加上這一位后,使得“1”的位數(shù)應(yīng)為偶數(shù)(偶校驗(yàn))或奇數(shù)(奇校驗(yàn))
          • 停止位:它是一個(gè)字符數(shù)據(jù)的結(jié)束標(biāo)志。可以是1位、1.5位、2位的高電平。
          • 空閑位:處于邏輯“1”狀態(tài),表示當(dāng)前線路上沒(méi)有資料傳送。


          我們這里使用的時(shí)序?yàn)槿サ粜r?yàn)位的時(shí)序

          本設(shè)計(jì)共有四個(gè)模塊,一個(gè)top模塊,一個(gè)baud模塊,一個(gè)接收模塊和一個(gè)發(fā)送模塊,大家可以根據(jù)自己的需求進(jìn)行調(diào)整。


          Verilog代碼

          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: Uart_bus
          // 
          // Author: Step
          // 
          // Description: The module for uart communication
          // 
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2016/04/20   |Initial ver
          // --------------------------------------------------------------------
          module Uart_Bus #
          (
          parameter				BPS_PARA = 1250 //當(dāng)使用12MHz時(shí)鐘時(shí)波特率參數(shù)選擇1250對(duì)應(yīng)9600的波特率
          )
          (
          input					clk_in,			//系統(tǒng)時(shí)鐘
          input					rst_n_in,		//系統(tǒng)復(fù)位,低有效
          input					rs232_rx,		//FPGA中UART接收端,分配給UART模塊中的發(fā)送端TXD
          output					rs232_tx		//FPGA中UART發(fā)送端,分配給UART模塊中的接收端RXD
          );		 /////////////////////////////////UART接收功能模塊例化////////////////////////////////////
          wire					bps_en_rx,bps_clk_rx;
          wire			[7:0]	rx_data; //UART接收波特率時(shí)鐘控制模塊 例化
          Baud #
          (
          .BPS_PARA				(BPS_PARA		)
          )
          Baud_rx
          (	
          .clk_in					(clk_in			),	//系統(tǒng)時(shí)鐘
          .rst_n_in				(rst_n_in		),	//系統(tǒng)復(fù)位,低有效
          .bps_en					(bps_en_rx		),	//接收時(shí)鐘使能
          .bps_clk				(bps_clk_rx		)	//接收時(shí)鐘輸出
          ); 
          //UART接收數(shù)據(jù)模塊 例化
          Uart_Rx Uart_Rx_uut
          (
          .clk_in					(clk_in			),	//系統(tǒng)時(shí)鐘
          .rst_n_in				(rst_n_in		),	//系統(tǒng)復(fù)位,低有效
          .bps_en					(bps_en_rx		),	//接收時(shí)鐘使能
          .bps_clk				(bps_clk_rx		),	//接收時(shí)鐘輸入
          .rs232_rx				(rs232_rx		),	//UART接收輸入
          .rx_data				(rx_data		)	//接收到的數(shù)據(jù)
          ); 
           /////////////////////////////////UART發(fā)送功能模塊例化////////////////////////////////////
           wire					bps_en_tx,bps_clk_tx; 
           //UART發(fā)送波特率時(shí)鐘控制模塊 例化
           Baud #
           (
           .BPS_PARA				(BPS_PARA		)
           )
           Baud_tx
           (
           .clk_in					(clk_in			),	//系統(tǒng)時(shí)鐘
           .rst_n_in				(rst_n_in		),	//系統(tǒng)復(fù)位,低有效
           .bps_en					(bps_en_tx		),	//發(fā)送時(shí)鐘使能
           .bps_clk				(bps_clk_tx		)	//發(fā)送時(shí)鐘輸出
           ); 
           //UART發(fā)送數(shù)據(jù)模塊 例化
           Uart_Tx Uart_Tx_uut(.clk_in					(clk_in			),	//系統(tǒng)時(shí)鐘
           .rst_n_in				(rst_n_in		),	//系統(tǒng)復(fù)位,低有效
           .bps_en					(bps_en_tx		),	//發(fā)送時(shí)鐘使能
           .bps_clk				(bps_clk_tx		),	//發(fā)送時(shí)鐘輸入
           .rx_bps_en				(bps_en_rx		),	//因需要自收自發(fā),使用接收時(shí)鐘使能判定:接收到新的數(shù)據(jù),需要發(fā)送
           .tx_data				(rx_data		),	//需要發(fā)出的數(shù)據(jù)
           .rs232_tx				(rs232_tx		)	//UART發(fā)送輸出
           ); 
           endmodule
          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: Baud
          // 
          // Author: Step
          // 
          // Description: Beat for uart transfer and receive baud rate
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2016/04/20   |Initial ver
          // --------------------------------------------------------------------
          module Baud #
          (
          parameter				BPS_PARA = 1250 //當(dāng)使用12MHz時(shí)鐘時(shí)波特率參數(shù)選擇1250對(duì)應(yīng)9600的波特率
          )
          (
          input					clk_in,		//系統(tǒng)時(shí)鐘
          input					rst_n_in,	//系統(tǒng)復(fù)位,低有效
          input					bps_en,		//接收或發(fā)送時(shí)鐘使能
          output	reg				bps_clk		//接收或發(fā)送時(shí)鐘輸出
          );	 
          reg				[12:0]	cnt;//計(jì)數(shù)器計(jì)數(shù)滿足波特率時(shí)鐘要求
          always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) 
          		cnt <= 1'b0;
          	else if((cnt >= BPS_PARA-1)||(!bps_en)) //當(dāng)時(shí)鐘信號(hào)不使能(bps_en為低電平)時(shí),計(jì)數(shù)器清零并停止計(jì)數(shù)
          		cnt <= 1'b0;						
          		//當(dāng)時(shí)鐘信號(hào)使能時(shí),計(jì)數(shù)器對(duì)系統(tǒng)時(shí)鐘計(jì)數(shù),周期為BPS_PARA個(gè)系統(tǒng)時(shí)鐘周期
          	else 
          		cnt <= cnt + 1'b1;end //產(chǎn)生相應(yīng)波特率的時(shí)鐘節(jié)拍,接收模塊將以此節(jié)拍進(jìn)行UART數(shù)據(jù)接收
          		always @ (posedge clk_in or negedge rst_n_in)
          	begin
          		if(!rst_n_in) 
          			bps_clk <= 1'b0;
          		else if(cnt == (BPS_PARA>>1)) 	
          		//BPS_PARA右移一位等于除2,因計(jì)數(shù)器終值BPS_PARA為數(shù)據(jù)更替時(shí)間點(diǎn),所以計(jì)數(shù)器中值時(shí)為數(shù)據(jù)最穩(wěn)定時(shí)間點(diǎn)
          			bps_clk <= 1'b1;	
          		else 
          			bps_clk <= 1'b0;
          	end 
          	endmodule
          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: Uart_Rx
          // 
          // Author: Step
          // 
          // Description: The receive module of uart interface
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2016/04/20   |Initial ver
          // --------------------------------------------------------------------
          module Uart_Rx(input					clk_in,			//系統(tǒng)時(shí)鐘
          input					rst_n_in,		//系統(tǒng)復(fù)位,低有效 
          output	reg				bps_en,			//接收時(shí)鐘使能
          input					bps_clk,		//接收時(shí)鐘輸入 
          input					rs232_rx,		//UART接收輸入
          output	reg		[7:0]	rx_data			//接收到的數(shù)據(jù)
          );	 
          reg	rs232_rx0,rs232_rx1,rs232_rx2;	//多級(jí)延時(shí)鎖存去除亞穩(wěn)態(tài)
          always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		rs232_rx0 <= 1'b0;
          		rs232_rx1 <= 1'b0;
          		rs232_rx2 <= 1'b0;
          	end else begin
          		rs232_rx0 <= rs232_rx;
          		rs232_rx1 <= rs232_rx0;
          		rs232_rx2 <= rs232_rx1;
          	endend //檢測(cè)UART接收輸入信號(hào)的下降沿
          	wire	neg_rs232_rx = rs232_rx2 & rs232_rx1 & (~rs232_rx0) & (~rs232_rx);	 
          	reg				[3:0]	num;			//接收時(shí)鐘使能信號(hào)的控制
          	always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in)
          		bps_en <= 1'b0;
          	else if(neg_rs232_rx && (!bps_en))	
          	//當(dāng)空閑狀態(tài)(bps_en為低電平)時(shí)檢測(cè)到UART接收信號(hào)下降沿,進(jìn)入工作狀態(tài)(bps_en為高電平),控制時(shí)鐘模塊產(chǎn)生接收時(shí)鐘
          		bps_en <= 1'b1;		
          	else if(num==4'd9)		      		//當(dāng)完成一次UART接收操作后,退出工作狀態(tài),恢復(fù)空閑狀態(tài)
          		bps_en <= 1'b0;			
          		end 
          		reg				[7:0]	rx_data_r;//當(dāng)處于工作狀態(tài)中時(shí),按照接收時(shí)鐘的節(jié)拍獲取數(shù)據(jù)
          		always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		num <= 4'd0;
          		rx_data <= 8'd0;
          		rx_data_r <= 8'd0;
          	end else if(bps_en) begin	
          		if(bps_clk) begin			
          			num <= num+1'b1;
          			if(num<=4'd8)
          			rx_data_r[num-1]<=rs232_rx;	//先接受低位再接收高位,8位有效數(shù)據(jù)
          		end else if(num == 4'd9) begin	//完成一次UART接收操作后,將獲取的數(shù)據(jù)輸出
          			num <= 4'd0;			
          			rx_data <= rx_data_r;	
          		end
          	end
          	end 
          	endmodule
          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module: Uart_Tx
          // 
          // Author: Step
          // 
          // Description: The transfer module of uart interface
          // 
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2016/04/20   |Initial ver
          // --------------------------------------------------------------------
          module Uart_Tx
          (
          input					clk_in,			//系統(tǒng)時(shí)鐘
          input					rst_n_in,		//系統(tǒng)復(fù)位,低有效
          output	reg				bps_en,			//發(fā)送時(shí)鐘使能
          input					bps_clk,		//發(fā)送時(shí)鐘輸入
          input					rx_bps_en,		
          //因需要自收自發(fā),使用接收時(shí)鐘使能判定:接收到新的數(shù)據(jù),需要發(fā)送
          input			[7:0]	tx_data,		//需要發(fā)出的數(shù)據(jù)
          output	reg				rs232_tx		//UART發(fā)送輸出
          ); 
          reg						rx_bps_en_r;//延時(shí)鎖存接收時(shí)鐘使能信號(hào)
          always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) rx_bps_en_r <= 1'b0;
          	else rx_bps_en_r <= rx_bps_en;end //檢測(cè)接收時(shí)鐘使能信號(hào)的下降沿,因?yàn)橄陆笛卮斫邮諗?shù)據(jù)的完成,以此作為發(fā)送信號(hào)的激勵(lì)
          	wire	neg_rx_bps_en = rx_bps_en_r & (~rx_bps_en); 
          	reg				[3:0]	num;
          	reg				[9:0]	tx_data_r;	//根據(jù)接收數(shù)據(jù)的完成,驅(qū)動(dòng)發(fā)送數(shù)據(jù)操作
          	always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		bps_en <= 1'b0;
          		tx_data_r <= 8'd0;
          	end else if(neg_rx_bps_en)begin	
          		bps_en <= 1'b1;						
          		//當(dāng)檢測(cè)到接收時(shí)鐘使能信號(hào)的下降沿,表明接收完成,需要發(fā)送數(shù)據(jù),使能發(fā)送時(shí)鐘使能信號(hào)
          		tx_data_r <= {1'b1,tx_data,1'b0};	
          	end else if(num==4'd10) begin	
          		bps_en <= 1'b0;	//一次UART發(fā)送需要10個(gè)時(shí)鐘信號(hào),然后結(jié)束
          	endend //當(dāng)處于工作狀態(tài)中時(shí),按照發(fā)送時(shí)鐘的節(jié)拍發(fā)送數(shù)據(jù)
          	always @ (posedge clk_in or negedge rst_n_in) begin
          	if(!rst_n_in) begin
          		num <= 1'b0;
          		rs232_tx <= 1'b1;
          	end else if(bps_en) begin
          		if(bps_clk) begin
          			num <= num + 1'b1;
          			rs232_tx <= tx_data_r[num];
          		end else if(num>=4'd10) 
          			num <= 4'd0;	
          	end
          	end 
          	endmodule

          小結(jié)

          本節(jié)主要為大家講解了UART通信的原理及軟件設(shè)計(jì),需要大家掌握的同時(shí)自己創(chuàng)建工程,通過(guò)整個(gè)設(shè)計(jì)流程,生成FPGA配置文件加載測(cè)試。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉