电设总结2——常见测频方法
测频方案主要包括两个方面:1、单片机测频,2、FPGA测频。
方案1:单片机测频
单片机测频主要有两种技术,第一种是输入捕获测频,另外输入捕获还可以测量占空比等参数,有兴趣可以去研究下
另一种是定时器外部中断测频,这个测频较为精准,以STM32F407为例,使用定时器外部中断测频,下面贴一下部分代码
// 该代码是配置定时器外部触发配置的代码,主要的逻辑代码就不贴了 void TIM2_CH1_Cap_Init(u32 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //TIM2时钟使能 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIOA0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0 GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_TIM2); //PA0复用位定时器2 //初始化定时器2 TIM2 TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式 TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITRxExternalClockConfig(TIM2,TIM_TS_ETRF); //配置外部触发,否则不会计数 TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0); TIM_SetCounter(TIM2, 0); TIM_Cmd(TIM2,ENABLE ); //使能定时器2 NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、 }
方案二:FPGA测频
FPGA测频主要来分享一种等精度测频法,是目前使用最广泛的方法。

根据原理我们可以发现等精度测频法保证了闸门的上升沿与被测信号同步,且周期是被测信号的整数倍。
测得的频率=标准信号的频率*被测信号的计数/标准信号的计数。
等精度测频法的Verilog实现代码如下
Gate标准闸门的生成:
module Gate( input clk, input rst_n, output reg T_1s ); parameter Count_1s = 24_999_999; reg [31:0]cnt; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin // reset cnt <= 32'd0; T_1s <= 1'b0; end else if (cnt >= Count_1s) begin cnt <= 32'd0; T_1s <= ~T_1s; end else begin cnt <= cnt + 1'b1; end end endmodule
计数模块如下:
module Fre( input CLK_200M, input RST_N, input CLK, input signal, output reg [31:0] N, output reg [31:0] M ); //N reg [31:0] Cnt_N; always @ (posedge signal or negedge RST_N) begin if(!RST_N) Cnt_N <= 0; else if(CLK) Cnt_N <= Cnt_N + 1; else Cnt_N <= 0; end reg [31:0] Cnt_M; always @ (posedge CLK_200M or negedge RST_N) begin if(!RST_N) Cnt_M <= 0; else if(CLK) Cnt_M0 <= Cnt_M + 1; else Cnt_M <=0; end always @ (negedge CLK or negedge RST_N) begin if(!RST_N) begin N<=0; M<=0; end else begin N <= Cnt_N; M <= Cnt_M; end end endmodule
在精度方面,根据理论分析在进行测量时,若在闸门时间内有 N个测量结果,测量误差将降低倍。
因此举个例子,如果测量的是1MHz的波,闸门时间是1s,标准信号频率从为100MHz,那么精度将是。