FPGA综合系统设计(六)脉冲参数测量仪

概述

这篇博文记录一下博主在两年前大二时做过的一个小东西。在这个设计实例中,使用并行ADC采集脉冲信号,测量其频率、占空比、幅度、上升沿和下降沿时间,将测量结果通过串口发送至MSP430单片机,使用TFT做界面显示。另外FPGA还可以输出一路10%占空比的标准1MHz脉冲信号。

这是一些完成本文设计的参考文章:
1. ADC采集设计参考“FPGA基础设计(五):并行ADC与DAC” https://blog.csdn.net/FPGADesigner/article/details/80672231
2. 串口通信设计参考“FPGA基础设计(三):UART串口通信”https://blog.csdn.net/FPGADesigner/article/details/75201194


环境与设备

Quartus Prime 16.0
Altera FPGA开发板
AD9226信号采集板
MSP430开发板、高速比较器等其它硬件模块


系统设计

测量信号的频率、占空比、幅度都比较简单,对于FPGA而言可以轻而易举得达到很高的精度和分辨率。最难的设计应该是测量上升沿和下降沿的时间。

博主最初的构想是脉冲信号一路由ADC采集测量幅度和边沿时间,一路由高速比较器整形为FPGA I/O端口的电平标准,直接输入到FPGA中测量频率和占空比,硬件结构如下:
这里写图片描述
这也是FPGA+单片机的一种典型应用,由FPGA完成高速数据采集工作,由单片机完成一些低速的数据处理和显示工作,FPGA和单片机之间采用某种通信协议交互数据。本设计所使用的FPGA开发板端口电平为LVCMOS3.3,因此需要使用比较器将脉冲信号整形到3.3V,使FPGA可以正常识别出脉冲信号的0和1状态。

FPGA设计的RTL视图如下:
这里写图片描述
1.幅度测量:PLL产生系统所需的时钟,ADC采样频率设置为50MHz。AD9226采集到数据后,在一个固定的周期内判决信号的最大幅值(即每个周期内单独判断),达到实时更新的效果。

2.边沿时间测量:上升沿是指从信号稳态幅度的10%上升到90%所经过的时间间隔,下降沿反之。pos_tr模块根据测量的幅度,判定信号的边沿时间。

3.频率测量:根据频率的定义,由系统时钟分频出1Hz(周期1s)的信号,统计1s内输入信号上升沿的个数,即为频率,具体代码如下:

module count(
    input clk,
    input rst_n,
    input fm_in,
    output reg [31:0] fm_out
    );

    //1Hz分频,产生clk_1s,1s内计数值即为频率
    reg [31:0]cnt;
    reg clk_1s;

    always @ (posedge clk or negedge rst_n)
        if (!rst_n) 
        begin 
            cnt <= 32'h0;
            clk_1s <= 1'b0;
        end
        else if (cnt == 32'd49_999_999)
        begin
            cnt <= 32'h0;
            clk_1s <= ~clk_1s;
        end
        else  cnt <= cnt + 1'b1;

    //1S内计数
    reg [31:0]fm_cnt;

    always @ (posedge fm_in or negedge rst_n)
        if (!rst_n) fm_cnt <= 32'd0;
        else if (!clk_1s) fm_cnt <= 32'd0;
        else fm_cnt <= fm_cnt + 1'b1;

    //获取计数结果
    always @ (negedge clk_1s or negedge rst_n)
        if (!rst_n) fm_out <= 32'd0;
        else fm_out <= fm_cnt;

endmodule

4.占空比测量:使用两级寄存器检测输入脉冲信号的上升沿,在两个上升沿之间分别在信号的高电平和低电平期间计数,利用这两个计数结果就可以计算得到信号的占空比。具体代码如下:

module dutycycle(
    input clk,
    input rst_n,
    input wave_in,
    output reg [31:0] pos_out,  //输出高电平计数结果
    output reg [31:0] neg_out  //输出低电平计数结果
    );


// ************************************************
//                      输入脉冲上升沿检测
// ************************************************

reg syn1;
reg syn2;

always @ (posedge clk)
begin
    syn1 <= wave_in;
    syn2 <= syn1;
end

wire wave_pos = syn2 & (~syn1);
//wire wave_neg = (~syn2) & syn1;


// ************************************************
//                      高电平低电平计数
// ************************************************

reg [31:0]cnt_pos;      //高电平计数器
reg [31:0]cnt_neg;      //低电平计数器

always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin
        cnt_pos <= 32'd0;
        cnt_neg <= 32'd0;
        pos_out <= 32'd0;
        neg_out <= 32'd0;
    end                          
    else if (wave_pos) begin
        cnt_pos <= 32'd0;
        cnt_neg <= 32'd0;
        pos_out <= cnt_pos;
        neg_out <= cnt_neg;
    end
    else if (syn1)  cnt_pos <= cnt_pos + 1'b1;
    else    cnt_neg <= cnt_neg + 1'b1;  

endmodule

所有的测量结果按一定的帧格式拼接,通过串口发送至MSP430单片机,在单片机中处理、显示即可。

博主当时在设计时遇到了一个问题:430无论如何都不能正确的接收到FPGA传来的数据。但是单独使用串口调试助手调试FPGA和430,结果又是正确的。费了一番功夫才发现是因为两边的通信格式不匹配:FPGA带了奇偶校验、430没有配置奇偶校验,这样MSP430在收到校验位时会错误的把它当作停止位,从而导致通信出错。而单独使用串口调试助手时又会容错这种错误。总之在通信问题上一定要注意双方协议的匹配。

输出10%占空比的标准1MHz脉冲信号很简单,利用一个计数器,在相应的计数状态改变输出端口的值即可。代码如下:

module pulse(
    input clk,
    input rst_n,
    output reg pulse);

    reg [7:0] cnt;

    reg pulse_reg1;

    always @ (posedge clk or negedge rst_n)
        if (!rst_n) begin 
            cnt <= 'd0; 
            pulse_reg1 <= 1'b1; 
        end
        else if (cnt == 'd18) begin
            pulse_reg1 <= 1'b0;
            cnt <= cnt + 1'b1;
        end 
        else if (cnt == 'd199) begin
            cnt <= 'd0;
            pulse_reg1 <= 1'b1;
        end 
        else begin
            cnt <= cnt + 1'b1;
            pulse_reg1 <= pulse_reg1;
        end 

    always @ (posedge clk)
    begin
        pulse      <= pulse_reg1;
    end

endmodule

实物

搭建好的整体系统如下:
这里写图片描述
频率、占空比、幅度在实际测试中都表现不错,能达到很高的精度,但是边沿时间的测量就差强人意。因为50MHz的采样频率,在测量中时间分辨率只有20ns,由于代码设计的关系能达到的时间测量大概在80ns以上(因为要检测信号幅度的10%和90%),更不用说通常脉冲信号的边沿时间只有几ns甚至更低。

在网上查询资料后,我找到了一款型号为TDC-GP2的时间间隔测量芯片,分辨率可达50ps,可以用它来测量脉冲边沿时间。将系统设计框图修改为:
这里写图片描述
这样就可以完成边沿时间的测量,使整体系统功能更完整。

猜你喜欢

转载自blog.csdn.net/FPGADesigner/article/details/80723931