UART 串口收发模块设计及Verilog实现

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

一、UART协议介绍

UART的全称是通用异步收发器(Universal Asynchronous Receiver/Transmitter)。

Universal 通用性: 体现在UART使用范围广上,作为一个通用的接口协议,UART广泛的应用在各类MCU和SOC产品上。
Asynchronous 异步性: 体现在”不需要额外的时钟线进行数据的同步传输”即只要信号拉低,即可开始传送数据,而另一些通讯协议,需要引入时钟信号来进行操作,如AMBA,需要在时钟的上升沿发送数据。
Receiver/Transmitter收发器:则更好理解,即一个数据的发送方和一个数据的接收方,也意味着在数字IC设计中需要分别设计Receiver和Transmitter。

发送端的UART将来自控制设备(如CPU)的并行数据转换为串行数据,以串行方式将其发送到接收端的UART,然后由接收端的UART将串行数据转换为并行数据以用于接收设备的正常处理。

这里只需要两条线RX/TX即可在两个UART之间传输数据。具体如下图所示;
UART 串口收发模块设计及Verilog实现

1.1 UART协议层

1.2.1 UART的帧格式

UART的一帧由1位起始位 、5~9个数据位 、一个可选的奇偶校验位 和停止位 组成。数据逐位传输,如下图所示。
UART 串口收发模块设计及Verilog实现

  1. 为什么UART的传输需要起始位?

    因为UART没有控制线,要让接收方知道什么时候开始接收数据,需要一些手段。

    在发送数据之前,先发一位逻辑“0”作为数据发送的起始标志,接收方在空闲时,当检测到有一个低电平,则开始以波特率的频率接逐位接收数据。

    在具体设计UART的过程中,如何检测低电平,使用到了电平检测电路。很显然这里使用的是下降沿检测电路

  2. UART基本的数据形式

    • 默认无传输数据时,为高电平。

    • 当信号拉低,传输线上的电平拉低,意味着开始进行数据传输

    • 紧接着起始位的是数据位,它可以是5、6、7或8位

    • UART的“校验位”紧挨着“数据位”,采用奇偶校验​ 方式,根据设置,校验位可以存在也可以不存在。

    • UART将停止位作为停止标志,是在数据位(没有校验位)和校验位(有校验位)之后发送1~2位的逻辑“1”高电平。当发送完停止位之后,UART总线进入空闲。

  3. 为什么UART的数据位可变?

    数据位包含正在传输的实际数据。如果使用奇偶校验位,则可以是5位,最多8位。如果不使用奇偶校验位,则数据帧的长度可以为9位。

    因为UART是一种低速总线,每多发一位都占用不少的时间(由传输波特率决定),所以可以根据传输数据的特点,采用不同位宽以节约数据传输的时间。

1.2.2 UART的波特率

如果从更高的level审视UART传输协议,如嵌入式开发者的角度,我们会发现,在使用具体的UART协议前,我们需要对发送端和接收端进行波特率的同步,以此来确保发射端的数据可以在接收端得到正确的采集。常用的波特率可以是300,1200,2400,9600,19200,38400,115200,这些数意味着什么呢?别着急,我们接下来要讨论这个内容。

  1. 什么是波特率

    波特率等于每秒钟传输的数据位数,即Bit/s。 假如波特率设置为9600,那么意味着每秒该UART传输协议可以传输9600bits的数据,换句话说传输1比特需时间约为:10^9(ns)/9600=104166(ns)。

    下表是各个波特率下数据位时间宽度。
    UART 串口收发模块设计及Verilog实现

  2. 如何换算波特率

    时钟频率假如为100MHz,这意味着我们的时钟周期为10ns,因此10416个时钟周期我们就可以传输1bit数据,换言之我们需要一个大小为10416的分频电路来对100MHz时钟进行处理,因此在设计UART的过程中,我们需要使用分频电路依据波特率处理全局时钟,依据分频后的时钟节奏来发送数据和接收数据。

    同样的,参考作者之前的文章,我们可以获知分频电路的设计方法

  3. 波特率和采样频率是一样的吗?

    按照前文所说,好像波特率和采样频率是一个意思,即9600波特率对应接收端1s进行9600次采样,也对应发射端1s进行9600bit的发射,那么请读者思考,真的是这样吗?
    答案其实是否定的
    这是因为:在数据的传输中,信号可能受到一些干扰而产生一些抖动(比如说电磁兼容性设计中的近端串扰),如果接收端只对这些信号进行一次采样,那么它有可能采样到的是不准确的数据,所以接收端在采样时,通常都要
    采样多次
    ,然后通过处理获得准确的数据,比如说,我们可以用多数表决的方法来在接收端进行多次采样,得到准确值。

1.2 UART物理层

1.3.1 物理连接

UART 串口收发模块设计及Verilog实现

1.3.2 接口标准

UART、RS232、RS485在串口通信中,主要区别是电平的不同,其中UART通常使用TTL电平,下面介绍这几个存在的差异;

  • TTL

    TTL全名是晶体管-晶体管逻辑集成电路(Transistor-Transistor Logic)

    输入高电平最小2V,输出高电平最小2.4V,典型值3.4V

    输入低电平最大0.8V,输出低电平最大0.4V,典型值0.2V

  • RS232

    RS232 逻辑1电平(MARK)=-3V~-15V逻辑0电平(SPACE)=+3~+15V

    同样的,对于传输数据0x55,即二进制的01010101,RS232和TTL的区别如下;(LSB:最低位,MSB:最高位)
    UART 串口收发模块设计及Verilog实现

  • RS485

    RS485是差分信号进行串行传输;

    逻辑1以两线间的电压差为+(2 ~ 6)V表示 逻辑 "0"以两线间的电压差为-(2 ~ 6)V表示
    在工业通信中,使用RS485比较多,因为RS485是差分信号,可以抑制共模干扰,因此在恶劣的环境中拥有很好的抗干扰性,比较稳定

1.3.3 硬件设计

UART 串口收发模块设计及Verilog实现

FPGA采用TTL电平:3.3V(1)、0V(0)。而PC采用的是负逻辑电平:-15~-5为逻辑1,+5 ~ +15为逻辑0。

因此,PC与FPGA之间通信时,需要进行电平转换。

老早以前的台式机和笔记本可都是有串口的,虽然现在很多台式机串口没有了,笔记本也没有串口了,但是串口从来没有被丢弃,只是以另外一种形式存在,这就是 USB 转串口芯片。串口只需要 2 根线就可以实现一

收一发,使用简单,可靠方便,在低速场合大量使用。

1. USB转串口电路
  1. CH340G

UART 串口收发模块设计及Verilog实现

  1. CP2104

UART 串口收发模块设计及Verilog实现

2. RS232转串口电路

UART 串口收发模块设计及Verilog实现

二、UART设计及Verilog实现

2.1 UART设计概述

本实例设计的UART特性:

  1. 并没有支持奇偶检验,故没有奇偶校验位。
  2. 并不支持数据位宽可配,数据位位宽固定为8bit。
  3. 支持输入时钟与波特率可配。

原理图如下,分两个大模块,一个==数据接收控制模块(Receive_Control)==,一个数据发送控制模块(Send_Control)

模块启动后,

  • 接收模块一直在接收数据uart_rx。每当有新数据发送过来时,将新的8位数据放置于rx_data中,接收完成信号rx_data会置高。
  • 发送模块发送数据需要发送使能tx_en有效后,才能将要发送的数据tx_data发送到uart_tx端口,发送完成后tx_finish会置高,之后可以使能tx_en发送新的数据。

UART 串口收发模块设计及Verilog实现

各模块详细设计图示
UART 串口收发模块设计及Verilog实现

端口说明:

UART 串口收发模块设计及Verilog实现

接收控制模块与发送控制模块内部都有一个波特率时钟产生模块(BuadRate_set),用于将电路输入时钟(clk)进行分频产生波特率时钟,用于接收和发送数据控制。

UART 串口收发模块设计及Verilog实现

可以看到,BuadRate_set模块有一个enable控制信号,只有当enable信号为高时,BuadRate_set模块才工作。 在发送控制模块里面,只有发送数据的时候才拉高其相应的enable;在接收控制模块里面,只有检测到有数据发送进来的时候才拉高其相应的enable。这是为了降低功耗

2.2 UART详细设计

2.2.1 UART发送模块设计

数据发送模块的时序如下所示。
UART 串口收发模块设计及Verilog实现

  • 当发送使能tx_en有效时,启动波特率时钟分频模块开始计数。状态由IDLE转为EN_TX。
  • 波特率时钟分频模块用于生成发送数据的时钟,并控制数据移位。
  • 当波特率时钟到来时将此刻要发送的数据送出。
1. 波特率时钟分频模块
`timescale 1ns / 1ps
module BuadRate_set #(
  parameter CLK_Period=50000000,//the unit is Hz
  parameter Buad_Rate=9600 //the unit is bits/s
)(
   input      clk,         //原始系统时钟
   input      rst_n,       //复位
   input      enable,      //模块使能信号 
   output     Buad_clk     //输出的分频
);

localparam DIV_PEREM=CLK_Period/Buad_Rate/2;    //计数器最大值
reg[15:0] cnt;

always @( posedge clk )
  if( !rst_n )
    cnt <= 16'b0000;
  else if( enable ) begin
    if( cnt != DIV_PEREM )
      cnt <= cnt+1'b1;	  
    else	  
      cnt <= 16'h0000;
  end
  else
    cnt <= 16'h0000;

reg DIV_clk;

always @( posedge clk )
  if( !rst_n || !enable )    //当复位或者模块不使能的时候,分频器停止。
    DIV_clk <= 1'b1;
  else if(cnt==DIV_PEREM)    //计数器满,输出时钟翻转
    DIV_clk <= ~DIV_clk;

assign Buad_clk = DIV_clk;
    
endmodule
2. 发送模块
`timescale 1ns / 1ps
module Send_Control #(
  parameter CLK_Period=50000000,//the unit is Hz
  parameter Buad_Rate=9600 //the unit is bits/s
)(
  input        clk,
  input        rst_n,
  input        tx_en,
  input [7:0]  tx_data,
  output       tx_finish,
  output       uart_tx
);
localparam IDLE=2'b00;    //0
localparam EN_TX=2'b10;   //2
localparam END_BIT=2'b11; //3
wire Buad_clk;
wire Buad_en;
BuadRate_set #(
  .CLK_Period(CLK_Period),//the unit is Hz
  .Buad_Rate (Buad_Rate) //the unit is bits/s
) BuadRate_set_inst(
   .clk     (clk     ),
   .rst_n   (rst_n   ),
   .enable  (Buad_en ),
   .Buad_clk(Buad_clk)
);

reg [9:0] data_to_send;    //发送10个数

reg [1:0] state;
reg [3:0] cnt;
//发送模块状态机
always @( posedge clk )
  if( !rst_n )
    state <= IDLE;
  else
    case(state)
    IDLE:if( tx_en )    //tx_en发送有效的下一个时钟上升沿,开始发送数据
         state <= EN_TX;
    EN_TX: if( cnt=='d10 )
         state <= IDLE;
    END_BIT: if( cnt=='d0 )
         state <= IDLE;
    default: state <= IDLE;
    endcase
//波特率时钟发生启动信号
assign Buad_en = (state == EN_TX || state == END_BIT);    
//发送计数0~9
always @( posedge Buad_clk or negedge rst_n)
  if( !rst_n )
    cnt <= 4'b000;
  else begin
    if( cnt<4'd10)
      cnt <= cnt + 1'b1;
    else 
      cnt <= 4'b0000;
  end	 
//发送数据
always @( posedge Buad_clk or negedge rst_n )
  if( !rst_n )
    data_to_send <= 10'h3ff;
  else if( cnt == 'd0 )    //发送第一个数
    data_to_send <= {1'b1,tx_data,1'b0}; 
  else    //之后,数据右移位
    data_to_send <= {1'b1,data_to_send[8:1]};

assign uart_tx = (Buad_en)?data_to_send[0]:1'b1;	
assign tx_finish = (state == END_BIT)? 1'b1:1'b0;

endmodule
3. testbench
`timescale 1ns / 1ps
module tb_send();
  reg        clk;
  reg        rst_n;
  reg        tx_en;
  reg [7:0]  tx_data;
  wire       tx_finish;
  wire       uart_tx;
  // 50MHz,9600bps 
  Send_Control my_Send_Control(clk, rst_n, tx_en, tx_data, tx_finish, uart_tx);	
  initial begin
    clk=0;rst_n=0; tx_en=0;  //复位信号不能太短。
    #100 rst_n=1;  tx_en=1;    tx_data=8'b11001100;
    # 100000000 $stop;
  end
  
  //50Mhz的时钟
  always #10 clk=~clk;
endmodule
4. 结果

UART 串口收发模块设计及Verilog实现

2.2.2 UART接收模块设计

数据接收模块的时序如下所示:

UART 串口收发模块设计及Verilog实现

  • 当检测到输入数据从高位跳转到低位时,启动波特率时钟分频模块开始计数。状态由IDLE转为GET_DATA。
  • 波特率时钟分频模块用于生成接收数据的使能信号,并控制数据移位。
  • 当波特率时钟到来时将此刻接口上的数据保存到接收数据数组rx_data_tmp中。
  • 该设计中每bit的数据都会检测8次。取平均值作为最终的检测结果。
1. 波特率时钟分频模块
// 公众号: 小鱼FPGA
// Engineer: littlefish

module BuadRate_set_multi #(
  parameter CLK_Period=50000000,//the unit is Hz
  parameter Buad_Rate=9600 //the unit is bits/s
)(
   input      clk,         //原始系统时钟
   input      rst_n,       //复位
   input      enable,      //模块使能信号 
   output   reg  Buad_en,     //输出的分频
   output   reg  Cap_en
);

localparam DIV_PEREM=CLK_Period/Buad_Rate;    //计数器最大值
localparam Cap_DIV_PEREM=DIV_PEREM/8;    //计数器最大值
reg[15:0] cnt;


//波特率分频
always @( posedge clk )
  if( !rst_n )
    cnt <= 16'b0000;
  else if( enable ) begin
    if( cnt != DIV_PEREM )
      cnt <= cnt+1'b1;	  
    else	  
      cnt <= 16'h0000;
  end
  else
    cnt <= 16'h0000;



always @( posedge clk )
  if( !rst_n || !enable )    //当复位或者模块不使能的时候,分频器停止。
    Buad_en <= 1'b0;
  else if(cnt==DIV_PEREM)    //计数器满,输出时钟翻转
    Buad_en <= 1;
  else 
    Buad_en<=0;

//采集分频
reg[15:0] cap_cnt;

always @( posedge clk )
  if( !rst_n )
    cap_cnt <= 16'b0000;
  else if( enable ) begin
    if( cap_cnt < Cap_DIV_PEREM )
      cap_cnt <= cap_cnt+1'b1;	  
    else	  
      cap_cnt <= 16'h0000;
  end
  else
      cap_cnt <= 16'h0000;

always @( posedge clk )
  if( !rst_n || !enable )    //当复位或者模块不使能的时候,分频器停止。
    Cap_en <= 1'b0;
  else if(cap_cnt==Cap_DIV_PEREM)    //计数器满,输出时钟翻转
    Cap_en <= 1;
  else 
    Cap_en<=0;
endmodule
2. 接收模块
`timescale 1ns / 1ps
module receive_control_opt #(
  parameter CLK_Period=50000000,//the unit is Hz
  parameter Buad_Rate=9600 //the unit is bits/s
)(
  input            clk,	
  input            rst_n,

  input            uart_rx,
  output wire [7:0] rx_data,
  output            rx_finish,
  output           o_valid  
);

    localparam IDLE=2'b00;
    localparam GET_DATA=2'b01;
    localparam END=2'b11;
    
    
    reg[5:0] get_start_bit;
    reg start;
    wire rx_start;
    wire Buad_en;
    wire Cap_en;
    reg [8:0] rx_data_tmp;   //8位数据位+1位停止位
    //波特率采集时钟生成
    BuadRate_set_multi #(
      .CLK_Period(CLK_Period),//the unit is Hz
      .Buad_Rate (Buad_Rate) //the unit is bits/s
    ) BuadRate_set_multi_inst(
       .clk     (clk     ),
       .rst_n   (rst_n   ),
       .enable  (rx_start ),
       .Buad_en(Buad_en),
       .Cap_en(Cap_en)
    );
    
    //启动低电平信号检测!
    always @( posedge clk )
      if( !rst_n )
        get_start_bit <= 6'b111111;
      else
        get_start_bit <= {get_start_bit[4:0],uart_rx};
    always @( posedge clk )
      if( !rst_n )
        start <= 1'b0;
      else if(state !=IDLE)                //至到状态state转为非IDLE状态时,start才转为0。
        start <= 1'b0;
      else if( get_start_bit==6'b111000 )    //有三个联系低电平0出现是,start==1。
        start <= 1'b1;
    //波特率产生模块启动信号:当未检测到起始位并且状态是IDLE空闲时,置无效。其他时刻为有效。
    assign rx_start =( ~(start==1'b0 && state==IDLE) )? 1'b1:1'b0;   
    
    reg [1:0] state;
    reg [3:0] cnt;
    //接收模块状态机
    always @( posedge clk or negedge rst_n )    //特定波特率采集时钟下
      if( !rst_n )
        state <= IDLE;
      else 
          case( state )
            IDLE: begin
                if( start )    //检测到起始低电平信号,状态转为开始接收,并开始生成检测波特率时钟
                  state <= GET_DATA;
              end
            GET_DATA: begin     //开始接收9个数据:1个起始位+8个数据位
                    if( cnt=='d9 )
                  state <= END;
            end
            END: begin     //接收停止位
                  state <= IDLE;
            end
            default: begin 
                state <= IDLE;
            end
          endcase
    reg [4:0] cap_tmp;
    reg [3:0] cap_cnt;
    //每bit数据采集7次,取7次的平均值作为该bit的数值
    always @( posedge clk or negedge rst_n ) begin
      if( !rst_n || Buad_en==1)
        cap_tmp <= 5'd15;
      else if( state == GET_DATA && Cap_en==1 ) begin
        if(uart_rx==1)
            cap_tmp<=cap_tmp+1;
        else if(uart_rx==0)
            cap_tmp<=cap_tmp-1;
      end
    end
    always @( posedge clk or negedge rst_n ) begin
      if( !rst_n )
        cap_cnt <=0;
      else if( state == GET_DATA && Cap_en==1 ) begin
        if(cap_cnt<7)
            cap_cnt<=cap_cnt+1;
        else 
            cap_cnt<=0;
      end
    end
    
    //接收9位有效数据:1个起始位+8个数据位    存放于rx_data_tmp
    always @( posedge clk or negedge rst_n ) begin
      if( !rst_n )
        rx_data_tmp <= 9'b0;
      else if( state == GET_DATA &&Buad_en==1) begin
        if(cap_tmp>'d15)
            rx_data_tmp <= {'b1,rx_data_tmp[8:1]};
        else
            rx_data_tmp <= {'b0,rx_data_tmp[8:1]};
      end  
    end
    //接收计数,接收9位有效数据:1个起始位+8个数据位,取其中的8位数据位即可。
    always @( posedge clk or negedge rst_n)  begin
      if( !rst_n || state==IDLE ||state==END )
        cnt <= 'd0;
      else if(state==GET_DATA&&Buad_en==1 )
        cnt <= cnt+1'b1;
    end
    
    assign rx_finish=(state==END);
    reg finish_d;
    always @( negedge clk or negedge rst_n )
      if( !rst_n )
        finish_d<=1'b0;
      else 
        finish_d<=rx_finish;
    
    assign o_valid = rx_finish&(~finish_d);   
    
    assign rx_data=(state==GET_DATA)?8'b0:rx_data_tmp[8:1];
        
endmodule
3. testbench
module tb_receive_opt();
  reg            clk;	
  reg            rst_n;	
  reg            uart_rx;
  	
  wire [7:0]     rx_data;	
  wire           rx_finish;	
  wire           o_valid;
  // 50MHz,9600bps 
  receive_control_opt my_Receive_Control(clk, rst_n, uart_rx, rx_data, rx_finish, o_valid);	
  initial begin
    clk=0;rst_n=0;          //复位信号不能太短。
    #15 rst_n=1;uart_rx=1;
    //1位起始位
    #104166 uart_rx=0;
    //8位数据:先发低位
    #104166 uart_rx=1;
    #104166 uart_rx=0;
    #104166 uart_rx=1;
    #104166 uart_rx=0;
    #104166 uart_rx=1;
    #104166 uart_rx=0;
    #104166 uart_rx=1;
    #104166 uart_rx=0;
    //1位停止位
    #104166 uart_rx=1; 
    #104166 uart_rx=1;
    #104166 uart_rx=1;
    #104166 uart_rx=1;
    #104166 uart_rx=1;
  end
  
  //50Mhz的时钟
  always #10 clk=~clk;
endmodule
4. 结果

UART 串口收发模块设计及Verilog实现文章来源地址https://www.toymoban.com/news/detail-495477.html

到了这里,关于UART 串口收发模块设计及Verilog实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32+UART串口+DMA收发

    目录 1、cubemax端配置 1.1 初始化配置 1.2 GPIO配置  1.3 UART配置 1.3.1 串口基础配置 1.3.2 DMA配置 2、keil端代码设计 2.1 初始化配置 2.2 DMA接收初始化配置 2.3 DMA发送配置  2.4 接收回调函数设置 2.5 回调函数内容代码编写 2.5.1 接收回调函数 2.5.2 发送回调函数 2.6 回调函数内容代码优化

    2024年02月07日
    浏览(32)
  • FPGA(Verilog)实现uart传输协议传输数据(含仿真)

    目录 实现功能: 1.接收uart串行数据,输出并行数据(1byte)。 2.输入并行数据(1byte),输出uart串行数据。 3.完成uart传输的1次环回。 uart协议的1帧数据传输 模块封装-port设置 Verilog代码实现 1.uart接收模块:接收串行数据,输出并行数据和其有效标志。 仿真结果: 2.uart发送模块:接收

    2024年04月16日
    浏览(34)
  • Verilog(1)UART串口通信

    第一部分为uart串口通信的接收部分,用pc端虚拟串口来对其发送数据。 第三部分为uart串口通信的发送部分,用此部分对pc端虚拟串口发送数据。 第二部分loop,处理数据,形成回环,使发送部分有数据来源,以此来保证实验的完成。 串口接收 :  输入: sys_clk、sys_rst_n、u

    2024年02月03日
    浏览(70)
  • FPGA协议篇:UART通信及Verilog最易懂实现方式/通用于任何工程/带握手信号 ----UART_TX

            UART(Universal Asynchronous Receiver/Transmitter)是一种通用的 异步收发传输协议 ,用于在计算机系统和外部设备之间进行串行数据传输。UART 协议定义了数据的传输格式和通信规则,使得不同设备之间能够进行可靠的数据交换。 首先先把设计代码放到这里: UART_TX完整代

    2024年03月27日
    浏览(40)
  • FPGA用verilog HDL实现串口通讯协议

    串口通信是一种通过串行传输数据的通信方式。它使用单个数据线将数据位逐个传输,而不是同时传输多个数据位。串口通信常用于连接计算机与外部设备,如打印机、调制解调器、传感器等。 串口通信一般使用的是异步传输方式,即发送方和接收方的时钟不同步。数据传输

    2024年02月05日
    浏览(46)
  • FPGA纯verilog实现UDP协议栈,sgmii接口SFP光口收发,提供工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但中间的FIFO或者RAM等调用了IP,或者不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的

    2024年02月16日
    浏览(33)
  • UART串口通信协议

    串行通信分为两种方式: 同步串行通信 和 异步串行通信 。 同步串行通信需要通信双方在同一时钟的控制下,同步传输数据。 异步串行通信是指通信双方使用各自的时钟控制数据的发送和接收过程。 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART)是一种 全双

    2024年02月03日
    浏览(29)
  • FPGA实现AD9708和AD9280波形收发输出HDMI模拟示波器,串口协议帧控制显示,提供工程源码和技术支持

    AD9708 很简单,8 位分辨率,125MSPS 采样率,输入参考电压3~5V,内置 1.2V 参考电压,8bit数字信号输入,差分电流输出;芯片操作不需要软件配置,给个时钟信号就工作,简单得很,根据官方手册,内部结构如下: SLEEP引脚提供芯片休眠功能,当不需要使用该芯片时可拉高SLEEP以

    2024年02月02日
    浏览(41)
  • 基于FPGA的通用异步收发传输器(UART)设计

    基本目的:   (1)了解UART通讯原理,包括数据传输格式、电气特性等; (2)研究Basys3开发板与PC之间通讯电平规格的转换; (3)设计并实现UART的发送(TX)功能或接收(RX)功能。 高级任务(可选):可调。 (4)设计并实现UART的发送(TX)功能和接收(RX)功能,构建回

    2024年02月16日
    浏览(35)
  • 【FPGA + 串口】功能完备的串口测试模块,三种模式:自发自收、交叉收发、内源

    【FPGA + 串口】功能完备的串口测试模块,三种模式:自发自收、交叉收发、内源 将 mode设置为0,是自发自收; 将 mode设置为1,是交叉收发; 将 mode设置为2,是内源;外部串口直接看数据即可; 通过三种模式的测量,可以精确的测量串口是否通,出故障,也可以判断出 是

    2024年02月15日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包