基于FPGA的频率检测与LCD显示

链接:https://pan.baidu.com/s/1GRuf4OAcr4qKnzSmm3A7zg
提取码:1234

一、 设计要求
利用FPGA设计一个信号测频器,要求:
(1)测量脉冲信号;
(2)频率测量1-10MHz以及占空比10%-99% 精确到1%;
(3)将测出频率和占空比显示在LCD1602上;
二、 设计方案
FPGA设计主要分为三个大模块来设计:1.被测信号产生模块;2.被测信号检测模块;3.数字显示模块。设计框图如图 1所示。

图 1 基于FPGA的信号测频器设计框图

  1. 被测信号产生模块
    该模块主要是用来产生被测信号,可以在模块中设置被测信号的频率和占空比。采用的方法是对系统时钟进行计数分频产生被测信号。这部分也采用了一个PLL,输出一个100MHz的时钟作为检测模块的采样时钟。该部分涉及的模块:signal_gen模块和PLL模块。
    在这里插入图片描述

  2. 被测信号检测模块
    该模块对被测信号进行检测的方法是等精度测频法:
    (1)被测信号频率检测
    检测被测信号的频率,通过在外部使能信号有效时(即一段时间内),计数系统时钟脉冲数Ns与被测信号脉冲数Nd,若系统时钟频率为Fs,被测信号频率为Fd,则有Fs/Ns=Fd/Nd 最后有Fd=(Fs/Ns)·Nd。
    (2)被测信号占空比检测:
    检测被测信号的占空比,利用系统时钟,在外部使能信号有效时(即一段时间内),计数被测信号的正脉宽数Np和负脉宽数Nn,则占空比ducy=Np/(Np+Nn)*100%。
    该部分涉及的模块:signal_detect模块。

在这里插入图片描述

  1. 数字显示模块
    该模块主要分为两个部分:一个部分是把检测的频率码转换为十进制BCD码,采用这种方法虽然会提高运算时间,但却可以大大节省FPGA的资源(面积与速度的折衷);另外一个部分是驱动LCD1602进行显示。这里给出二进制码转换为十进制BCD码的几个步骤(以8bit二进制码为例): 1.将二进制码左移一位(或者乘2);2.找到左移后的码所对应的个,十,百位;3.判断在个位,十位和百位的码是否大于等于5;4.继续重复以上三步直到移位8次后停止;5.如果是则该段码加3。该部分涉及的模块:BCD2to10模块和lcd1602模块。

最终在FPGA的RTL视图如图 2所示:

三、 仿真测试
对设计进行Modelsim仿真测试,仿真采用一个近似于1MHz、占空比近似于50%的信号进行测试。在仿真中,我们可以发现经过检测之后的频率为980392Hz,占空比为49%。BCD转换模块分别每一位提取了出来,供LCD1602显示。如图 3所示。
在这里插入图片描述

//synopsys translate_off
`timescale 1 ns/ 1 ps
//synopsys translate_on
module signal_gen(
	s_clk,
	rst_n,
	d_clk,
	en
	);
	
	input		s_clk;													// 系统时钟 50MHz
	input  		rst_n;													// 复位信号
	output		d_clk;													// 被测信号
	output 		en;														// 检测使能 高电平时 允许检测
	
	//*********************************************************************************************
    //  模块名称:   被测信号产生模块
    //  功能描述:  这里采用计数分频产生被测信号  
	//			     调整count1可以设置频率和占空比
	//				 5MHz:		count1 == 32'd9
	//				 1MHz:		count1 == 32'd49
	//				 10KHz:?	count1 == 32'd4999?????
	//				 100Hz:?	count1 == 32'd499999?????
	//				 50Hz:?		count1 == 32'd999999???????
	//				 10Hz:     ?count1 == 32'd4999999
	//				 1Hz:       count1 == 32'd49999999 ????
    //*********************************************************************************************
	reg 	   	d_clk;
	reg [31:0] 	count1;
	
	always@(posedge s_clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			count1 <= #1 32'b0;
		else
		begin
			if(count1 == 32'd4999)									// 设置频率
				count1 <= #1 32'b0;
			else
				count1 <= #1 count1 + 32'b1;
		end
	end
	
	always@(posedge s_clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			d_clk <= #1 1'b0;
		else
		begin
			if(count1 <= 32'd2499)									// 设置占空比
				d_clk <= #1 1'b1;
			else
				d_clk <= #1 1'b0;
		end
	end
	
	//*********************************************************************************************
    //  模块名称:   检测使能模块
    //  功能描述:  en为高电平时,允许检测
	//			     这里一共16个时钟,前6个时钟en高电平,后10个时钟低电平???????
    //*********************************************************************************************
	reg 		en;
	reg [3:0]	count2;
	
	always@(posedge d_clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			count2 <= #1 4'b0;
		else if(count2 != 4'd15)
			count2 <= #1 count2 + 1'b1;
		else
			count2 <= #1 count2;
	end
	
	always@(posedge d_clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
			en <= #1 1'b0;
		else 
		begin
			if((count2 >= 4'd0)&&(count2 <= 4'd5))
				en <= #1 1'b1;
			else
				en <= #1 1'b0;
		end
	end

endmodule 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值