FPGA 串口通信(uart)初探篇(含源代码)

这篇具有很好参考价值的文章主要介绍了FPGA 串口通信(uart)初探篇(含源代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、UART

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

而编著的。

FPGA是一种可编程的逻辑器件,用于各种数字电路设计与实现,是一种可重复利用的芯片盒。今天所介绍的是利用赛灵思xc7a35tftg256-1系列的FPGA实现串口通信(UART)。

一个状态机,我们有发送模块(uart_tx)和接收模块((uart_tx)。模块首先得有一个时钟信号CLK,复位信号RESET.

波特率解释:

        串口协议中baud_rate波特率是很重要的知识点,字面意思就是一秒钟传输的码元(即一个0-1状态)的个数,就是指的是一秒钟传输的二进制位数,常见单位是bit/s和bps两种,常见的串口速度有115200bps(RS232串口)和9600bps and so on,

波特率和字节转换:

        1GB=1024MB   1MB=1024KB   1KB=1024B字节  ,倘若我们串口数据位每秒钟512字节,串口的波特率就是115200位/秒   (没搞懂换算?)

如果我们校验位置零,则位/10=字节 ,如波特率115200,即是115200(位/秒)=11520(b/s) ;除以1024 就可以从位换算到KB:波特率115200=115200((位/秒))=11.25KB/S

今天我们要在FPGA上实现异步串口通信,假设我们FPGA的clk时钟是50Mhz的系统时钟,波特率是9600bps,那么传输一个bit需要的时钟周期个数是50_000_000/9600个个数。得到这个个数,再乘以周期时间,就可以得到这个1bit所需要的时间。

状态机工作原理解释:

1.串口通信的信号线只需要两条线就可以完成。tx和rx, tx是状态机信号发送端,rx是状态机的信号接收端。

2.起始位STATE_START,数据线由高变低,低有效触发,即0开始,数据开始传输。

3.数据位,起始位低有效之后,数据位开始传输,如下图是8为数据,从左向右开始传输低位向着高位前进。

4.校验位PARITY,我们可以将校验位当成一个特殊的空位。通常使用的是奇偶校验位,通常在代码中有说明是否有校验, PARITY_ON=0,   //校验位,1为有校验位,0为无校验位,缺省为0。(即在串口通信中,校验位通常不适用)

5.停止位end,高有效=1,它表是一个个字节传输的结束

6.空闲位,是持续的高有效,由于当start=0低电平以后开始数据传输,所以高有效就能够使得状态机处于空闲状态。

7.帧:我们将一个个字节传输从起始位到停止位经历的全部时间称之为一帧。

fpga uart,fpga开发,信息与通信

状态机模型解释:

        如下图,我们定义了一个state状态机,用于控制串口通信的不同状态。我们还定义了一个bit_counter计数器用于计算每个位的延迟时间,在串口通信实例中,假设每个位延迟时间为bit_delay。然后定义一个数据寄存器serial_data,用于存储接收到的数据,开始时置位为0

在状态机的always块中,我们根据不同的状态开始发送以及接收。在空闲状态IDLE下,如果检测到起始位,则将状态切换到‘START_BIT’,同时重置计数器和数据寄存器。

在‘start_bit’状态下,通过计数器进行延迟,等待计数器进行延迟,等待起始位结束,然后将状态位切换到data_bits

在‘data_bits’状态下,通过计数器位逐位接收数据,并将存储在数据寄存器‘serial_data’中。当接收完所有数据后,应该切换到parity_bit位

然后根据parity_bit数据校验位的是否需要,进行逻辑处理

在stop位置等待结束后,切换☞IDLE空闲状态,并将发送状态的‘uart_tx’设置为停止位。

fpga uart,fpga开发,信息与通信

下列给出具体实现代码:

发送端uart_tx实现原理:发送思路原理:我们可以通过定义一个计数器,来记录每次发送所需要的的时间,然后用一个状态机来记录发送的状态。

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 03/10/2024 08:46:28 PM
// Design Name: 
// Module Name: uart_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_tx
#(                                         //搜素一下 这里为什么要加井号才能成功
parameter CLK_FRE=50,   //默认时钟频率为50Mhz
parameter DATA_WIDTH=8,   //有效数据位,缺省为8位
parameter PARITY_TYPE=0,   //校验类型,1为奇校验,0为偶校验,缺省为偶校验
parameter PARITY_ON=0,   //校验位,1为有校验位,0为无校验位,缺省为0
parameter BAUD_RATE=9600   //波特率,缺省为9600
    )
    (
  input i_clk_sys,//系统时钟
  input i_rst_n,//全局异步复位
  input[DATA_WIDTH-1:0] i_data_tx,//传输数据输入
  input   i_data_valid,//传输数据有效
  output reg o_uart_tx//UART输出
    );
    
 //状态机定义   
reg[2:0] r_current_state;//当前状态
reg[2:0] r_next_state;//次态
localparam STATE_IDLE=3'b000; //空闲状态
localparam STATE_START=3'b001;  //开始状态
localparam STATE_DATA=3'b011;  //数据发送状态
localparam STATE_PARITY=3'b100; //数据校验计算和发送
localparam STATE_END=3'b101; //结束状态

localparam CYCLE=CLK_FRE*1000000/BAUD_RATE;   //波特率计数周期

reg baud_valid;//波特计数有效位
reg[15:0] baud_cnt;  //波特率计数器 
reg baud_pulse;  //波特率采样脉冲

reg[3:0] r_tx_cnt; //接收数据位计数

//波特率计数器
always @(posedge i_clk_sys or negedge i_rst_n )
    begin
        if(!i_rst_n)  //如果是低电平 则成立
         baud_cnt<=16'h0000;
        else if(!baud_valid)
         baud_cnt<=16'h0000;
         else if(baud_cnt==CYCLE-1)
          baud_cnt<=16'h0000; 
         else
            baud_cnt=baud_cnt+1;           
    end
    
//波特采样脉冲
always @(posedge i_clk_sys or negedge i_rst_n )
begin
    if(!i_rst_n)
        baud_pulse<=1'b0;
     else if(baud_cnt==CYCLE/2-1)
        baud_pulse<=1'b1;
     else if(baud_valid&&baud_cnt==16'h0000)
       r_current_state<= r_next_state;
end


//状态机的次态定义
always @(*)
begin
    case(r_current_state)
     STATE_IDLE:  r_next_state<= STATE_START;
     STATE_START: r_next_state<=STATE_DATA;
     STATE_DATA:
     if(r_tx_cnt==DATA_WIDTH)  
     begin
        if(PARITY_ON==0)
          r_next_state<=STATE_END;
        else
          r_next_state<=STATE_PARITY;    
     end
     else
     begin
        r_next_state<=STATE_DATA;
     end
     STATE_PARITY:r_next_state<=STATE_END;
     STATE_END:r_next_state<=STATE_IDLE;
     default:                             ;
     endcase
end

reg [DATA_WIDTH-1:0] r_data_tx;
reg r_parity_check;

//状态机的输出逻辑
//状态机的输出逻辑根据当前状态执行相应的操作,如发送开始位、数据位、校验位和结束位
always @(posedge i_clk_sys or negedge i_rst_n )
    begin
        if(!i_rst_n)
        begin
          baud_valid<=1'b0;
          r_data_tx<='d0;
          o_uart_tx<=1'b1;
          r_tx_cnt<=4'd0;
          r_parity_check<=1'b0;         
        end
        else
            case(r_current_state)
            STATE_IDLE:begin
                o_uart_tx<=1'b1;
               r_tx_cnt<=4'd0;
                r_parity_check<=4'b0; 
                if(i_data_valid)
                begin
                    baud_valid<=1'b1;
                    r_data_tx<= i_data_tx;
                end
                
            end
     STATE_START:begin
     if(baud_pulse)
         o_uart_tx<=1'b0;
     end 
     STATE_DATA:begin
        if(baud_pulse)
        begin
            r_tx_cnt<=r_tx_cnt+1'b1;  //这行代码将r_tx_cnt(数据发送计数器)的值增加1
            o_uart_tx<= r_data_tx[0];//这行代码将r_data_tx寄存器中的最低位(第0位)输出到o_uart_tx(UART发送输出)。这意味着数据的最低位被发送出去。
            r_parity_check<=r_parity_check+r_data_tx[0];
            r_data_tx<={1'b0,r_data_tx[DATA_WIDTH-1:1]};
        end
     end
     /*
     总结来说,当状态机处于STATE_DATA状态且baud_pulse为高电平时,模块会发送当前数据位,更新发送计数器,计算校验位,并准备下一个数据位的发送。\
     这个过程会重复进行,直到所有数据位都被发送完毕。
     */
     STATE_PARITY:begin
     if(baud_pulse)  //判断是否具有高电平脉冲过来
     begin
        if(PARITY_TYPE == 1)
           o_uart_tx<= r_parity_check;
        else
            o_uart_tx<= r_parity_check+1'b1; 
     end
     end   
      STATE_END:begin
      if(baud_pulse)
      begin
       o_uart_tx<= 1'b1;
      baud_valid<=1'b0; 
      end
      end
      default:;
      endcase  
    end

endmodule

下面是数据接收端的verilog代码实现,在串口通信时,一定要实现两边的波特率一致,这样才能够同步接收和发送,本次串口通信设置是baud=9600,表是1秒钟可以发送9600个数据位。

(程序中添加了奇偶校验,但是校验不会进行,校验原则:

  • 奇校验(Odd Parity):在数据位中加上一个额外的校验位,使得整个传输的数据(包括校验位)中1的总数为奇数。如果数据位中1的数量已经是奇数,则校验位设为0,以保持总数为奇数;如果是偶数,则校验位设为1。接收端检查接收到的数据中1的总数是否为奇数,如果是,则认为数据传输正确。
  • 偶校验(Even Parity):与奇校验相反,偶校验要求加上的校验位保证数据中1的总数为偶数。如果数据位中1的数量是偶数,则校验位设为0;如果是奇数,则校验位设为1。接收端同样通过检查1的总数是否为偶数来判断数据是否正确。

接收端rx代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 03/13/2024 08:22:34 AM
// Design Name: 
// Module Name: uart_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_rx
#(
    parameter CLK_FRE=50,//时钟频率,默认为50Mhz
    parameter DATA_WIDTH=8,//有效数据位,缺省为8位
    parameter PARITY_ON=0,//校验位,1为有校验位,0为无校验位,缺省为0
    parameter PARITY_TYPE=0,//校验类型,1为奇校验,0为偶校验,缺省为偶校验
    parameter BAUD_RATE=9600//波特率,缺省为9600,每秒传输的位数
)//输入输出端口设置
    (input i_clk_sys,//系统时钟脉冲
    input i_rst_n,//全局异步复位,低电平有效
    input i_uart_rx,//uart输入
    output reg[DATA_WIDTH-1:0] o_uart_rx,//uart接收数据
    output reg o_ld_parity,//校验位校验LED,高电平 位为校验正确
    output reg o_rx_done,  //数据接收完成标志
    output reg o_uart_data
    );
  /*
  UART是异步输入,最好是同步到FPGA内部的时钟域
  可以省略,在异步时钟电路中,保持时钟同步是一个好习惯
  */  
  reg sync_uart_rx; //同步接受数据端,用于同步输入的UART信号,以避免时钟域之间的问题。
  always@(posedge i_clk_sys or negedge i_rst_n ) 
  begin
    if(!i_rst_n)
        sync_uart_rx<=1'b1;
    else
        sync_uart_rx<=i_uart_rx;
  end
  
  /*
   连续采样五个接收路电平来判断rx是否有信号传来
   用五个采样信号来作为判断标准可以有效排除毛刺噪声带来的误判
   */  
   
   //接受信号检测 
   reg[4:0] r_flag_rcv_start;
   wire w_rcv_start;
   always@(posedge i_clk_sys or negedge i_rst_n)
   begin
       if(!i_rst_n)
           r_flag_rcv_start<=5'b11111;
       else
            r_flag_rcv_start<={r_flag_rcv_start[3:0],sync_uart_rx};
     end
  //状态机定义
  reg[2:0]r_current_state; //当前状态
  reg[2:0]r_next_state; //次态
  
  localparam STATE_IDLE=3'b000;  //空闲状态  
  localparam STATE_START=3'b001;  //开始状态
  localparam STATE_DATA=3'b011;  //数据接收状态
  localparam STATE_PARITY=3'b000;  //空闲状态
  localparam STATE_END=3'b101;  //结束状态
  
  localparam CYCLE=CLK_FRE*1000000/BAUD_RATE;  //ji计算波特率周期 即单个时长
  reg baud_valid; //波特率有效位
  reg[15:0]baud_cnt;//波特率计数器
  reg baud_pulse;//波特率采样脉冲
  
  reg[3:0] r_rcv_cnt;//接收数据位计数
  
  //波特率计数器
  always @(posedge i_clk_sys or negedge i_rst_n )
  begin
    if(!i_rst_n)
        baud_cnt<=16'h0000;
    else if (!baud_valid)
        baud_cnt<=16'h0000;
    else if(baud_cnt==CYCLE-1)
         baud_cnt<=16'h0000;
    else
        baud_cnt<=baud_cnt+1'b1;
  end
  
  //波特采样脉冲
  always @(posedge i_clk_sys or negedge i_rst_n )
    begin
      if(!i_rst_n)
          baud_pulse<=1'b0;     
      else if(baud_cnt==CYCLE/2-1)
           baud_pulse<=1'b1;
      else
         baud_pulse<=1'b1;
    end
  
  //状态机状态变化定义
  always @(posedge i_clk_sys or negedge i_rst_n )
  begin
    if(!i_rst_n)  //低电平输入
        r_current_state<=STATE_IDLE;
    else if(!baud_valid)
        r_current_state<=STATE_IDLE;
     else if(baud_valid&&baud_cnt==16'h0000)
        r_current_state<=r_next_state;
  end
  
  //状态机次态定义
  always @(*)   //。在这个语句中,@(*) 表示该 always 块对敏感列表中的所有信号都敏感。换句话说,当敏感列表中的任何一个信号发生变化时,always 块都会被执行。
  begin
    case(r_current_state)
      STATE_IDLE :r_next_state<=STATE_START;
      STATE_START:r_next_state<=STATE_DATA;
      STATE_DATA:
        if(r_rcv_cnt==DATA_WIDTH)
        begin
            if(PARITY_ON==0)
                r_next_state<=STATE_END;
             else
                 r_next_state<=STATE_PARITY;//校验位开启时进                   
        end
        else
        begin
            r_next_state<=STATE_DATA;
        end
        STATE_PARITY:r_next_state<=STATE_END;
        STATE_END:r_next_state<=STATE_IDLE;  //STATE_IDLE 即是空闲位
        default:;
    endcase
  end
  
  reg[DATA_WIDTH-1:0] r_data_rcv;  //声明一个8位寄存器
  reg r_parity_check;  //奇偶校验位寄存器 存储结果
  
  //状态机输出逻辑
  always @(posedge i_clk_sys or negedge i_rst_n)
  begin
    if(!i_rst_n)
        begin
            baud_valid<=1'b0;
            r_data_rcv<='d0;
            r_rcv_cnt<=4'd0;
            r_parity_check<=1'b0;
            o_uart_data<='d0;
            baud_pulse<=1'b0;
            o_rx_done<=1'b0;            
        end
      else
        case(r_current_state)
                    STATE_IDLE:begin
                    //闲置状态下 对寄存器进行复位
                    r_rcv_cnt<=4'd0;
                    r_data_rcv<='d0;
                    r_parity_check<=1'b0;
                    o_rx_done<=1'b0; 
                   
 //连续检测到低电平,则认为UART传输过来数据,拉高baud_valid。低电平作为数据开始位
                   if(r_flag_rcv_start==5'b00000)
                       baud_valid<=1'b1;
                       end
                STATE_START:begin
                    if(baud_pulse && sync_uart_rx) //波特率采样脉冲到来时
                        baud_valid<=1'b1;
                end  
                STATE_DATA:begin
                if(baud_pulse)
                    begin
                       r_data_rcv <={sync_uart_rx,r_data_rcv[DATA_WIDTH-1:1]};//数据移位。将同步串口接收信号(sync_uart_rx)和当前接收到的数据(r_data_rcv)进行移位操作,并将结果赋值给接收数据寄存器(r_data_rcv)。
                       r_rcv_cnt<=r_rcv_cnt+1'b1;//数据位计数
                       r_parity_check<=r_parity_check+sync_uart_rx;//校验位做校验                   
                    end
                end 
                STATE_PARITY:begin
                if(baud_pulse) //如果是高电平
                begin
                    //校验检测,正确则0_ld_parity拉高,则可输出给led检测,如果闪烁则表示有错误数据
                    if(r_parity_check+sync_uart_rx==PARITY_TYPE)
                        o_ld_parity<=1'b1;
                    else
                        o_ld_parity<=1'b0;
                end
                else
                    o_ld_parity<=o_ld_parity;              
                end  
                  STATE_END:begin
                    if(baud_pulse)
                        begin
                        //没有校验位或校验位正确时才输出数据,否则直接丢弃数据
                        if(PARITY_ON==0||o_ld_parity)
                        begin
                           o_uart_data<= r_data_rcv;
                           o_rx_done<=1'b1; 
                        end
                        end
                      else
                        begin
                            o_rx_done<=1'b0; 
                        end
                      if(baud_cnt==16'h0000)
                        baud_valid<=1'b0;
                  end     
  default:;
  endcase                 
  end
  
endmodule

如上串口通信的发送端程序和接收端程序均已完美。但是还需要做一个顶层程序来调动发送端和接收端。即是给uart_tx发送端和uart_rx 接收端初始化相关寄存器变量。整个模块的功能用来接收来自UART的输入信号,并将其传输给UART模块输出。同时使用校验位检验LED来指示检验是否正确。

如下代码:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 03/13/2024 11:31:45 AM
// Design Name: 
// Module Name: uart_loop
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_loop(
    input i_clk_sys,
    input i_rst_n,
    input i_uart_rx,
    output o_uart_tx,
    output o_ld_parity
    );
    
    localparam DATA_WIDTH = 8;
    localparam BAUD_RATE = 9600;
    localparam PARITY_ON = 1;
    localparam PARITY_TYPE = 1;
    
    wire w_rx_done;
    wire[DATA_WIDTH-1 : 0] w_data;
    
    
    uart_rx 
    #(
            .CLK_FRE(50),         //时钟频率,默认时钟频率为50MHz
            .DATA_WIDTH(DATA_WIDTH),       //有效数据位,缺省为8位
            .PARITY_ON(PARITY_ON),        //校验位,1为有校验位,0为无校验位,缺省为0
            .PARITY_TYPE(PARITY_TYPE),      //校验类型,1为奇校验,0为偶校验,缺省为偶校验
            .BAUD_RATE(BAUD_RATE)      //波特率,缺省为9600
    ) u_uart_rx
    (
        .i_clk_sys(i_clk_sys),      //系统时钟
        .i_rst_n(i_rst_n),        //全局异步复位,低电平有效
        .i_uart_rx(i_uart_rx),      //UART输入
        .o_uart_data(w_data),    //UART接收数据
        .o_ld_parity(o_ld_parity),    //校验位检验LED,高电平位为校验正确
        .o_rx_done(w_rx_done)       //UART数据接收完成标志
    );
    
    uart_tx
    #(
        .CLK_FRE(50),         //时钟频率,默认时钟频率为50MHz
        .DATA_WIDTH(DATA_WIDTH),       //有效数据位,缺省为8位
        .PARITY_ON(PARITY_ON),        //校验位,1为有校验位,0为无校验位,缺省为0
        .PARITY_TYPE(PARITY_TYPE),      //校验类型,1为奇校验,0为偶校验,缺省为偶校验
        .BAUD_RATE(BAUD_RATE)      //波特率,缺省为9600
    ) u_uart_tx
    (   .i_clk_sys(i_clk_sys),      //系统时钟
        .i_rst_n(i_rst_n),        //全局异步复位
        .i_data_tx(w_data),      //传输数据输入
        .i_data_valid(w_rx_done),   //传输数据有效
        .o_uart_tx(o_uart_tx)       //UART输出
        );
    
endmodule

下面是电路仿真实现:

该模块的输入包括:

  • i_clk_sys:系统时钟信号。
  • i_rst_n:全局异步复位信号,低电平有效。
  • i_uart_rx:UART输入信号。

该模块的输出包括:

  • o_uart_tx:UART输出信号。
  • o_ld_parity:校验位检验LED,高电平表示校验正确

fpga uart,fpga开发,信息与通信

下面在波形仿真模块,先定义一些寄存器变量,和线型变量,然后分别调用发送模块和数据接收模块。并且初始化全局复位和时钟信号。

`timescale 1ns / 1ps
//
// Company: 南京信息工程大学
// Engineer: 王彪
// 
// Create Date: 03/13/2024 07:43:29 PM
// Design Name: 同步串口通信
// Module Name: uart_loop_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_loop_tb(
    );
    
    reg clk_sys;
    reg rst_n;
    reg uart_in;
    wire uart_out;
    wire parity;
    
    uart_loop u_uart_loop(
        .i_clk_sys(clk_sys),
        .i_rst_n(rst_n),
        .i_uart_rx(uart_in),
        .o_uart_tx(uart_out),
        .o_ld_parity(parity)
        );
        
        
    initial begin
        clk_sys = 1'b0;
        rst_n = 1'b0;
        uart_in = 1'b1;
    end
    
    always #10 clk_sys = ~clk_sys;
    
    localparam ELEMENT_TIME = 104160;
    reg [7:0] DATA = 8'hAC;
    
    initial begin
        #100 rst_n = 1'b1;
        #20000;
        //  #并且可以使用#来进行时间等待。
        uart_in = 1'b0;//uart_in = 1'b0; 将UART输入信号uart_in设置为低电平,模拟开始位的发送。
        #ELEMENT_TIME
        uart_in = DATA[0];
        #ELEMENT_TIME
        uart_in = DATA[1];
        #ELEMENT_TIME
        uart_in = DATA[2];
        #ELEMENT_TIME
        uart_in = DATA[3];
        #ELEMENT_TIME
        uart_in = DATA[4];
        #ELEMENT_TIME
        uart_in = DATA[5];
        #ELEMENT_TIME
        uart_in = DATA[6];
        #ELEMENT_TIME
        uart_in = DATA[7];
        #ELEMENT_TIME
        uart_in = 1'b1;
        #ELEMENT_TIME
        uart_in = 1'b1;
        
    end
//总结来说,这个测试模块通过模拟发送一个包含8位数据的UART数据帧,包括开始位、数据位、校验位(如果有的话)和停止位。
//ELEMENT_TIME参数用于控制每个位的时间间隔,以确保数据按照正确的时序发送。这个测试模块可以用来检查UART接收模块是否能够正确地接收和处理发送的数据。
endmodule

下面进行全局行为仿真,发送的数8为16进制ac

fpga uart,fpga开发,信息与通信文章来源地址https://www.toymoban.com/news/detail-851070.html

到了这里,关于FPGA 串口通信(uart)初探篇(含源代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • (五)零基础学懂FPGA中的串口通信(UART)

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

    2024年02月04日
    浏览(51)
  • 【27个FPGA实例源代码】助力你成为FPGA开发高手(可下载)

    FPGA(可编程门阵列)技术在数字电路设计和嵌入式系统开发中有着广泛的应用。 对于FPGA工程师来说,拥有丰富的FPGA实例源代码资料是非常重要的,因为这可以帮助工程师更好地理解FPGA编程的实际应用、解决问题、进行优化等。 为了帮助FPGA工程师更好地理解和应用这一技术

    2024年02月03日
    浏览(44)
  • 【毕业设计】42基于FPGA的LCD1602控制器设计仿真与实现(原理图+仿真+源代码+论文)

    包含此题目毕业设计全套资料: 原理图工程文件 仿真工程文件 源代码 仿真截图 低重复率论文,字数:19964 基于altera 公司cyclone4代芯片的fpga以及quartusII软件设计一款屏幕显示系统,显示装置可以选择点阵或字符型液晶,最终实现滚动显示、可控制滚动方向、暂停、清屏等功能

    2024年02月04日
    浏览(94)
  • FPGA实现串口通信(RS232)含代码

    带有CH340的FPAG开发板 该模块的功能是接收通过 PC 机上的串口调试助手发送的固定波特率的数据,串口接收模块按照串口的协议准确接收串行数据,解析提取有用数据后需将其转化为并行数据;简单的说,接收模块的功能就是 解析+串转并 ; 具体实现步骤如下: 1、算出波特

    2024年02月02日
    浏览(56)
  • 【技术分享】Altera FPGA EP4CGX22CF19C8详解:原理图、PCB图纸、源代码及PCIe二次开发驱动和代码全解析

    altera fpga ep4cgx22cf19c8,有原理图,PCB图纸,源代码,PCIe二次开发驱动和代码等。 ID:313000 681436451614 小明子555 《基于Altera FPGA EP4CGX22CF19C8的硬件开发与PCIe驱动开发》 摘要:本文基于Altera FPGA EP4CGX22CF19C8芯片,探讨了硬件开发和PCIe驱动开发的相关技术。首先介绍了EP4CGX22CF19C8芯片

    2024年04月25日
    浏览(35)
  • 【FPGA协议篇】UART通信及其verilog实现(代码采用传参实现模块通用性,适用于快速开发)

    ​ 即通用异步收发器(Universal Asynchronous Receiver/Transmitter),是一种 串行、异步、全双工 的通信协议。特点是通信线路简单,适用于远距离通信,但传输速度慢。 数据传输速率:波特率(单位:baud,波特) 常见波特率有:1200、2400、4800、19200、38400、57600等,最常用的是9600和11520

    2024年02月05日
    浏览(50)
  • FPGA实战 -- UART --- 实现串口回环(加FIFO)

    FPGA基础 – 通信协议 — 了解UART以及电脑串口环境准备 咱们上一文章学过了UART的基础,已经初步了解了协议的基础知识和时序要求,接下来就是将学到的写出东西来,本文通过上位机的串口助手发送数据,FIFO将数据在RX和TX之间进行传递,并且传递回上位机的串口助手,修改

    2024年02月20日
    浏览(43)
  • FPGA开发基础篇之一(接口篇)UART串口

    写在前面 从本文开始,将连载fpga开发基础知识,将这几年浅显的fpga开发经验整理出来,一是梳理一下这几年给别人做fpga的经历,同时也是分享给大家,也希望大牛批评指正。 一、UART串口通信基本概念 串口通信是非常基本且应用十分广泛的低速通信接口,无论是在dsp、单片

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

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

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

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

    2024年02月13日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包