FPGA—串口RS232(附实现代码)

2023-11-09

目录

1. 理论

1.1 串口简介

1.2 RS232信号线

1.3 RS232通信协议简介

2. 实操

2.1 硬件资源

2.2  顶层模块

2.2.1 模块说明

2.2.2 RTL 代码

2.2.3  仿真验证

2.3 串口数据接收模块

2.3.1 模块说明

2.3.2 波形设计

2.3.3 RTL代码

2.3.4 仿真验证

2.4 串口数据发送模块

2.4.1 模块说明

 2.4.2 波形设计

​编辑2.4.3 RTL代码

2.4.4 仿真部分

2.5 上板测试

3. 总结


1. 理论

       通用异步收发传输器( Universal Asynchronous Receiver/Transmitter) ,简称UART。 UART 是一种通用的数据通信协议,也是异步串行通信口(串口)的总称,它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。 它包括了RS232、 RS499、 RS423、 RS422 和 RS485 等接口标准规范和总线标准规范。

1.1 串口简介

       串口作为常用的三大低速总线(UART、 SPI、 IIC)之一,在通信接口和调试时占有重要地位。但 UART 和 SPI、 IIC 不同的是,它是异步通信接口,异步通信中的接收方并不知道数据什么时候会到达,双方收发端有各自的时钟。注意在数据传输过程中是不需要时钟的,发送方发送的时间间隔可以不均匀,接受方是在数据的起始位和停止位的帮助下实现信息同步的。而 SPI、 IIC 是同步通信接口,同步通信中双方使用频率一致的时钟,在数据传输过程中时钟伴随着数据一起传输,发送方和接收方使用的时钟都是由主机提供的。
         UART 通信只有两根信号线,一根是发送数据端口线叫 tx(Transmitter),一根是接收数据端口线叫 rx(Receiver),如下图所示。对于 PC 来说它的 tx 要和对于 FPGA 来说的 rx 连接,同样 PC 的 rx 要和 FPGA 的 tx 连接。UART 可以实现全双工(可以同时进行发送数据和接收数据)。

串口的优点:

1.很多传感器芯片或 CPU 都带有串口功能,进行串口调试方便。

2.串口数据线两根使用简单。

3.在较为复杂的高速数据接口和数据链路集合的系统中往往联合调试比较困难,可以先使用串口将数据链路部分验证后,再把串口换成高速数据接口。

缺点:只能短距离传输,传输速率相对较慢。

1.2 RS232信号线

信号线的连接方式: 有以下两种   

       (1) 接口为 DB9 接口的串口线

       准备一根串口线连接在旧式的台式计算机中一般会有 RS-232 标准的 COM 口(也称 DB9 接口)和FPGA的公头接口上,如下图。

       由上图可知 COM 口有许多信号线,但一般只使用RXD、 TXD 以及 GND 三条信号线传输数据信号。

      (2) USB接口的串口线,连接FPGA与PC的两端。

1.3 RS232通信协议简介

        RS232 是 UART 的一种,没有时钟线,只有两根数据线, rx 和 tx,这两根线都为1bit 位宽(一位二进制数)。由于FPGA内部接收模块与发送模块是并行传输的,所以要模块要分别经行串转并,并转串的处理。

       串口数据的发送与接收是基于帧结构的,即一帧一帧的发送与接收数据。一帧数据的组成为起始位(固定为 0)+  有效数据( 8bit )+ 停止位(固定为 1),即最基本的帧结构有10bit(不包括校验等)。在不发送或者不接收数据的情况下, rx 和 tx 处于空闲状态,此时 rx 和 tx 线都保持高电平。下面是一个最基本的 RS232 帧结构示意图

       波特率:在信息传输通道中,携带数据信息的信号单元叫码元(串口是 1bit 进行传的,所以其码元就代表一个二进制数),每秒时间内传送二进制数据的位数简称波特率, 常用符号“Baud”表示,其单位为“波特每秒(Bps)”。串口常见的波特率有 4800、 9600、 115200 等,这里选用 9600 的波特率。
         比特率:比特率表示有效数据的传输速率每秒钟通信信道传输的信息量称为位传输速率,简称比特率,其单位为“每秒比特数(bps)”。比特率可由波特率计算得出,公式为:比特率=波特率 * 单个调制状态对应的二进制位数。 9600 的波特率,其串口的比特率为: 9600Bps *1bit= 9600bps。       

       假设数据以一帧10bit进行传输,那么码元为10个二进制数(有效位8位)。每秒传输65帧数据,故Baud = 65 x 10 = 650 Bps, 波特率 = 650 x (4/5)= 520bps。注意区别传输是一帧还是1bit(串行或并行)

         在9600Bps下,计算传输1bit数据需要花多少个时钟周期?每秒传输9600个码元数,即传1位数据需要1/9600秒 。在50Mhz的系统时钟下,一个时钟脉冲为20ns,需要花  (1s * 10^9)ns /
9600) / 20ns ≈ 5208 个系统时钟周期

2. 实操

       实验目标:PC 机的串口调试助手发送一串数据,经过 FPGA 后再传回到 PC 机的串口调试助手中显示。

2.1 硬件资源

       由于RS-232电平标准的信号不能直接被控制器直接识别,所以信号会经过一个"电平转换芯片" (MA3232 芯片)转换成控制器能识别的"TTL校准"的电平信号才能实现通讯。

 结构示意图:

RS232 收发器电路:

        为了方便使用,开发板中还搭载了 USB 转串口的芯片 CH340,供 USB 线进行串口调试。

2.2  顶层模块

2.2.1 模块说明

       模块功能是完成串口数据接收模块与发送模块的各信号之间的连接。

      loopback 的数据传输的详细过程为: PC 机的串口调试助手发送一帧串行数据,给 rs232 模块的 rx 端,uart_rx 模块负责解析出一帧数据中的有用数据,并将其转化为 8bit 并行数据 po_data。 8bit 并行数据 po_data 和数据有效标志信号 po_flag 通过 FPGA 的内部连线直接传输给 uart_tx 模块的 8bit 数据输入端 pi_data 和数据有效标志信号输入端 pi_flag, uart_tx 模块再将接收到的并行数据转为串行数据传回到 PC 机的串口调试助手中打印显示。实现了发送什么就接收什么,如果发送和接收的数据不一致,那就说明链路存在错误。

 实验整体框图

 ​​​该设计分为三个模块。

2.2.2 RTL 代码

`timescale  1ns/1ns
//FPGA中RS232通信模块
module  rs232
(
    input   wire    sys_clk     ,   
    input   wire    sys_rst_n   ,   
    input   wire    rx          ,   //串口接收数据

    output  wire    tx              //串口发送数据
);

parameter   UART_BPS    =   20'd9600        ,   //波特率
            CLK_FREQ    =   26'd50_000_000  ;   //时钟频率
			
wire    [7:0]   po_data;
wire            po_flag;
//串口接受数据模块
uart_rx
#(
    .UART_BPS    (UART_BPS  ),  //串口波特率
    .CLK_FREQ    (CLK_FREQ  )   //时钟频率
)
uart_rx_inst
(
    .sys_clk    (sys_clk    ), 
    .sys_rst_n  (sys_rst_n  ), 
    .rx         (rx         ), 
            
    .po_data    (po_data    ), 
    .po_flag    (po_flag    )  
);
//串口发送数据模块
uart_tx
#(
    .UART_BPS    (UART_BPS  ),  //串口波特率
    .CLK_FREQ    (CLK_FREQ  )   //时钟频率
)
uart_tx_inst
(
    .sys_clk    (sys_clk    ),  
    .sys_rst_n  (sys_rst_n  ),  
    .pi_data    (po_data    ),  
    .pi_flag    (po_flag    ),  
                
    .tx         (tx         )   
);
endmodule

2.2.3  仿真验证

`timescale  1ns/1ns

module  tb_rs232();

wire    tx          ;

reg     sys_clk     ;
reg     sys_rst_n   ;
reg     rx          ;

initial begin
    sys_clk    = 1'b1;
    sys_rst_n <= 1'b0;
    rx        <= 1'b1;
    #20;
    sys_rst_n <= 1'b1;
end
//初始化任务函数
initial begin
    #200
    rx_byte();  //调用任务rx_byte
end

always #10 sys_clk = ~sys_clk;

//创建任务rx_byte,本次任务调用rx_bit任务,发送8次数据,分别为0~7
task    rx_byte();  //因为不需要外部传递参数,所以括号中没有输入
    integer	j;
    for(j=0; j<8; j=j+1)    //调用8次rx_bit任务,每次发送的值从0变化7。for 括号中最后执行的内容不可写成i= i++
        rx_bit(j);
endtask

//创建任务rx_bit,每次发送的数据有10位,data的值分别为0到7由j的值传递进来
task    rx_bit(input   [7:0]   data);
    integer i;
    for(i=0; i<10; i=i+1)   begin
        case(i)
            0: rx <= 1'b0;     //起始位为0
            1: rx <= data[0];
            2: rx <= data[1];
            3: rx <= data[2];
            4: rx <= data[3];
            5: rx <= data[4];
            6: rx <= data[5];
            7: rx <= data[6];
            8: rx <= data[7];
            9: rx <= 1'b1;    //终止位为1
        endcase
        #(5208*20);   //每发送1位数据延时5208个时钟周期
    end
endtask

rs232   rs232_inst
(
    .sys_clk    (sys_clk    ),  
    .sys_rst_n  (sys_rst_n  ),  
    .rx         (rx         ),  

    .tx         (tx         )   
);
endmodule

2.3 串口数据接收模块

2.3.1 模块说明

        该模块功能是接收来自PC 机上的串口调试助手发送的固定波特率的串行数据,解析提取有用数据,再转化为并行数据(并行数据在 FPGA 内部传输的效率更高)同时产生一个数据有效信号标志信号(后级模块或系统在使用该并行数据的时候可能无法知道该时刻采样的数据是否有效的)伴随着并行的有效数据一同输出。模块框图如下。

2.3.2 波形设计

(1)reg1、reg2、reg3设计思路:      

      rx_reg1和rx_reg2对rx进行了打两拍处理,原因是时钟信号(来自fpga)和数据传输 rx (来自pc端)是异步的关系,输出很容易产生亚稳态。亚稳态是指触发器无法在某个规定的时间段内到达一个可以稳定的状态。产生亚稳态的本质原因是在时钟上升沿的建立时间或保持时间段输入数据不稳定,导致寄存器输出数据在一段时间也不稳定但在亚稳态后下一个时钟沿来临前会稳定下来(数据随机)。所以使用打两拍的方式消除亚稳态。示意图如下。

(2)staet_nedge设计思路:      

      rx_reg2取反再和rx_reg3进行 与 运算,产生staet_nedge信号,作为开始接收数据的标志。

(3)work_en、baud_cnt、bit_flag、bit_cnt、rx_flag设计思路:

     标记有效位。

(4)rx_data设计思路:

      使用位拼接的方式将串行数据转为并行然后存在寄存器中。

2.3.3 RTL代码

`timescale 1ns/1ns
//接收8位串行数据后转并行

module    uart_rx
#(
    parameter     UART_BPS = 'd9600,       //9600BPS
	              CLK_FREQ = 'd50_000_000  //50MHZ
)
(  
    input    wire        sys_clk      ,
	input    wire        sys_rst_n    ,
	input    wire        rx           ,
	                           
    output   reg  [7:0]  po_data      ,
    output   reg         po_flag      
);

localparam  BAUD_CNT_MAX    =   CLK_FREQ/UART_BPS   ;  //接受1bit数据所需多少个脉冲周期
reg             rx_reg1; 
reg             rx_reg2;  
reg             rx_reg3;
reg             start_nedge;
reg             bit_flag;
reg    [3:0]    bit_cnt;
reg             work_en;
reg    [15:0]   baud_cnt;
reg    [7:0]    rx_data;
reg             rx_flag;

//rx_reg: 进行打拍操作,消除亚稳态					   
always @(posedge sys_clk or negedge sys_rst_n)
     if( !sys_rst_n ) begin
	    rx_reg1 <= 1'b1;
		rx_reg2 <= 1'b1;
		rx_reg3 <= 1'b1;
		end
     else   begin
        rx_reg1 <= rx;	
        rx_reg2 <= rx_reg1;
        rx_reg3 <= rx_reg2;	
		end
		
//start_nedge:开始传输数据的标志								   
always @(posedge sys_clk or negedge sys_rst_n)
     if( !sys_rst_n )
         start_nedge	<= 1'b0;
     else if((rx_reg2 == 1'b0 && rx_reg3 == 1'b1 ) && (work_en == 1'b0))
	     start_nedge	<= 1'b1;
	 else 
	     start_nedge	<= 1'b0;
		 
//work_en:高电平传输数据使能	
always @(posedge sys_clk or negedge sys_rst_n)
     if( !sys_rst_n )
         work_en	<= 1'b0;
     else if (start_nedge == 1'b1)
	     work_en	<= 1'b1;
	 else if ((bit_flag == 1'b1) && (bit_cnt == 4'd8))
	     work_en	<= 1'b0;		 
//传输一位数据需要花 5208 脉冲周期
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	    baud_cnt	<= 1'b0;
	else  if (baud_cnt == BAUD_CNT_MAX - 1'b1) 
	    baud_cnt	<= 1'b0;
    else  if (work_en	== 1'b1)
	    baud_cnt  <= baud_cnt + 1'b1;
	else  
  	    baud_cnt	<= 1'b0;
		
//bit_flag:接收数据标志	
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	   bit_flag	<= 1'b0;    		
	else  if (( baud_cnt == (BAUD_CNT_MAX/2)  - 1 ))
        bit_flag	<= 1'b1; 
	else	
	    bit_flag	<= 1'b0;
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	   bit_cnt <= 1'b0; 
	else if ((bit_flag	== 1'b1) && (bit_cnt < 4'd8))
       bit_cnt <= bit_cnt + 1'b1;
	else if ((bit_flag	== 1'b1) && (bit_cnt == 4'd8))
	   bit_cnt <= 1'b0;
	
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )  
       rx_data	<= 1'b0; 
	else if ((bit_cnt >= 4'd1)&&(bit_cnt <= 4'd8)&&(bit_flag == 1'b1))
	   rx_data <= {rx_reg3, rx_data[7:1]};
	 
		
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rx_flag <= 1'b0;
    else    if((bit_cnt == 4'd8) && (bit_flag == 1'b1))
        rx_flag <= 1'b1;
    else
        rx_flag <= 1'b0;
		
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)  begin
        po_data <= 1'b0;
		po_flag  <= 1'b0;
		end
    else if (rx_flag == 1'b1)  begin	
   	    po_data <= rx_data;
		po_flag  <= 1'b1; 		
		end
	else 	
	    po_flag  <= 1'b0;
endmodule

2.3.4 仿真验证

     模拟PC机的串口调试助手产生一组串行数据 RX 输入接收模块。

`timescale  1ns/1ns

module  tb_uart_rx();

reg             sys_clk;
reg             sys_rst_n;
reg             rx;

wire    [7:0]   po_data;
wire            po_flag;

always #10 sys_clk = ~sys_clk;

initial begin
        sys_clk    = 1'b1;
        sys_rst_n <= 1'b0;
        rx        <= 1'b1;
        #20;
        sys_rst_n <= 1'b1;
end

//模拟发送8次数据,分别为0~7
initial begin
        #200
        rx_bit(8'd0);  //任务的调用,任务名+括号中要传递进任务的参数
        rx_bit(8'd1);
        rx_bit(8'd2);
        rx_bit(8'd3);
        rx_bit(8'd4);
        rx_bit(8'd5);
        rx_bit(8'd6);
        rx_bit(8'd7);
end

task rx_bit(input   [7:0]   data);
        integer i;      //定义一个变量
		                //integer类型也是一种寄存器数据类型,integer类型的变量为有符号数
        for(i=0; i<10; i=i+1) begin  //不可用i=i++的方式
            case(i)
                0: rx <= 1'b0;   //起始位
                1: rx <= data[0];
                2: rx <= data[1];
                3: rx <= data[2];
                4: rx <= data[3];
                5: rx <= data[4];
                6: rx <= data[5];
                7: rx <= data[6];
                8: rx <= data[7];
                9: rx <= 1'b1;
            endcase
            #(5208*20); //每发送1位数据延时5208个时钟周期
        end
endtask         //任务以endtask结束

uart_rx uart_rx_inst(
        .sys_clk    (sys_clk    ),  
        .sys_rst_n  (sys_rst_n  ),  
        .rx         (rx         ),  
                
        .po_data    (po_data    ),  
        .po_flag    (po_flag    )   
);
endmodule

2.4 串口数据发送模块

2.4.1 模块说明

    该模块的功能是将 FPGA 中的数据转化为串行数据。

 2.4.2 波形设计

2.4.3 RTL代码

`timescale 1ns/1ns
//并转串行

module     uart_tx
#(     
    parameter    UART_BPS    =   'd9600 ,  
    parameter    CLK_FREQ    =   'd50_000_000 

)
(
    input   wire            sys_clk     , 
    input   wire            sys_rst_n   , 
    input   wire    [7:0]   pi_data     , 
    input   wire            pi_flag     , 
    
    output  reg             tx            
);

reg          work_en;
reg  [15:0]  baud_cnt;
reg          bit_flag;
reg  [3:0]   bit_cnt;

localparam  BAUD_CNT_MAX    =   CLK_FREQ/UART_BPS   ;
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	    work_en <= 1'b0;
    else   if(pi_flag == 1'b1)  
	    work_en <= 1'b1;
	else   if((bit_flag == 1'b1) && (bit_cnt == 4'd9) )
	    work_en <= 1'b0;
		
//传输一位数据需要花 5208 脉冲周期
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	    baud_cnt	<= 1'b0;
	else  if (baud_cnt == BAUD_CNT_MAX - 1'b1) 
	    baud_cnt	<= 1'b0;
    else  if (work_en	== 1'b1)
	    baud_cnt  <= baud_cnt + 1'b1;
	else  
  	    baud_cnt	<= 1'b0;
	
//bit_flag:接收数据标志	
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	   bit_flag	<= 1'b0;    		
	else  if (( baud_cnt == (BAUD_CNT_MAX/2)  - 1 ))
        bit_flag	<= 1'b1; 
	else	
	    bit_flag	<= 1'b0;
		
always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
	   bit_cnt <= 1'b0; 
	else if ((bit_flag	== 1'b1) && (bit_cnt < 4'd9))
       bit_cnt <= bit_cnt + 1'b1;
	else if ((bit_flag	== 1'b1) && (bit_cnt == 4'd9))
	   bit_cnt <= 1'b0;		

always @(posedge sys_clk or negedge sys_rst_n)
    if( !sys_rst_n )
        tx <=  1'b1;
	else if(bit_flag == 1'b1)
	    case(bit_cnt)
		    0    :   tx  <= 1'b0;        //起始位
	        1    :   tx  <= pi_data[bit_cnt - 1];
            2    :   tx  <= pi_data[bit_cnt - 1];
            3    :   tx  <= pi_data[bit_cnt - 1];
            4    :   tx  <= pi_data[bit_cnt - 1];
            5    :   tx  <= pi_data[bit_cnt - 1];
            6    :   tx  <= pi_data[bit_cnt - 1];
            7    :   tx  <= pi_data[bit_cnt - 1];
            8    :   tx  <= pi_data[bit_cnt - 1];
            9    :   tx  <= 1'b1 ;       //结束位
			default : tx <= 1'b1;
			endcase

endmodule
			
			

2.4.4 仿真部分

      模拟并行数据传入发送模块。

`timescale  1ns/1ns

module  tb_uart_tx();

reg         sys_clk;
reg         sys_rst_n;
reg [7:0]   pi_data;
reg         pi_flag;

wire        tx;

initial begin
        sys_clk    = 1'b1;
        sys_rst_n <= 1'b0;
        #20;
        sys_rst_n <= 1'b1;
end

always #10 sys_clk = ~sys_clk;

initial begin
        pi_data <= 8'b0;
        pi_flag <= 1'b0;
        #200
        //发送数据0
        pi_data <= 8'd0;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
//每发送1bit数据需要5208个时钟周期,一帧数据为10bit
//所以需要数据延时(5208*20*10)后再产生下一个数据
        #(5208*20*10);
        //发送数据1
        pi_data <= 8'd1;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据2
        pi_data <= 8'd2;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据3
        pi_data <= 8'd3;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据4
        pi_data <= 8'd4;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据5
        pi_data <= 8'd5;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据6
        pi_data <= 8'd6;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
        #(5208*20*10);
        //发送数据7
        pi_data <= 8'd7;
        pi_flag <= 1'b1;
        #20
        pi_flag <= 1'b0;
end

uart_tx uart_tx_inst(
        .sys_clk    (sys_clk    ),
        .sys_rst_n  (sys_rst_n  ),
        .pi_data    (pi_data    ),
        .pi_flag    (pi_flag    ),

        .tx         (tx         ) 
);
endmodule

2.5 上板测试

3. 总结

重点理解整个回环的工作流程以及如何进行并行、串行数据数据的相互转换。

说明:

       本人参考的是野火家Xilinx Spartan6系列开发板及配套教程,以上内容如有疑惑或错误欢迎评论区指出。

开发软件:ise14.7     仿真:modelsim 10.5 

如需上述资料私信或留下邮箱。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FPGA—串口RS232(附实现代码) 的相关文章

  • FPGA零基础学习之Vivado-ROM使用教程

    FPGA零基础学习之Vivado ROM使用教程 本系列将带来FPGA的系统性学习 从最基本的数字电路基础开始 最详细操作步骤 最直白的言语描述 手把手的 傻瓜式 讲解 让电子 信息 通信类专业学生 初入职场小白及打算进阶提升的职业开发者都
  • 8x8LED点阵

    点量这个只需要把9高电平 13低电平就可以了 共阳极点阵 行线是led的正极 列线是led的列线 左上角点亮 显示多个灯是动态扫描的 一个一个显示的 然后间隔速度要快就可以造成显示 点阵由两篇74Hc595级联在一起驱动的 只需要三个io口
  • DDR的VTT有源端接和无源端接(slua886a笔记)

    DDR的VTT有源端接和无源端接 slua886a笔记 背景 对于DDR的VTT端接 一直有说法是有源端接可降低功耗 之前一直没仔细理解其中原因 现在找了些相关的资料来介绍和对比有源和无源端接 理解有源端接的优点和降低功耗的原理 主要基于读
  • Vivido添加pynq-Z2开发板

    一 下载pynq z2开发板文件 下载地址 https www tulembedded com FPGA ProductsPYNQ Z2 html 二 将下载的文件解压到vivado安装的位置 如果boards目录下面没有boards fi
  • MIPI D-PHY介绍(二) FPGA

    MIPI D PHY介绍 二 FPGA 随着移动设备的广泛普及 MIPI D PHY作为其最主要的物理层标准之一 被越来越多地使用在各种嵌入式系统中 本文将详细介绍MIPI D PHY的工作原理和在FPGA设计中的实现方法 MIPI D P
  • 硬件基础知识

    SPI是串行外设接口 Serial Peripheral Interface 的缩写 是一种高速的 全双工 同步的通信总线 SCLK SCLK是一种有固定周期并与运行无关的信号量 CLK CLK是一种脉冲信号 TDNN 时延神经网络 它的两
  • 用Vscode编辑verilog代码配置

    这篇教程感觉很详细了 我这里分享一下vscode和插件的安装包链接 都是官网下载的 放心食用 用VSCode编辑verilog代码 iverilog编译 自动例化 自动补全 自动格式化等常用插件 链接 https pan baidu com
  • 【FPGA】:频率测量

    转载 1 FPGA频率测量的三种方法 直接测量法 间接测量法 等精度测量法
  • 上拉电阻和下拉电阻

    一 定义 上拉电阻 将一个不确定的信号 通过一个电阻与电源VCC相连 固定在高电平 下拉电阻 将一个不确定的信号 通过一个电阻与地GND相连 固定在低电平 二 作用 提高输出信号驱动能力 确定输入信号电平 防干扰 限流 阻抗匹配 抗回波干扰
  • 小梅哥Xilinx FPGA学习笔记9——语法(阻塞与非阻塞赋值)

    阻塞赋值与非阻塞赋值详解 注意 阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 非阻塞赋值 1 设计文件 2 激励文件 3 原理图 4 仿真图 注意 阻塞赋值与非阻塞赋值 只有在时序逻辑中才有 不是阻塞赋值 也不是非阻塞赋值
  • IC数字后端

    在 innovus 里面 有时候我们需要控制 tie cell 的 fanout 和 net length 来避免 tie cell 可能出现 max transition 或者 max fanout 的违例 一般来说 只要 fanout
  • BUCK电路分析(二)

    BUCK电路分析 二 PSIM仿真同步BUCK电路 在上片文章中 初步的分析了BUCK电路的工作原理 本章使用PSIM软件仿真BUCK电路 观察分析BUCK电路器件关键波形 图1是同步BUCK电路图 开关频率设置为200K 固定占空比 在仿
  • [HDLBits] Exams/ece241 2014 q7a

    Design a 1 12 counter with the following inputs and outputs Reset Synchronous active high reset that forces the counter
  • PAJ7620U2手势识别——配置0x00寄存器(3)

    文章目录 前言 一 为啥要配置0x00寄存器 二 配置步骤 1 单个读操作步骤图 2 模块状态转移图绘制 3 模块波形图绘制 4 上板验证 5 参考代码 总结 前言 在前面的教程中 小编带领各位读者学习了如何通过I2C协议去唤醒PAJ762
  • 【FPGA】通俗理解从VGA显示到HDMI显示

    注 大部分参考内容来自 征途Pro FPGA Verilog开发实战指南 基于Altera EP4CE10 2021 7 10 上 贴个下载地址 野火FPGA Altera EP4CE10征途开发板 核心板 野火产品资料下载中心 文档 hd
  • 【FPGA多周期时序约束详解】- 解读FPGA多周期时序约束的全过程

    FPGA多周期时序约束详解 解读FPGA多周期时序约束的全过程 FPGA作为数字电路设计的常见工具 其设计中必然会遇到时序约束的问题 而多周期时序约束更是FPGA设计中不可避免的难点之一 本文将详细介绍FPGA多周期时序约束的全过程 并结合
  • 【FMC141】基于VITA57.4标准的4通道2.8GSPS 16位DA播放子卡(2片DAC39J84)

    FMC141是一款基于VITA57 4标准的4通道2 8GSPS 2 5GSPS 1 6GSPS采样率16位DA播放FMC子卡 该板卡为FMC 标准 符合VITA57 4与VITA57 1规范 16通道的JESD204B接口通过FMC 连接
  • 硬核 | 从零制作一个激光雷达需要多久?

    编辑 ADS智库 点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 硬件交流 技术交流群 本文只做学术分享 如有侵权 联系删文 激光雷达 LiDAR 是激光探测及测距系统的简称 目前广泛应用在无
  • 【ZYNQ学习】PL第一课

    这节课讲什么 这节课的名字本来是想写为LED 但这一课里除了LED也有按键 又想换为GPIO控制 但关于PL的GPIO控制 不应该这么草率和简单 而且这一课有很多和ZYNQ或者PL关联性不强的东西要说 所以我写了删删了写改了好几遍 终于定为
  • Matlab图像处理系列——图像复原之噪声模型仿真

    微信公众号上线 搜索公众号 小灰灰的FPGA 关注可获取相关源码 定期更新有关FPGA的项目以及开源项目源码 包括但不限于各类检测芯片驱动 低速接口驱动 高速接口驱动 数据信号处理 图像处理以及AXI总线等 本节目录 一 图像复原的模型 二

随机推荐

  • 富文本编辑器 VUE-QUILL-EDITOR 使用教程

    一 基础用法 1 NPM 导入 VUE QUILL EDITOR npm install vue quill editor save 2 引入 VUE QUILL EDITOR 在全局中引入 import Vue from vue impo
  • 如何实现单链表任意两个元素交换(不包括表头)

    凭第一感觉写的版本 算法和思路有好的想法再优化 交换链表任意两个元素 void SwapItem LinkedList head int posA int posB 从非头结点开始交换操作 保证至少存在两个节点 assert head he
  • 教你如何用C语言做一个简单的贪吃蛇

    小时候大家可能都玩过贪吃蛇 但有没有想过自己做一个出来玩玩看 今天我们就教大家用C语言做一个简单的贪吃蛇游戏 这里没有采用图形界面去做 而是采用win32控制台 首先 先把做好的游戏初始界面和游戏截图先展示一下 游戏初始界面如图 游戏截图如
  • Vue切换路由,页面回到上一次缓存的滚动位置(代码量少,通用有效)

    需求 当切换不同路由时 期望切换后的路由页面保留上次滚动的位置 解决思路 利用路由中的meta属性 对不同路由页面滚动的位置做缓存 切换路由时 获取当前路由meta属性中缓存的滚动位置 再自动滚动到此位置即可 具体代码 router js文
  • Kali Linux安装教程

    虚拟机Vmware Worksation下Kali Linux安装教程 本次安装Vmware Worksation采用的是15 5 pro 下载kali镜像 首先进入kali官网 https www kali org 点击Downloads
  • GIT操作:把当前仓库的一个分支push到另一个仓库的指定分支

    背景 有时候我们想把当前仓库A的一个指定分支1 推给 另一个仓库B的另一个指定分支2 可以通过2个主要命令git remote xxx 和 git push newOrigin 当前分支 目标分支 完成 示例 假设有2个仓库uu和uunew
  • java什么时候需要用序列化?

    文章目录 一 Java序列化概述 二 什么时候用序列化 三 项目创建很多对象怎么优化 场景 优化思路一 加条件判断 优化思路二 使用clone浅拷贝 一 Java序列化概述 简单说就是为了保存在内存中的各种对象的状态 也就是实例变量 不是方
  • vscode 缩进,取消自动格式化,溢出不换行

    Ctrl P gt 在输入框中输入 settings json 打开第一个 取消自动换行 editor wordWrap off 代码缩进 editor tabSize 4 取消每次保存的时候自动格式化 editor formatOnSav
  • 离散数学:常用的数学符号

    x A x 是 A 的元素 x A x 不是 A 的元素 A B A 是 B 的子集 或 A 包含于 B B 包含 A A B A 是 B 的真子集 A B B 不包含 A 或 A 不包含 B A B A 与 B 有相同的元素 A B A
  • zookeeper的Linux下安装和使用 单机版/集群版

    这个是单节点的 集群的在另一篇文章里做了说明 一 解压zookeeper的tar包 二 到zookeeper的conf目录下 拷贝zoo sample cfg 为zoo cfg 记住名字必须叫zoo cfg root VM 0 7 cent
  • 【高级篇 / SDWAN】(7.0) ❀ 07. DNS 解析最快的宽带优先上网 ❀ FortiGate 防火墙

    自从配置SD WAN之后 很多人反应网速变慢了 打开网站卡半天 你有没有接到过这种投诉 其实这是因为DNS解析的原因 由于多条宽带属于不同的运营商 而运营商自带的DNS对自己宽带的解析很快 但对其它宽带就会报错 所以我们只能使用通用DNS
  • 2021-08-06

    在编译OKVIS中 执行make j8时报错的解决方法 1 根据github上OKVIS的安装步骤一步一步执行 由于github经常进不去 我就进了gitee网站查到OKVIS的安装步骤 参考链接 https gitee com bill4
  • vue 引入 二维码

    vue cli3 动态生成二维码 不带logo的 第一步 先下载插件 npm install qrcodejs2 save 第二步 在需要生成二维码的 页面 导入 import QRCode from qrcodejs2 第三步 在页面中引
  • [云原生专题-34]:K8S - 核心概念 - 网络 - Web服务器与反向代理服务器nginx入门介绍

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122806880 目录 第1章 常见网
  • 深入了解一下C语言scanf()库函数

    目录 一 scanf函数的定义 二 scanf函数的返回值 三 scanf函数的控制符 四 scanf函数控制符的使用 1 一般用法 2 scanf 函数 控制符的用法 2 1 控制符的两种形式 2 2 字符的使用 3 键盘缓冲区残余信息问
  • Confluence 6 管理应用服务器内存设置

    应用服务器中的最小和最大 JVM Heap 空间配置将会影响系统的性能 Confluence 管理员可能希望对默认的配置进行修改 基于你系统的负载不同配置情况也会有所不同 请参考页面 Server Hardware Requirements
  • sed命令常见用法

    常见sed命令的操作 a 增加 在当前行下面增加一行指定内容 c 整行替换 将选定行替换为指定内容 d 删除 删除选定的行 w 将行写入新文件 r 从文件中读取 i 插入 在选定行上面插入一行指定内容 p 打印 如果同时指定行 表示打印指定
  • 五彩斑斓的黑

  • c++操作sqllite

    项目中需要使用的sqllite 有想过使用内存的结果 好像都不大使用 最接近的算是vector了 但是查询方式不大好 而且数据有好几个字段 所以考虑了数据库 sqllite目前已经到了3了 好快 好像这个数据库也不弱 就先用着吧 其实挺简单
  • FPGA—串口RS232(附实现代码)

    目录 1 理论 1 1 串口简介 1 2 RS232信号线 1 3 RS232通信协议简介 2 实操 2 1 硬件资源 2 2 顶层模块 2 2 1 模块说明 2 2 2 RTL 代码 2 2 3 仿真验证 2 3 串口数据接收模块 2 3