ZYNQ+Vivado2015.2系列(九)基于AXI总线的等精度频率计(测量数字信号频率)
2017-12-19 22:34
225 查看
上一节我们体验了一把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,可以提高测量精度。这种方法高低频通吃。
今天我们要采用的是第三种方法,系统框图如下:
可见看见后面两个计数模块的使能信号都是来自D触发器的输出,D触发器的输入是待测信号,也就是测量时间会是待测信号的整数倍,然后两个模块分别对待测信号和一个已知频率的时钟信号进行脉冲计数。
设计思路是:
得到计数值——PL完成
计算频率——PS完成
新建一个工程叫Freq_Meter,
创建基于AXI总线的频率计数模块
命名为Freq_EA,默认4个寄存器,添加端口:
添加用户逻辑,复位信号连接到系统的,寄存器0的第0位用于计数清零,第1位用于控制计数时间:
计数值存到寄存器1,2中,寄存器0留着给控制信号(Tpr,rst):
顶层文件里,添加端口号:
端口调用里的信号补齐:
打包好IP。然后回到之前的工程,添加这个IP到库里。
新建一个Block Design,添加zynq核,因为我们需要两个信号,一个标准时钟(已知的,这里用的是100M),一个待测信号,我们都用PS产生,最后我们可以看下这种方法测的到底准不准:
添加Freq_EA,CLK1连接到Ftest上,连接好后的框图如下:
一系列顺序操作,生成比特流后导入到SDK。
SDk部分设计
新建一个应用工程,首先还是找到xparameters.h文件,找到我们的IP的基地址:
列一下,前面的硬件设计是这样的:
寄存器0是给控制i信号的,第0位用于计数复位,第1为用于控制计数时间,拉高时开始计数,然后拉低时停止计数,
寄存器1存的是标准时钟计数值,
寄存器2是待测信号计数值。
一些相关注释在代码后边
上电,program FPGA,运行软件部分:
可以看见:
对比一下,可以精确到小数点后4位,还是很准的:
小插曲:
打印函数不能用xil_printf(),因为Xilinx提供的打印函数不能打印浮点数。上面是我一开始用的xil_printf,结果数字出不来,要么计数一些奇怪符号,下面是换成C自带的库函数就可以了
总结:
基于AXI总线的开发是很强大的,PS可以和Pl交互,不管是控制信号还是数据,甚至PL可以控制PS,这里权当抛砖引玉。
如何测量数字信号的频率
最简单的办法——在一段时间内计数
在我们设定的时间(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,可以提高测量精度。这种方法高低频通吃。
今天我们要采用的是第三种方法,系统框图如下:
可见看见后面两个计数模块的使能信号都是来自D触发器的输出,D触发器的输入是待测信号,也就是测量时间会是待测信号的整数倍,然后两个模块分别对待测信号和一个已知频率的时钟信号进行脉冲计数。
设计思路是:
得到计数值——PL完成
计算频率——PS完成
新建一个工程叫Freq_Meter,
创建基于AXI总线的频率计数模块
命名为Freq_EA,默认4个寄存器,添加端口:
添加用户逻辑,复位信号连接到系统的,寄存器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 4000 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):
顶层文件里,添加端口号:
端口调用里的信号补齐:
打包好IP。然后回到之前的工程,添加这个IP到库里。
新建一个Block Design,添加zynq核,因为我们需要两个信号,一个标准时钟(已知的,这里用的是100M),一个待测信号,我们都用PS产生,最后我们可以看下这种方法测的到底准不准:
添加Freq_EA,CLK1连接到Ftest上,连接好后的框图如下:
一系列顺序操作,生成比特流后导入到SDK。
SDk部分设计
新建一个应用工程,首先还是找到xparameters.h文件,找到我们的IP的基地址:
列一下,前面的硬件设计是这样的:
寄存器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,运行软件部分:
可以看见:
对比一下,可以精确到小数点后4位,还是很准的:
小插曲:
打印函数不能用xil_printf(),因为Xilinx提供的打印函数不能打印浮点数。上面是我一开始用的xil_printf,结果数字出不来,要么计数一些奇怪符号,下面是换成C自带的库函数就可以了
总结:
基于AXI总线的开发是很强大的,PS可以和Pl交互,不管是控制信号还是数据,甚至PL可以控制PS,这里权当抛砖引玉。
相关文章推荐
- ZYNQ+Vivado2015.2系列(七)软硬件联合Debug观察AXI总线读、写时各信号的时序
- ZYNQ+Vivado2015.2系列(八)ARM+FPGA的优势,PS控制PL产生需要的PWM波(基于AXI总线)
- Xilinx ZYNQ 7000+Vivado2015.2系列(六)创建一个基于AXI总线的GPIO IP并使用
- 关于单片机测量信号频率的精度问题
- 信号处理中数字频率和模拟频率简明讲解
- 【graceup系列】--基于Java带数字签名的邮件收发系统
- FPGA基础实验:用计数器读取ROM数据产生信号波形(直接数字频率合成DDS)
- 数字信号中的频率
- 基于信号完整性分析的高速数字PCB 的设计方法
- 基于FPGA的高速高精度频率测量的研究
- 数字万用表各指标含义:准确度(精度)分辨力(分辨率)测量范围--转
- FPGA等精度测量法测信号频率
- 基于声卡的数字信号发生器与数字电子琴的实现
- fpga等精度频率测量原理
- 数字信号中心频率
- ZYNQ基础系列(一) AXI总线通信
- 视频接口系列(三)--------DVI(VGA基础上发展起来的数字信号传输)
- 基于FPGA的高精度数字信号发生器
- 测量,信号处理中的精度分析or误差传播理论
- 基于jquery扩展文本——之精度文本控件(数字,精度文本)