首页 > 其他分享 >Xilinx ZYNQ 7000+Vivado2015.2系列(九)基于AXI总线的等精度频率计(测量数字信号频率)

Xilinx ZYNQ 7000+Vivado2015.2系列(九)基于AXI总线的等精度频率计(测量数字信号频率)

时间:2024-03-27 19:24:44浏览次数:38  
标签:Vivado2015.2 计数 ZYNQ 信号 寄存器 test AXI 频率计 时钟

上一节我们体验了一把PS和PL是怎样联合开发的,这种ARM和FPGA联合设计是ZYNQ的精华所在。

这一节我们实现一个稍微复杂一点的功能——测量未知信号的频率,

PS和PL通过AXI总线交互数据,实现我们希望的功能。

如何测量数字信号的频率

最简单的办法——在一段时间内计数

在我们设定的时间(Tpr) 内对被测信号的脉冲进行计数, 得Nx, Fx=Nx/Tpr。

Tpr 越大,测频精度越高。

这种方法适合于高频信号,因为这里可能会有一个被测信号周期的误差,测量高频信号时误差小。

另一个变种——在一个周期内计数

在被测信号一个周期内对基准时钟信号计数,得Nx, 基准时钟周期为T, 则Tx=T*Nx, Fx=1/Tx。

被测信号频率越低, 基准时钟频率越高,测量精度越高。

因此这种方法适用于低频信号。

二者结合——多个周期同步计数

这种方法的精髓在于同步二字。

在计数时引入D触发器,在被测信号的上升沿计数(Ntest),

实际测量时间是被测信号周期的整数倍,消除了可能的1 个周期的误差。

引入一个标准时钟信号(Fstd已知),在测量被测信号频率的同时,对标准时钟脉冲进行计数(Nstd)。

它俩的计数时间相同:Nstd/Fstd = Ntest / Ftest,所以Ftest=Fstd*Ntest/Nstd

增大Tpr或提高Fstd,可以提高测量精度。这种方法高低频通吃。

今天我们要采用的是第三种方法,系统框图如下:

20171219225241223

可见看见后面两个计数模块的使能信号都是来自D触发器的输出,

D触发器的输入是待测信号,也就是测量时间会是待测信号的整数倍,

然后两个模块分别对待测信号和一个已知频率的时钟信号进行脉冲计数。

设计思路是:

①新建一个工程叫Freq_Meter,

创建基于AXI总线的频率计数模块

③命名为Freq_EA,默认4个寄存器,添加端口:

20171219230103653

④ 添加用户逻辑,复位信号连接到系统的,寄存器0的第0位用于计数清零,第1位用于控制计数时间:

// Add user logic here
    reg clr;
    reg Tpr;
    reg[31:0] Nstd;
    reg[31:0] Ntest;
    
    always @( posedge S_AXI_ACLK ) begin
        if ( S_AXI_ARESETN == 1'b0 ) begin
            clr <= 1'd0;
            Tpr <= 1'd0;
        end
        else begin
            clr <= slv_reg0[0];  //复位
            Tpr <= slv_reg0[1];  //预置时间
        end
    end
    //-----------------------------
    always @(posedge S_AXI_ACLK) begin //标准时钟
        if(!clr)
            Nstd <= 32'd0;
        else if(Tpr == 1'b1)
            Nstd <= Nstd + 1'b1;
        else
            Nstd <= Nstd;
    end 
    
    //------------------------------
    always @(posedge Ftest) begin //待测信号
        if(!clr)
            Ntest <= 32'd0;
        else if(Tpr == 1'b1)
            Ntest <= Ntest + 1'b1;
        else
            Ntest <= Ntest;
    end 
	// User logic ends

	endmodule

⑤计数值存到寄存器1,2中,寄存器0留着给控制信号(Tpr,rst):

20171219230337263

⑥顶层文件里,添加端口号:

20171219230508005

⑦端口调用里的信号补齐:

20171219230553937

⑧打包好IP。然后回到之前的工程,添加这个IP到库里。

⑨新建一个Block Design,添加zynq核,

因为我们需要两个信号,一个标准时钟(已知的,这里用的是100M),一个待测信号,

我们都用PS产生,最后我们可以看下这种方法测的到底准不准:

20171219231124099

⑩添加Freq_EA,CLK1连接到Ftest上,连接好后的框图如下:

20171219230821337

⑪一系列顺序操作,生成比特流后导入到SDK。

SDk部分设计

新建一个应用工程,首先还是找到xparameters.h文件,找到我们的IP的基地址:

20171219231516704

列一下,前面的硬件设计是这样的:

寄存器0是给控制i信号的,第0位用于计数复位,第1为用于控制计数时间,

拉高时开始计数,然后拉低时停止计数,

寄存器1存的是标准时钟计数值,

寄存器2是待测信号计数值。

一些相关注释在代码后边:

#include <stdio.h>
#include "xil_io.h"
#include "sleep.h"
#include "xparameters.h"
#include "xil_types.h"

int main(){
	u32 N_std,N_test;
	double Freq_test;
	while(1){
		Xil_Out32(XPAR_FREQ_EA_V1_0_0_BASEADDR,0); //0000_0000  低电平复位
		usleep(10);
		Xil_Out32(XPAR_FREQ_EA_V1_0_0_BASEADDR,3); //0000_0011   10us后开始计数
		usleep(100000); //计数0.1s,最高计数32位,不能溢出了
		N_std =Xil_In32(XPAR_FREQ_EA_V1_0_0_BASEADDR+4);
		N_test =Xil_In32(XPAR_FREQ_EA_V1_0_0_BASEADDR+8);
		xil_printf("N_std=%d\r\n",N_std);
		xil_printf("N_test=%d\r\n",N_test);
		Freq_test =(double)100.0*N_test/N_std;  //标准时钟是100MHz
		printf("The Frequency is %f MHz\r\n",Freq_test);
		sleep(2);
	}
	return 0;
}

上电,program FPGA,运行软件部分:

可以看见:

20171219232719421

对比一下,可以精确到小数点后4位,还是很准的:

20171219232838787

小插曲:

打印函数不能用xil_printf(),因为Xilinx提供的打印函数不能打印浮点数。

上面是我一开始用的xil_printf,结果数字出不来,要么计数一些奇怪符号,下面是换成C自带的库函数就可以了

20171219232612427

总结:

基于AXI总线的开发是很强大的,PS可以和Pl交互,不管是控制信号还是数据,甚至PL可以控制PS。

标签:Vivado2015.2,计数,ZYNQ,信号,寄存器,test,AXI,频率计,时钟
From: https://www.cnblogs.com/L707/p/18100021

相关文章

  • Xilinx ZYNQ 7000+Vivado2015.2系列(十)MIO/EMIO再识,MIO的引脚“复用”,EMIO当作PS的接口
    前面我们介绍过EMIO,但是不详细。MIO是PS的IO接口,这个M代表的是Multiuse,也就是多用途,在下图中我们可以看到54个MIO连接这么多东西,必须得复用,所以当我们开发的时候需要的功能配置上,不需要的去掉,防止IO口被占用。板子用的是zc702。下面我们双击ZYNQ核:我们到MIO的配置里,把其......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(八)ARM+FPGA的优势,PS控制PL产生需要的PWM波(基于AXI
    上一节我们观察了AXI总线的信号,了解了基于AXI总线读写的时序,这一节我们继续探索基于AXI总线的设计,来看一看ZYNQ系列开发板的独特优势,PS可以控制PL产生定制化的行为,而不需要去动硬件代码。这次实验是产生频率和占空比可调的PWM(PulseWidthModulation)信号,调用8次,产生8路PWM......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(七)软硬件联合Debug观察AXI总线读、写时各信号的时
    前面一节我们学会了创建基于AXI总线的IP,但是对于AXI协议各信号的时序还不太了解。这个实验就是通过SDK和Vivado联合调试观察AXI总线的信号。由于我们创建的接口是基于AXI_Lite协议的,所以我们实际观察到是AXI_Lite协议的信号时序。具体做法是创建一个基于AXI总线的加法器模块,在......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(六)创建一个基于AXI总线的GPIO IP并使用
    前言:FPGA+ARM是ZYNQ的特点,那么PL部分怎么和ARM通信呢,依靠的就是AXI总线。这个实验是创建一个基于AXI总线的GPIOIP,利用PL的资源来扩充GPIO资源。通过这个实验迅速入门开发基于总线的系统。使用的板子是zc702。AXI总线初识:AXI(AdvancedeXtensibleInterface),由ARM公司提出的......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(五)之ZYNQ的三种启动方式-JTAG、SD card、Flash
    前言:前面我们都是使用JTAG方式下载比特流文件,然后下载elf文件,最后点击Runas或者Debugas来运行程序。JTAG方式是通过tcl脚本来初始化PS,然后用JTAG收发信息,优点是可以在线调试,缺点是断电后程序就丢失了。为了解决程序丢失的问题,可以制作镜像文件烧写到sd卡或者flash中,上电即......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(四)之GPIO的三种方式:MIO、EMIO、AXI_GPIO
    前言:ZYNQ7000有三种GPIO:MIO,EMIO,AXI_GPIOMIO是固定管脚的,属于PS,使用时不消耗PL资源;EMIO通过PL扩展,使用时需要分配管脚,使用时消耗PL管脚资源;AXI_GPIO是封装好的IP核,PS通过M_AXI_GPIO接口控制PL部分实现IO,使用时消耗管脚资源和逻辑资源。使用的板子是zc702。1.MIO方式Zynq7000......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(三)之HelloWorld实验(最小系统)(纯PS)
    前言:使用的板子是zc702。用Vivado的IP核搭建最小系统,包括ARM核(CPUxc7z020),DDR3(4×256M),一个UART串口(MiniUSB转串口),纯PS,通过串口打印出HelloWorld,工程虽小,五脏俱全,算是一种朝圣。配置要和板子对应,大家注意修改。操作步骤:硬件部分1.新建Vivado工程选择芯片型号xc7z020clg484_1......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(二)之奇数分频和逻辑分析仪(ILA)的使用
    前言:偶数分频容易得到:N倍偶数分频,可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。奇数分频如何得到呢?第一部分 奇数分频奇数分频方法:N倍奇数分频,首先进行上升沿触发进行......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(一)之流水灯(纯PL)
    原文链接:https://blog.csdn.net/u014485485/article/details/78056980前言:学习Xilinx的ZYNQ7000系列,用的板子是zc702(注意不是zedboard),SOC型号是xc7z020。虽然设计思路一样,但不同的套件引脚和io标准是有区别的,zc702评估板的的外观图如下,可以对照下自己的板子:作为入门体验,本设......
  • zynq Lwip学习笔记-recv_callback函数
    文章目录前言一、概述二、函数体三调用位置前言最近在学习zynq中的lwip协议族,找不到很好的记笔记的地方,所以就用csdn记录一下自己的学习过程。现在对lwip不熟悉,只是把官方的lwipechoserver例程跑了一下,能跑通就一点点的照着学了,笔记都是根据自己的理解写的,而且部......