FPGA实战 -- UART --- 实现串口回环(加FIFO)

这篇具有很好参考价值的文章主要介绍了FPGA实战 -- UART --- 实现串口回环(加FIFO)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

FPGA基础 – 通信协议 — 了解UART以及电脑串口环境准备



前言

咱们上一文章学过了UART的基础,已经初步了解了协议的基础知识和时序要求,接下来就是将学到的写出东西来,本文通过上位机的串口助手发送数据,FIFO将数据在RX和TX之间进行传递,并且传递回上位机的串口助手,修改校验方式数据会发生变化。


一、思路设计

1、框架图

FPGA实战 -- UART --- 实现串口回环(加FIFO),FPGA实战,fpga开发,fpga

大体框架就如图所示,通过电脑串口助手发送数据,FPGA芯片的RX将数据接收,经过FIFO缓存传输到TX,再由TX传输回到串口助手。

二、代码

1.RX

rx模块:接收串口助手发送过来的数据。

状态机:FPGA实战 -- UART --- 实现串口回环(加FIFO),FPGA实战,fpga开发,fpga

由上一篇文章知道,在传输数据的过程中,一共有四种总线的变化。
起始位(1bit)、数据位(8bit)、校验位(1bit)、停止位(1bit)。所以设置了五个状态来控制总线。
传输数据速率是由波特率来决定的,所以设置一个波特率计数器和bit计数器,来控制总线上数据的传输和状态机的变换。

assign idle2start  = state_c == IDLE   &&  rx == 0  ;
assign start2data  = state_c == START  &&  end_cnt_bps  ;
assign data2stop   = state_c == DATA   &&  end_cnt_bit && CHECK_BIT == "None" ;
assign data2check  = state_c == DATA   &&  end_cnt_bit  ;
assign check2stop  = state_c == CHECK  &&  end_cnt_bps  ;
assign stop2idle   = state_c == STOP   &&  end_cnt_bps  ;

上边的代码就是状态机的状态跳转条件:
由初始状态到发送起始位总线会拉低1bit的时间,所以条件就是当总线拉低时表示发送起始位。
接下来就是按照每个状态会通过总线发送几bit的数据来控制状态的跳转。其中校验位通过顶层来设置有无校验或者奇偶校验。
如果代码中的CHECK_BIT是无校验的话,发送完8bit的数据就会直接发送停止位。有校验位就会先跳转到发送校验位的状态,再发停止位。

assign check_val	=	(CHECK_BIT == "Odd")? ~^rx_data : ^rx_data;

上边的代码就是发送的校验位。上一章已经提过了,奇校验和偶校验指

若是奇校验,则要保证发送的数据中“1”的bit数是奇数个。
若是偶校验,则要保证发送的数据中“1”的bit数是偶数个。

在代码中的写法就是“奇同偶异”,
奇校验就是将8bit的数据进行按位同或;
偶校验就是将8bit的数据进行按位异或;

例如我想写入一个:11010001。下面图中的红色就是数据中的每一位,黑色就是异或后得到的值。异或就是相同为0,不同为1。最后得到的值就是0。校验位就是0。和8bit数据和在一起就是110100010。一共有4位1,符合偶校验的要求。
FPGA实战 -- UART --- 实现串口回环(加FIFO),FPGA实战,fpga开发,fpga
仔细看上边

下面就是完整的代码。基本上注释写的差不多,有哪些不懂得发评论区或加qq:35二4291零六5

//---------<模块及端口声名>------------------------------------------------------
module rx( 
    input             clk         ,
    input             rst_n       ,
    input             rx          ,
    output reg [7:0]  rx_data     ,
    output            rx_data_vld 	
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter	CHECK_BIT = "None" ;            
parameter   BPS = 115200       ;
parameter   CLK = 50_000_000   ;
parameter   BPS_MAX = CLK/BPS  ;

//---------<内部信号定义>-----------------------------------------------------
localparam  IDLE  = 'b00001 ,//初始状态
            START = 'b00010 ,//发送起始位
            DATA  = 'b00100 ,//发送数据
            CHECK = 'b01000 ,//发送校验位
            STOP  = 'b10000 ;//发送停止位
reg   [4:0] state_c     ;//现态
reg   [4:0] state_n     ;//次态
wire        idle2start  ;
wire        start2data  ;
wire        data2stop   ;
wire        data2check  ;
wire        check2stop  ;
wire        stop2idle   ; 
//波特率计数器
reg  [12:0] cnt_bps	    ;
wire        add_cnt_bps ;
wire        end_cnt_bps ; 
//bit计数器
reg  [2:0]  cnt_bit	    ;
wire        add_cnt_bit ;
wire        end_cnt_bit ;
reg  [3:0]  bit_max     ;

//校验位
reg		    rev_check	;
wire		check_val	;

//****************************************************************
//--状态机
//****************************************************************   
	//第一段:时序逻辑描述状态转移
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
       state_c <= IDLE ;
   end 
   else begin 
       state_c <= state_n ;
   end 
end
   //第二段:组合逻辑描述状态转移规律和状态转移条件
always @(*)begin 
   case (state_c)
       IDLE   : begin
           if (idle2start) begin
               state_n = START ;
           end
           else begin
               state_n = state_c ;
           end
       end 
       START   : begin
           if (start2data) begin
               state_n = DATA ;
           end
           else begin
               state_n = state_c ;
           end
       end 
       DATA   : begin
           if (data2stop) begin
               state_n = STOP ;
           end
           else if (data2check) begin
               state_n = CHECK ;
           end
           else begin
               state_n = state_c ;
           end
       end
       CHECK   : begin
           if (check2stop) begin
               state_n = STOP ;
           end
           else begin
               state_n = state_c ;
           end
       end  
       STOP   : begin
           if (stop2idle) begin
               state_n = IDLE ;
           end
           else begin
               state_n = state_c ;
           end
       end 
       default: state_n = IDLE ;
   endcase
end	
//第三段:描述输出,时序逻辑或组合逻辑皆可
assign idle2start  = state_c == IDLE   &&  rx == 0  ;
assign start2data  = state_c == START  &&  end_cnt_bps  ;
assign data2stop   = state_c == DATA   &&  end_cnt_bit && CHECK_BIT == "None" ;
assign data2check  = state_c == DATA   &&  end_cnt_bit  ;
assign check2stop  = state_c == CHECK  &&  end_cnt_bps  ;
assign stop2idle   = state_c == STOP   &&  end_cnt_bps  ;
//****************************************************************
//--波特率计数器
//****************************************************************
 always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_bps <= 'd0 ;
    end 
    else if(add_cnt_bps)begin 
        if(end_cnt_bps)begin 
            cnt_bps <= 'd0 ;
        end
        else begin 
            cnt_bps <= cnt_bps + 1'b1 ;
        end 
    end
 end 
 
 assign add_cnt_bps = state_c != IDLE ;
 assign end_cnt_bps = add_cnt_bps && cnt_bps == BPS_MAX - 1;
 
//****************************************************************
//--位数
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_bit <= 'd0 ;
    end 
    else if(add_cnt_bit)begin 
        if(end_cnt_bit)begin 
            cnt_bit <= 'd0 ;
        end
        else begin 
            cnt_bit <= cnt_bit + 1'b1 ;
        end 
    end
end 

assign add_cnt_bit = end_cnt_bps && state_c == DATA ;
assign end_cnt_bit = add_cnt_bit && cnt_bit == bit_max - 1;

always @(*)begin 
    case (state_c)
        IDLE  : bit_max <= 1 ; 
        START : bit_max <= 1 ; 
        DATA  : bit_max <= 8 ; 
        CHECK : bit_max <= 1 ;
        STOP  : bit_max <= 1 ;
        default: bit_max <= 1 ; 
    endcase
end

//****************************************************************
//--接受
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        rx_data <= 0;
    end 
    else begin
        case (state_c)
            IDLE  :  rx_data <= 0 ; 
            START :  rx_data <= rx_data ;
            DATA  :  if(cnt_bps == BPS_MAX / 2)
                        rx_data[cnt_bit] <= rx ;
            CHECK :  rx_data <= rx_data ;            
            STOP  :  rx_data <= rx_data ;
            default: rx_data <= 0 ;
        endcase
    end
end

//****************************************************************
//--接收校验位
//****************************************************************
always @(posedge clk or negedge rst_n) begin
	if (!rst_n) begin
		rev_check <= 'd0;
	end
	else if (state_c == CHECK && cnt_bps == BPS_MAX / 2) begin
		rev_check <= rx;
	end
	else begin
		rev_check <= rev_check;
	end
end

//****************************************************************
//--计算校验位
//****************************************************************
assign check_val	=	(CHECK_BIT == "Odd")? ~^rx_data : ^rx_data;

assign rx_data_vld	=	(CHECK_BIT == "None")	? (state_c == DATA	&& end_cnt_bit)
					:	((state_c == CHECK	&& end_cnt_bps) && (check_val == rev_check)) ? 1
					:	0;

endmodule

2.TX

TX发送模块是指由FPGA芯片将接收到的数据发送回PC端 串口助手上。

这个模块的状态机和校验位基本都一样,也没啥说的。上代码

//---------<模块及端口声名>------------------------------------------------------
module tx(
    input              clk		     ,
    input              rst_n	     ,
    input     [7:0]    tx_data	     ,
    input              tx_data_vld	 ,
    output             ready         ,
    output    reg      tx	
);								 
//---------<参数定义>--------------------------------------------------------- 
 localparam  IDLE  = 'b00001 ,//初始状态
             START = 'b00010 ,//发送起始位
             DATA  = 'b00100 ,//发送数据
             CHECK = 'b01000 ,//发送校验位
             STOP  = 'b10000 ;//发送停止位
             
 parameter	 CHECK_BIT = "None";
 parameter   BPS = 115200     ;
 parameter   CLK = 50_000_000 ;
 parameter   BPS_MAX = CLK/BPS ;
//---------<内部信号定义>-----------------------------------------------------
 reg   [4:0] state_c ;//现态
 reg   [4:0] state_n ;//次态
 wire        idle2start;
 wire        start2data;
 wire        data2stop ;//有校验位
 wire        data2check;//无校验位
 wire        check2stop;
 wire        stop2idle ; 

 reg  [12:0] cnt_bps	 ;
 wire        add_cnt_bps ;
 wire        end_cnt_bps ; 
 reg  [2:0]  cnt_bit	 ;
 wire        add_cnt_bit ;
 wire        end_cnt_bit ;

 reg  [3:0]  bit_max    ;
 reg  [7:0]  tx_data_t  ;
 wire		 check_vld  ;  

 always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        tx_data_t <= 'd0;
    end 
    else if(tx_data_vld)begin 
        tx_data_t <= tx_data ;
    end 
    else begin 
        tx_data_t <= tx_data_t ;
    end 
end

 //****************************************************************
 //--状态机
 //****************************************************************   
 	//第一段:时序逻辑描述状态转移
 always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        state_c <= IDLE ;
    end 
    else begin 
        state_c <= state_n ;
    end 
 end

    //第二段:组合逻辑描述状态转移规律和状态转移条件
 always @(*)begin 
    case (state_c)
        IDLE   : begin
            if (idle2start) begin
                state_n = START ;
            end
            else begin
                state_n = state_c ;
            end
        end 
        START   : begin
            if (start2data) begin
                state_n = DATA ;
            end
            else begin
                state_n = state_c ;
            end
        end 
        DATA   : begin
            if (data2stop) begin
                state_n = STOP ;
            end
            else if (data2check) begin
                state_n = CHECK ;
            end
            else begin
                state_n = state_c ;
            end
        end 
        CHECK   : begin
            if (check2stop) begin
                state_n = STOP ;
            end
            else begin
                state_n = state_c ;
            end
        end
        STOP   : begin
            if (stop2idle) begin
                state_n = IDLE ;
            end
            else begin
                state_n = state_c ;
            end
        end 
        default: state_n = IDLE ;
    endcase
 end

	//第三段:描述输出,时序逻辑或组合逻辑皆可
 assign idle2start  = state_c == IDLE   &&  tx_data_vld  ;
 assign start2data  = state_c == START  &&  end_cnt_bps  ;
 assign data2stop   = state_c == DATA   &&  end_cnt_bit && CHECK_BIT == "None" ;
 assign data2check  = state_c == DATA   &&  end_cnt_bit  ;
 assign check2stop  = state_c == CHECK  &&  end_cnt_bps  ;
 assign stop2idle   = state_c == STOP   &&  end_cnt_bps  ;

//****************************************************************
//--波特率计数器
//****************************************************************
 always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_bps <= 'd0 ;
    end 
    else if(add_cnt_bps)begin 
        if(end_cnt_bps)begin 
            cnt_bps <= 'd0 ;
        end
        else begin 
            cnt_bps <= cnt_bps + 1'b1 ;
        end 
    end
 end 
 
 assign add_cnt_bps = state_c != IDLE ;
 assign end_cnt_bps = add_cnt_bps && cnt_bps == BPS_MAX - 1;
 
//****************************************************************
//--位数
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_bit <= 'd0 ;
    end 
    else if(add_cnt_bit)begin 
        if(end_cnt_bit)begin 
            cnt_bit <= 'd0 ;
        end
        else begin 
            cnt_bit <= cnt_bit + 1'b1 ;
        end 
    end
end 

assign add_cnt_bit = end_cnt_bps && state_c == DATA ;
assign end_cnt_bit = add_cnt_bit && cnt_bit == bit_max - 1;

always @(*)begin 
    case (state_c)
        IDLE  : bit_max <= 1 ; 
        START : bit_max <= 1 ; 
        DATA  : bit_max <= 8 ; 
        CHECK : bit_max <= 1 ;
        STOP  : bit_max <= 1 ;
        default: bit_max <= 1 ; 
    endcase
end
//****************************************************************
//--校验
//****************************************************************
assign check_vld = 	(CHECK_BIT == "Odd")? ~^tx_data_t : ^tx_data_t;

//****************************************************************
//--输出
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        tx <= 1;
    end 
    else case (state_c)
        IDLE  : tx <= 1;//初始状态下总线拉高
        START : tx <= 0;//起始位将总线拉低1bit
        DATA  : tx <= tx_data_t[cnt_bit];//低位先发
        CHECK : tx <= check_vld;//有校验位的话就对校验位进行发送
        STOP  : tx <= 1;//停止位拉高
        default: tx <= 1;
    endcase
end

assign ready = state_c == IDLE ;

endmodule

3.CTRL

控制模块主要是将数据通过fifo进行缓存,没有这个模块也可以,就是在top里多些几行控制数据传输的代码就行。fifo的调用不会直接看我之前的文章。
点个传送门:fifo IP核调用

有的作者写的不加fifo串口回环也很简单,可以多找一些看一看。

//---------<模块及端口声名>------------------------------------------------------
module ctrl( 
    input              clk         ,	
    input              rst_n       ,
    input              ready       ,
    input    [7:0]     rx_data     ,
    input              rx_data_vld ,	
    output   [7:0]     tx_data     ,
    output             tx_data_vld 
);								 
//---------<参数定义>--------------------------------------------------------- 
  wire  fifo_full  ;
  wire  fifo_empty ;  
//---------<内部信号定义>-----------------------------------------------------
  fifo	fifo_inst (
	.aclr      (  ~rst_n      ),

	.data      (  rx_data      ),
	.wrclk     (  clk          ),
	.wrreq     (  rx_data_vld && ~fifo_full      ),
    .wrfull    (  fifo_full    ),

	.q         (  tx_data      ),	
    .rdclk     (  clk          ),
	.rdreq     (  ready && ~fifo_empty      ),
	.rdempty   (  fifo_empty   ),

	.rdusedw   (        ),
	.wrusedw   (        )
	);
  
  	assign tx_data_vld = ready && ~fifo_empty;  
    
endmodule

4.TOP

defparam		rx_inst.CHECK_BIT = "Odd";//"Odd"奇校验 "Even"偶校验 "None"无校验位
defparam		tx_inst.CHECK_BIT = "Odd";//"Odd"奇校验 "Even"偶校验 "None"无校验位

这里就是控制代码使用校验位的代码。tx和rx一定要在同一种校验下进行传输,不然数据会出错。

//---------<模块及端口声名>------------------------------------------------------
module top( 
   input               clk		  ,
   input               rst_n	  ,
   input               rx       ,
   output              tx	
);								 
//---------<参数定义>--------------------------------------------------------- 
wire  [7:0]  rx_data ;
wire         rx_data_vld ;
wire  [7:0]  tx_data ;
wire         tx_data_vld ;
wire         ready ;  
//---------<内部信号定义>-----------------------------------------------------
defparam		rx_inst.CHECK_BIT = "Odd";//"Odd"奇校验 "Even"偶校验 "None"无校验位
defparam		tx_inst.CHECK_BIT = "Odd";//"Odd"奇校验 "Even"偶校验 "None"无校验位

rx rx_inst( 
   /*input         */.clk         (clk ),
   /*input         */.rst_n       (rst_n ),
   /*input         */.rx          (rx ),
   /*output [7:0]  */.rx_data     (rx_data ),
   /*output        */.rx_data_vld (rx_data_vld )	
);   

   tx tx_inst(
    /*input              */.clk		     (clk ),
    /*input              */.rst_n	     (rst_n ),
    /*input     [7:0]    */.tx_data	     (tx_data ),
    /*input              */.tx_data_vld  (tx_data_vld ),
    /*output             */.ready        (ready ),
    /*output             */.tx	        (tx )
);
  
ctrl ctrl_inst( 
   /*input             */.clk         (clk ),	
   /*input             */.rst_n       (rst_n ),
   /*input    [7:0]    */.rx_data     (rx_data ),
   /*input             */.rx_data_vld (rx_data_vld ),	
   /*input             */.ready       (ready ),
   /*output   [7:0]    */.tx_data     (tx_data ),
   /*output            */.tx_data_vld (tx_data_vld )
);   
    

endmodule

5.仿真

`timescale 1ns/1ns
	
module top_tb();

//激励信号定义
	reg		 clk;
	reg		 rst_n;
	reg		 tx_data_vld;
	reg	[7:0]tx_data;
//输出信号定义	 
	wire	ready;
	wire	tx;
	wire	tx_2;
//时钟周期参数定义	
	parameter		CLOCK_CYCLE = 20;

//模块例化

	tx tx_inst(
		/* input	wire			 */.clk			(clk		),
		/* input	wire			 */.rst_n		(rst_n		),
		/* input	wire	[7:0]	 */.tx_data		(tx_data	),
		/* input	wire			 */.tx_data_vld	(tx_data_vld	),

		/* output	wire			 */.ready	    (ready	),
		/* output	reg				 */.tx		    (tx	) 
	);

	top top_inst(
		/* input	wire			 */.clk			(clk		),
		/* input	wire			 */.rst_n		(rst_n		),
		/* input	wire			 */.rx		(tx	),

		/* output	wire		 	 */.tx		(tx_2	) 
	);

//产生时钟
	always #(CLOCK_CYCLE / 2) clk = ~clk;
	initial begin
		clk = 1'b0;
		rst_n = 1'b0;
		#(CLOCK_CYCLE * 2);
		rst_n = 1'b1;
	end
//产生激励
	initial begin
		tx_data = 0;
		tx_data_vld = 0;
		#(CLOCK_CYCLE * 5);
		repeat(16) begin
			tx_data_vld = 1;
			tx_data = {$random};
			#20;
			tx_data_vld = 0;
			wait(ready == 1);
			#20;
		end

		#(CLOCK_CYCLE * 50);
		$stop;
	end

endmodule 

仿真代码加在这里,结果没错,反正网站上的图片也不能放大,就不放仿真图片了,可以自己去看。

温馨提示:本人不放仿真图片一是因为网站上的图片不能放大,看不清楚;二是懒。但是懂得看仿真是学会FPGA很重要的手段。如果各位看这个仿真有哪里不懂,记得加qq问,我可以解释。


总结

代码设置的奇校验,视频中可以看出来当串口助手不用奇校验时数据都是出错的。

UART串口回环

摄像头花了,有点模糊,各位在试验代码的时候如果发生错误记得说。

代码工程都放进baidu网盘了,自行提取(之前的一些baidu网盘链接失效了,我把我所有文章的链接都换了)

链接:https://pan.baidu.com/s/1lQqqWZXfb3i6XHwkKf52zg
提取码:yang文章来源地址https://www.toymoban.com/news/detail-830069.html

到了这里,关于FPGA实战 -- UART --- 实现串口回环(加FIFO)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA】UART串口通信——奇偶校验实现

    奇偶校验位是基于uart的数据上进行一个判断 奇校验:数据1个数为奇时,校验为0,反之为1 偶校验:数据0个数为偶时,校验为0,反之为1 Uart回环在之前已经实现,现在需要基于uart增加一个奇偶校验位的需求 uart及代码:https://blog.csdn.net/weixin_59150966/article/details/128005066?spm=10

    2024年02月11日
    浏览(42)
  • FPGA入门 —— FPGA UART 串口通信

    UART 通用异步收发传输器( Universal Asynchronous Receiver/Transmitter) ,通常称作 UART。 UART 是一种通用的数据通信协议,也是异步串行通信口(串口)的总称,它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。 它包括了ch340、 RS232、

    2024年02月09日
    浏览(46)
  • 基于异步FIFO的串口回环测试

      当涉及到串口通信的硬件设计和软件开发时,进行有效的测试是至关重要的。串口回环测试是一种常见的测试方法,用于验证串口通信的功能和稳定性。在许多应用中,为了确保串口通信的正常运行,往往需要使用缓冲区或FIFO来管理数据的传输和接收。   基于异步F

    2024年02月16日
    浏览(63)
  • 基于FPGA的超声波测距——UART串口输出

    环境: 1、Quartus18.0 2、vscode 3、板子型号:EP4CE10F17C8 4、超声波模块:HC_SR04 要求: 使用 EP4CE10F17C8开发板驱动 超声波检测模块(HC_SR04 ),并将所测得数据显示到串口助手上。 HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm;模块包括超声波发

    2024年02月14日
    浏览(46)
  • FPGA 串口通信(uart)初探篇(含源代码)

    一、UART 串口通信,说实话是日常生活中很常见的一种9针型的主机和显示屏之间的通信模式。本次博客,只为自己复盘相关知识,初学者,错误较多,请多指教。所以本文参考(一)FPGA之串口通信(UART)_fpga uart-CSDN博客 而编著的。 FPGA是一种可编程的逻辑器件,用于各种数字电

    2024年04月14日
    浏览(35)
  • FPGA_数码管显示UART串口接收的数据

          实验目标 :通过电脑调试助手向FPGA的UART串口接收模块发送数据,然后数据可以稳定显示 在数码管上。       实验目的 : 练习UART串口模块和数码管的使用。之前已经有文章详细讲解了串口和数码管的开发,故这里直接提供设计思路供大家参考。 (串口文章链接)ht

    2024年02月13日
    浏览(49)
  • (五)零基础学懂FPGA中的串口通信(UART)

    此篇为专栏 《FPGA学习笔记》 的第五篇,记录我的学习FPGA的一些开发过程和心得感悟,刚接触FPGA的朋友们可以先去此专栏置顶 《FPGA零基础入门学习路线》来做最基础的扫盲。 本篇内容基于笔者实际开发过程和正点原子资料撰写,将会详细讲解此FPGA实验的全流程, 诚挚 地

    2024年02月04日
    浏览(52)
  • UART串口通信(回环测试)

            UART(Universal Asynchronous Receiver-Transmitter)是采用异步串行通信方式的通用异步收发传输器,在发送数据时将并行数据转换为串行数据,在接收数据时将串行数据转换为并行数据。发送和接收的一帧数据由起始位、数据位、奇偶校验位和停止位组成,其数据帧格式如

    2024年02月05日
    浏览(56)
  • FPGA实战 -- UART --- 封装UART IP核

    FPGA基础 – 通信协议 — 了解UART以及电脑串口环境准备 FPGA实战 – UART — 实现串口回环(加FIFO) 咱们已经学习了UART协议,并且编写了串口回环的代码。每次一些项目遇到串口的时候都要对 RX 或者 TX 代码进行修改,像本人这种非非非非常懒的人,肯定不愿意经常修改代码,

    2024年02月21日
    浏览(39)
  • uart串口环回(加FIFO)

    UART(universal asynchronous receiver-transmitter)是一种采用异步串行通信方式的通用异步收发传输器。 定义如上,那么出现问题了,什么叫异步串行通信?请关注下文原理。 1.1同步通信 发送方发送出数据后,等接收方响应后才发送下一个数据 1.2异步通信 发送方发出数据后,不等接

    2024年01月24日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包