首页 > 技术 > 内容

基于AXI总线的未知信号频率测量

时间:2025-12-01  作者:Diven  阅读:0

上一节我们体验了一把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位用于控制计数时间:

// 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):

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

端口调用里的信号补齐:

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

新建一个Block Design,添加zynq核,因为我们需要两个信号,一个标准时钟(已知的,这里用的是100M),一个待测信号,我们都用PS产生,最后我们可以看下这种方法测的到底准不准:

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

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

SDk部分设计

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

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

寄存器0是给控制i信号的,第0位用于计数复位,第1为用于控制计数时间,拉高时开始计数,然后拉低时停止计数,

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

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

一些相关注释在代码后边

#include

#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,这里权当抛砖引玉。

猜您喜欢


合金电阻稳定的性能和优良的耐热性被应用于各种电子设备中。SUPEROHM(美隆)作为知名的合金电阻品牌,高品质和多样化的规格赢得了市场的认可。本文将详细介绍SU...
2015-03-06 19:39:20
现代电子产品中,封装技术的选择对器件的性能、散热、尺寸和成本等方面都有着重要影响。QFN(QuadFlatNo-lead)封装以其优良的散热性能和较小的体积,成...
2025-02-24 17:17:04
贴片电阻上的5R6代表阻值为5.6欧姆。字母R在这里是小数点的替代符号,方便在有限的空间内清晰地标注阻值。这种表示方法在电子元件领域非常普遍,尤其是在贴片元件上...
2024-11-29 10:26:21
四端子电阻因其高精度和稳定性,在测量和测试领域应用。作为全球知名的电子元件制造商,泰科电子(TE Connectivity)生产的四端子电阻受到关注。本文将详细...
2024-07-16 05:36:20
电子电路设计中,稳压二极管被用于电压稳定和过压保护。Multisim作为一款强大的电路仿真软件,提供了丰富的工具来模拟和分析电子元件的行为,包括稳压二极管。本文...
2025-04-04 17:00:34
隔离式RS485/422收发器(带电源)是重要的通信设备,应用于工业自动化、楼宇控制和数据采集等领域。其主要参数包括:工作电压范围一般为+5V至+12V,确保设...
2016-01-04 00:00:00
壁纸作为提升家居美感的重要元素,越来越受到人们的青睐。而在壁纸安装与使用过程中,熔断器作为保护电路安全的重要部件,其品牌和型号的选择同样关键。本文将围绕“YOU...
2022-06-26 15:48:30
在现代生活中,轻触开关作为重要的电子元件,是不可少的配件。不仅应用于家电、照明设备、汽车和智能家居等领域,更是提高我们生活便利性的重要工具。轻触开关的主要作用在...
2010-09-26 00:00:00
现代工业和制造领域,材料的选择非常重要。PM_40X25.4MM_TM作为新型材料,因其独特的物理和化学特性,正在逐渐受到关注。本文将为您详细解析PM_40X2...
2025-04-20 05:00:36
探头在现代科技中是非常重要的配件。是能够感知、检测和传递信息的设备,应用于医疗、工业、环境监测等领域。在医疗领域,探头可以用于超声波检查,帮助医生准确诊断病情;...
2023-12-07 00:00:00