IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 基于FPGA+stm32的的等精度频率计 -> 正文阅读

[嵌入式]基于FPGA+stm32的的等精度频率计

整体功能:实现正弦波(方波)的频率和周期测量,并测量方波信号占空比

测量方法:

1.频率测量:使用等精度测量方法:等精度测量,由于设置的门控时间是5000个待测的信号的周期,所以当输入信号频率较低,会导致测量的时间过长。

2.占空比测量:这里借鉴了基于FPGA的简易频率计设计这篇文章的测量方法。通过门控时间内,对PLL倍频的200MHz时钟clk_200计数,读出待测信号连续的四个边沿的计数值,通过计算可以得到高电平的时间和待测信号的周期。然后计算可得到占空比。此外在输入频率较低的情况,上述测量得到的周期的倒数,可以作为低频信号的频率测量值。

整形电路

将待测信号整形变成FPGA可以识别到的TTL电平。具体实现由硬件实现的小伙伴完成,也没太操心@_@。

FPGA测频模块

测频模块

//频率测量(等精度)
module freq
   #(parameter    CLK_FS = 26'd50_000_000,// 基准时钟频率
	parameter  MAX       =  10'd32)  // 定义数据位宽        
    (   //system clock
        input                 clk_fs ,     // 时钟信号
        input                 rst_n   ,  // 复位信号

        //cymometer interface
        input                 clk_fx ,     // 待测信号
		input gate,       // 门控信号(与待测时钟同步)
		input gate_fs,    // 与基准时钟同步的门控信号
		input  neg_gate_fx,//
		input  neg_gate_fs,//
        
		output reg    [32-1:0]   fs_cnt      ,           //门控时间内基准时钟信号的个数 
		output reg    [32-1:0]   fx_cnt      ,          // 门控时间内待测信号的个数
		output reg  	[32-1:0]   data_fx_temp  // 待测信号的频率值
);


reg    [32-1:0]   fs_cnt_temp ;           // fs_cnt 计数
reg    [32-1:0]   fx_cnt_temp ;           // fx_cnt 计数

//门控时间内待测信号的计数,设置的为5000个,这里重新计数,只是用于检验信号是否正确
always @(posedge clk_fx or negedge rst_n) begin
    if(!rst_n) begin
        fx_cnt_temp <= 32'd0;
        fx_cnt <= 32'd0;
    end
    else if(gate)begin
      fx_cnt_temp <= fx_cnt_temp + 1'b1;
    end   
    else if(neg_gate_fx) begin
        
        fx_cnt_temp <= 32'd0;
        fx_cnt <= fx_cnt_temp;
        
    end
end

//门控时间内基准时钟的计数
always @(posedge clk_fs or negedge rst_n) begin
    if(!rst_n) begin
        fs_cnt_temp <= 32'd0;
        fs_cnt <= 32'd0;
    end
    else if(gate_fs)
        begin
        fs_cnt_temp <= fs_cnt_temp + 1'b1;
        end
    else if(neg_gate_fs) begin
        
        fs_cnt_temp <= 32'd0;
		fs_cnt <= fs_cnt_temp;
		data_fx_temp<=fs_cnt;
    end
end
//计算待测信号的频率值
//always @(posedge clk_fs or negedge rst_n) begin
//    if(!rst_n) begin
//        data_fx_temp <= 64'd0;
//    end
//    else if(gate_fs == 1'b0)
//			data_fx_temp <=CLK_FS*fx_cnt/fs_cnt;
//end

endmodule


//频率、占空比测量模块(测周法)
module duty_ratio(
     clk,
	  rst_n,
	  gate,sig,
     fre_count,
	  duty_count
);
input 	 clk; 
input 	 rst_n; 
input 	 	gate; 
input 	 	sig; 
output 	[31:0] 	fre_count; 
output	[31:0]	duty_count;

wire clk_200;
wire locked;

clk_200 pll_module(
    .areset(!rst_n),
    .inclk0(clk),
    .c0(clk_200)
);

reg [31:0] counter;                         //32位计数器
always @(posedge clk_200 or negedge rst_n)
begin
     if(!rst_n)
     begin
        counter  <= 1'b0;
     end
     else
     begin
        if(gate == 1'b1)
        begin
            counter <= counter + 1'b1;
        end          
        else
        begin
            counter <= 32'b0;
        end
     end
end


reg [1:0] en_sig_edge;
reg [1:0] en_sig_edge_n;

always @(posedge clk_200 or negedge rst_n)
begin
     if(!rst_n)
     begin
        en_sig_edge  <= 2'b0;
     end
     else
     begin
        en_sig_edge <= en_sig_edge_n;
     end
end

always @(*)
begin
     if(!rst_n)
     begin
       en_sig_edge_n = 2'b0;
     end
     else
     begin
        en_sig_edge_n = {en_sig_edge[0],sig};
     end
end


wire    edge_turn;
assign  edge_turn = en_sig_edge[0] ^ en_sig_edge[1];        //检测双边沿

reg [31:0] time_record[3:0];
always @(posedge clk_200 or negedge rst_n)
begin
    if(!rst_n)
    begin
        time_record[0] <= 32'b0;
        time_record[1] <= 32'b0;
        time_record[2] <= 32'b0;
        time_record[3] <= 32'b0;
    end

    else if(gate == 1'b0 )
    begin
        time_record[0] <= 32'b0;
        time_record[1] <= 32'b0;
        time_record[2] <= 32'b0;
        time_record[3] <= 32'b0;
    end

    else
    begin
        if(edge_turn)
            begin
            time_record[0] <= counter;
            time_record[1] <= time_record[0];
            time_record[2] <= time_record[1];
            time_record[3] <= time_record[2];
            end 
        else
            begin
            time_record[0] <= time_record[0];
            time_record[1] <= time_record[1];
            time_record[2] <= time_record[2];
            time_record[3] <= time_record[3];
            end
    end
end

reg [31:0] pipe_add_1;
reg [31:0] pipe_add_2;
reg [31:0] pipe_result;

always @(posedge clk or negedge rst_n)
begin
     if(!rst_n)
     begin
        pipe_add_1 <= 32'b0;
        pipe_add_2 <= 32'b0;
     end
     else
     begin
        pipe_add_1 <= time_record[0] + time_record[1];
        pipe_add_2 <= time_record[2] + time_record[3];
     end
end

always @(posedge clk or negedge rst_n)
begin
     if(!rst_n)
     begin
        pipe_result  <= 32'b0 ;
     end
     else
     begin
        pipe_result <= pipe_add_1 - pipe_add_2;
     end
end

reg [31:0] duty_count_reg;
always @(posedge sig or negedge rst_n)
begin
     if(!rst_n)
     begin
        duty_count_reg  <= 32'b0 ;
     end
     else
     begin
			if(gate == 1'b1)
				duty_count_reg <= time_record[0] - time_record[1];
			else
				duty_count_reg <= 32'b0;
     end
end

assign duty_count = duty_count_reg;
assign fre_count = pipe_result;

endmodule

由上述测频模块产生三组测量值,高电平时间计数值duty_count,2个待测信号周期计数值fre_count,门控时间内基准时钟的计数值data_fx。然后通过SPI 接口将这3组数据发给单片机进行处理。
SPI+DDS+FRE

MCU模块

通过SPI串口接收FPGA发送的三组数据。
根据公式可以算出
占 空 比 : d u t y = d u t y c o u n t / f r e c o u n t ? 2.0 占空比:duty ={duty_{count}}/{fre_{count}} *2.0 :duty=dutycount?/frecount??2.0
频 率 1 : f r e q 1 = c l k 200 M H z ? 2.0 / f r e c o u n t 频率1:freq 1 =clk_{200MHz}*2.0/{fre_{count}} 1:freq1=clk200MHz??2.0/frecount?
频 率 2 : f r e q 2 = c l k 50 M H z ? 5000 / d a t a f x 频率2:freq 2 =clk_{50MHz}*5000/{data_{fx}} 2:freq2=clk50MHz??5000/datafx?

当测量频率较低时,采用频率1freq1作为输出结果
但测量频率较高时,采用频率2freq2作为输出结果
最后通过LCD频显示。

实际测量

输入信号频率(Hz) / 占空比(%)测量频率 (单位:Hz) / 占空比(%)
1.234000 / 801.234014 /79.996
1000 /641000.10009/64.144
10000000/4010000400.967295 /40.0

实测图片:
测量值1

如有错误或者言语不恰当的地方可在评论区指出,谢谢!

实验源码

https://download.csdn.net/download/Cauchy_Z/20555477?spm=1001.2014.3001.5501

参考文章

[1]. [基于FPGA的简易频率计设计]

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:59:49  更:2021-07-28 08:00:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 6:11:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码