基于FPGA的脉宽测量

FPGA 设计基础篇

FPGA 设计基础篇

基于FPGA 的脉宽测量著: 开源达人

时间:2016年12月14日

目录

1. 脉宽测量 ............................................................................................................................... 3

1.1简介 ............................................................................................................................ 3

1.2 代码解析.......................................................................................................................... 3

1. 脉宽测量

1.1简介

脉宽测量:测量出PWM 波高电平或低电平的宽度。

主要应用:脉宽调制的解调 占空比测量 频率测量

1.2 代码解析

脉宽测量案例1:VHDL 案例工程在如下文件夹中

(1_Foundation_course_of_FPGA_Design\example\Chapter7\Pulse_width_measure_VHDL)该案例采用的是 1M 采样频率,案例采用------------------------------------------------------

--design name :Pulse_width_measure

--use :脉宽测量 (脉宽调制的解调 占空比测量 频率测量) --build time :2016/12/14

--version :V0.1

--change note :

--V0.1 首次建立 2016年12月14日

-----------------------------------------------------

library IEEE;

port

(

:in std_logic;--系统时钟输入

:in std_logic;--系统复位输入

pulse_in :in std_logic;--脉冲输入

pulse_h_reg :out s td_logic_vector(15 downto 0);--脉冲高电平脉宽寄存器

pulse_l_reg :out s td_logic_vector(15 downto 0) --脉冲低电平脉宽寄存器

);

end Pulse_width_measure;

architecture Behavioral of Pulse_width_measure is

signal pulse_in_d1 :std_logic;--脉冲输入第1级D 触发器

signal pulse_in_d2 :std_logic;--脉冲输入第2级D 触发器

signal pulse_posedge :std_logic;--上升沿标志位

signal pulse_negedge :std_logic;--下降沿标志位

signal pulse_h_counter :std_logic_vector(15 downto 0);--高电平脉宽计数器 signal pulse_l_counter :std_logic_vector(15 downto 0);--低电平脉宽计数器

signal pulse_h_cache :std_logic_vector(15 downto 0);--高电平脉宽缓存寄存器 signal pulse_l_cache :std_logic_vector(15 downto 0);--低电平脉宽缓存寄存器

signal sampling :std_logic;--采样频率使能信号

signal sampling_counter :integer range 0 to 59;--1M 采样频率配置(此参数可配置成不同的采样速度)采样速度在1Mhz 时,推荐输入脉冲频率在20HZ~10Khz之间

signal reg_en :std_logic;--寄存器输出使能信号

--脉冲个数监测计数器,脉冲输入一个完整周期后再输出计数器的值,防止起始占空比计算值抖动

begin

---------------------脉冲输入第1级D 触发器代码---------------------

process(clk,rst)

begin

----------------------------------------------------------------

---------------------脉冲输入第2级D 触发器代码---------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_in_d2

elsif(clk'event and clk = '1')then

pulse_in_d2

end if;

end process;

----------------------------------------------------------------

----------------------上升沿下降沿标志位代码-----------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_posedge

pulse_negedge

elsif(clk'event and clk = '1')then

if(pulse_in_d2 = '0' and pulse_in_d1 = '1')then--上升沿

pulse_posedge

pulse_negedge

end if;

--下降沿 pulse_posedge

pulse_negedge

end if;

end if;

end process;

----------------------------------------------------------------

--------------------------采样频率配置代码------------------------

process(clk,rst)

begin

--配置成1M

sampling_counter

sampling

end if;

end if;

end process;

----------------------------------------------------------------

----------------------高电平脉宽计数器代码-------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_counter

elsif(clk'event and clk = '1')then

if(sampling = '1')then

if(pulse_posedge = '1')then

if(pulse_h_counter = x"ffff")then --脉宽限定,不要超出寄存器范围

pulse_h_counter

else

pulse_h_counter

end if;

else

pulse_h_counter

end if;

end if;

end if;

end process;

----------------------------------------------------------------

----------------------低电平脉宽计数器代码------------------------

process(clk,rst)

begin

if(rst = '1')then

--脉宽限定,不要超出寄存器范围

pulse_l_counter

end if;

else

pulse_l_counter

end if;

end if;

end if;

end process;

----------------------------------------------------------------

----------------------脉宽寄存器寄存代码--------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_cache

pulse_l_cache

elsif(clk'event and clk = '1')then

if(pulse_in_d2 = '0' and pulse_in_d1 = '1')then--上升沿时寄存低电平脉宽

pulse_l_cache

end if;

if(pulse_in_d2 = '1' and pulse_in_d1 = '0')then--下降沿时寄存高电平脉宽

pulse_h_cache

end if;

end process;

--------------------------------------------------------------

----------------------脉宽寄存器输出代码--------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_reg

pulse_l_reg

)then

下降沿输出, 防止占空比计算值抖动

--超过寄存器限制后占空比为0

该案例仿真主时钟为60M, 采样频率1M 对一个20K 的方波进行脉宽测量,一个周期后可见高地电平脉宽均为25,仿真结果正确。起始低电平脉宽为满值是为了避免占空比计算时出现0除以0的情况。

脉宽测量案例2:VERILOG 案例工程在如下文件夹中

(1_Foundation_course_of_FPGA_Design\example\Chapter7\Pulse_width_measure_Verilog)案例采用RTL 描述

/****************************************************

design name :Pulse_width_measure

use :脉宽调制的解调 占空比测量 频率测量

build time :2016/11/29

version :V0.1

change note :

V0.1 首次建立 2016年11月29日

*****************************************************/

module Pulse_width_measure

(

input clk, //时钟输入

input rst, //复位输入

input pulse_in, //脉冲信号输入

output reg [31:0] pulse_high_reg, //高电平宽度寄存器

output reg [31:0] pulse_low_reg //低电平宽度寄存器

);

reg pulse_in_q1,pulse_in_q2;//脉冲输入两级D 触发器

//输入脉冲上升沿标志触发器 //输入脉冲下降沿标志触发器

//脉冲高电平计数器 //脉冲低电平计数器

//高电平宽度寄存器D 端

//低电平宽度寄存器D 端

/****************输入两级D 触发器级联*******************/

begin

if(rst == 1'b0)

pulse_in_q1

else

pulse_in_q1

end

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_in_q2

else

pulse_in_q2

end

/***************************************************/

/***************输入脉冲上升沿标志采集*****************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_in_posedge_q

else

pulse_in_posedge_q

end

always@(*)

begin

//上升沿时标志触发器置1 pulse_in_posedge_d = 1'b1;

//下降沿时触发器清零 pulse_in_posedge_d = 1'b0;

else

end

/***************************************************/

/***************输入脉冲下升沿标志采集*****************/

begin

end

always@(*)

begin

if(pulse_in_q1 == 1'b0 && pulse_in_q2 == 1'b1)//下降沿时标志触发器置1 pulse_in_negedge_d = 1'b1;

else if(pulse_in_q1 == 1'b1 && pulse_in_q2 == 1'b0)//上升沿时标志触发器清零

pulse_in_negedge_d = 1'b0;

else

pulse_in_negedge_d = pulse_in_negedge_q;

end

/***************************************************/

/***************输入脉冲高电平计数器******************/ always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_high_counter_q

else

pulse_high_counter_q

always@(*)

begin

if(pulse_in_negedge_q == 1'b1)

pulse_high_counter_d = 1'b0;

else if(pulse_in_posedge_q == 1'b1)

else

end

/***************************************************/

/***************输入脉冲低电平计数器******************/ begin

if(rst == 1'b0)

else

end

pulse_low_counter_d = 1'b0;

else if(pulse_in_negedge_q == 1'b1)

pulse_low_counter_d = pulse_low_counter_q + 1'b1; else

pulse_low_counter_d = pulse_low_counter_q; end

/***************************************************/

/***************高电平宽度寄存器输出******************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_high_reg

else

pulse_high_reg

end

always@(*)

begin

if(pulse_in_q1 == 1'b0 && pulse_in_q2 == 1'b1)//下降沿时输出高电平脉宽 pulse_high_reg_d = pulse_high_counter_q + 1'b1;//补齐偏差值 else

pulse_high_reg_d = pulse_high_reg;

end

/***************************************************/

/***************低电平宽度寄存器输出******************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_low_reg

else

end

always@(*)

begin

//上升沿时输出高电平脉宽 //补齐偏差值

else

/***************************************************/

仿真分析:

该案例知识单纯输出脉宽,没有输出保护措施,若要使用该模块进行占空比和频率的测量,需要像上一案例一样进行输出保护措施。以上仿真为50M 采样

250K

方波的仿真,结果正确。

FPGA 设计基础篇

FPGA 设计基础篇

基于FPGA 的脉宽测量著: 开源达人

时间:2016年12月14日

目录

1. 脉宽测量 ............................................................................................................................... 3

1.1简介 ............................................................................................................................ 3

1.2 代码解析.......................................................................................................................... 3

1. 脉宽测量

1.1简介

脉宽测量:测量出PWM 波高电平或低电平的宽度。

主要应用:脉宽调制的解调 占空比测量 频率测量

1.2 代码解析

脉宽测量案例1:VHDL 案例工程在如下文件夹中

(1_Foundation_course_of_FPGA_Design\example\Chapter7\Pulse_width_measure_VHDL)该案例采用的是 1M 采样频率,案例采用------------------------------------------------------

--design name :Pulse_width_measure

--use :脉宽测量 (脉宽调制的解调 占空比测量 频率测量) --build time :2016/12/14

--version :V0.1

--change note :

--V0.1 首次建立 2016年12月14日

-----------------------------------------------------

library IEEE;

port

(

:in std_logic;--系统时钟输入

:in std_logic;--系统复位输入

pulse_in :in std_logic;--脉冲输入

pulse_h_reg :out s td_logic_vector(15 downto 0);--脉冲高电平脉宽寄存器

pulse_l_reg :out s td_logic_vector(15 downto 0) --脉冲低电平脉宽寄存器

);

end Pulse_width_measure;

architecture Behavioral of Pulse_width_measure is

signal pulse_in_d1 :std_logic;--脉冲输入第1级D 触发器

signal pulse_in_d2 :std_logic;--脉冲输入第2级D 触发器

signal pulse_posedge :std_logic;--上升沿标志位

signal pulse_negedge :std_logic;--下降沿标志位

signal pulse_h_counter :std_logic_vector(15 downto 0);--高电平脉宽计数器 signal pulse_l_counter :std_logic_vector(15 downto 0);--低电平脉宽计数器

signal pulse_h_cache :std_logic_vector(15 downto 0);--高电平脉宽缓存寄存器 signal pulse_l_cache :std_logic_vector(15 downto 0);--低电平脉宽缓存寄存器

signal sampling :std_logic;--采样频率使能信号

signal sampling_counter :integer range 0 to 59;--1M 采样频率配置(此参数可配置成不同的采样速度)采样速度在1Mhz 时,推荐输入脉冲频率在20HZ~10Khz之间

signal reg_en :std_logic;--寄存器输出使能信号

--脉冲个数监测计数器,脉冲输入一个完整周期后再输出计数器的值,防止起始占空比计算值抖动

begin

---------------------脉冲输入第1级D 触发器代码---------------------

process(clk,rst)

begin

----------------------------------------------------------------

---------------------脉冲输入第2级D 触发器代码---------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_in_d2

elsif(clk'event and clk = '1')then

pulse_in_d2

end if;

end process;

----------------------------------------------------------------

----------------------上升沿下降沿标志位代码-----------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_posedge

pulse_negedge

elsif(clk'event and clk = '1')then

if(pulse_in_d2 = '0' and pulse_in_d1 = '1')then--上升沿

pulse_posedge

pulse_negedge

end if;

--下降沿 pulse_posedge

pulse_negedge

end if;

end if;

end process;

----------------------------------------------------------------

--------------------------采样频率配置代码------------------------

process(clk,rst)

begin

--配置成1M

sampling_counter

sampling

end if;

end if;

end process;

----------------------------------------------------------------

----------------------高电平脉宽计数器代码-------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_counter

elsif(clk'event and clk = '1')then

if(sampling = '1')then

if(pulse_posedge = '1')then

if(pulse_h_counter = x"ffff")then --脉宽限定,不要超出寄存器范围

pulse_h_counter

else

pulse_h_counter

end if;

else

pulse_h_counter

end if;

end if;

end if;

end process;

----------------------------------------------------------------

----------------------低电平脉宽计数器代码------------------------

process(clk,rst)

begin

if(rst = '1')then

--脉宽限定,不要超出寄存器范围

pulse_l_counter

end if;

else

pulse_l_counter

end if;

end if;

end if;

end process;

----------------------------------------------------------------

----------------------脉宽寄存器寄存代码--------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_cache

pulse_l_cache

elsif(clk'event and clk = '1')then

if(pulse_in_d2 = '0' and pulse_in_d1 = '1')then--上升沿时寄存低电平脉宽

pulse_l_cache

end if;

if(pulse_in_d2 = '1' and pulse_in_d1 = '0')then--下降沿时寄存高电平脉宽

pulse_h_cache

end if;

end process;

--------------------------------------------------------------

----------------------脉宽寄存器输出代码--------------------------

process(clk,rst)

begin

if(rst = '1')then

pulse_h_reg

pulse_l_reg

)then

下降沿输出, 防止占空比计算值抖动

--超过寄存器限制后占空比为0

该案例仿真主时钟为60M, 采样频率1M 对一个20K 的方波进行脉宽测量,一个周期后可见高地电平脉宽均为25,仿真结果正确。起始低电平脉宽为满值是为了避免占空比计算时出现0除以0的情况。

脉宽测量案例2:VERILOG 案例工程在如下文件夹中

(1_Foundation_course_of_FPGA_Design\example\Chapter7\Pulse_width_measure_Verilog)案例采用RTL 描述

/****************************************************

design name :Pulse_width_measure

use :脉宽调制的解调 占空比测量 频率测量

build time :2016/11/29

version :V0.1

change note :

V0.1 首次建立 2016年11月29日

*****************************************************/

module Pulse_width_measure

(

input clk, //时钟输入

input rst, //复位输入

input pulse_in, //脉冲信号输入

output reg [31:0] pulse_high_reg, //高电平宽度寄存器

output reg [31:0] pulse_low_reg //低电平宽度寄存器

);

reg pulse_in_q1,pulse_in_q2;//脉冲输入两级D 触发器

//输入脉冲上升沿标志触发器 //输入脉冲下降沿标志触发器

//脉冲高电平计数器 //脉冲低电平计数器

//高电平宽度寄存器D 端

//低电平宽度寄存器D 端

/****************输入两级D 触发器级联*******************/

begin

if(rst == 1'b0)

pulse_in_q1

else

pulse_in_q1

end

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_in_q2

else

pulse_in_q2

end

/***************************************************/

/***************输入脉冲上升沿标志采集*****************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_in_posedge_q

else

pulse_in_posedge_q

end

always@(*)

begin

//上升沿时标志触发器置1 pulse_in_posedge_d = 1'b1;

//下降沿时触发器清零 pulse_in_posedge_d = 1'b0;

else

end

/***************************************************/

/***************输入脉冲下升沿标志采集*****************/

begin

end

always@(*)

begin

if(pulse_in_q1 == 1'b0 && pulse_in_q2 == 1'b1)//下降沿时标志触发器置1 pulse_in_negedge_d = 1'b1;

else if(pulse_in_q1 == 1'b1 && pulse_in_q2 == 1'b0)//上升沿时标志触发器清零

pulse_in_negedge_d = 1'b0;

else

pulse_in_negedge_d = pulse_in_negedge_q;

end

/***************************************************/

/***************输入脉冲高电平计数器******************/ always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_high_counter_q

else

pulse_high_counter_q

always@(*)

begin

if(pulse_in_negedge_q == 1'b1)

pulse_high_counter_d = 1'b0;

else if(pulse_in_posedge_q == 1'b1)

else

end

/***************************************************/

/***************输入脉冲低电平计数器******************/ begin

if(rst == 1'b0)

else

end

pulse_low_counter_d = 1'b0;

else if(pulse_in_negedge_q == 1'b1)

pulse_low_counter_d = pulse_low_counter_q + 1'b1; else

pulse_low_counter_d = pulse_low_counter_q; end

/***************************************************/

/***************高电平宽度寄存器输出******************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_high_reg

else

pulse_high_reg

end

always@(*)

begin

if(pulse_in_q1 == 1'b0 && pulse_in_q2 == 1'b1)//下降沿时输出高电平脉宽 pulse_high_reg_d = pulse_high_counter_q + 1'b1;//补齐偏差值 else

pulse_high_reg_d = pulse_high_reg;

end

/***************************************************/

/***************低电平宽度寄存器输出******************/

always@(posedge clk , negedge rst)

begin

if(rst == 1'b0)

pulse_low_reg

else

end

always@(*)

begin

//上升沿时输出高电平脉宽 //补齐偏差值

else

/***************************************************/

仿真分析:

该案例知识单纯输出脉宽,没有输出保护措施,若要使用该模块进行占空比和频率的测量,需要像上一案例一样进行输出保护措施。以上仿真为50M 采样

250K

方波的仿真,结果正确。


相关文章

  • 细说电子设计EDA工具软件
  • IT十八般武艺--细说电子设计EDA工具软件 IT产业如今在中国发展得如火如荼,IT专业年年扩招,人数越来越多.如今的IT相关的本科专业包括电子信息工程.通信工程.电子信息与技术.自动化与控制专业.计算机专业.机械与电子工程.信息安全工程. ...查看


  • 频率特性测试仪
  • <国外电子元器件>2008年第12期测控与仪器仪表 频率特性测试仪 施智强,何欣,唐铭杰,沈骋曦 (武汉大学电子信息学院,湖北武汉430079) 摘要:以集成的直接数字合成器(DDS)AD9851为核心,利用现场可编程门阵列(F ...查看


  • 基于51的频率计和温度计测量系统课程设计
  • 课程设计任务书 学生姓名: 专业班级: 通信1104班 指导教师: 艾青松 工作单位: 信息工程学院 题 目: 基于51的频率计和温度计测量系统 初始条件 1. 一台装有PROTEL 软件或以上版本的电脑及使用PROTEL 软件绘制电路原理 ...查看


  • FPGA频率计实验报告
  • 数字频率计 用VHDL 语言设计实现基于FPGA 的数字频率计 学校: 学院: 姓名: 学号: 实验室: 实验日期: 摘要 本文介绍了一种基于FPGA 的数字频率的实现方法.该设计采用硬件描述语言VHDL ,在软件开发平台ISE 上完成.该 ...查看


  • 电子信息工程毕业设计题目大全
  • 1 压力容器液位测量 2 多功能遥控小车 3基于RS232的仓库多点温度.湿度.气 4压检测系统 5自动控制升降旗系统 6基于RS485的温度报警系统 7基于模糊算法的水温控制系统的设计 8多分机电话交换机 9简易火灾自动报警系统 10基于 ...查看


  • 基于FPGA的乒乓球游戏参考毕业论文设计
  • 基于 XILINX-FPGA 的乒乓球游戏参考设计 一.背景: Xilinx 大学计划(xilinx university plan 简称 XUP)一直致力于为工程课程 提供新一代软件和硬件设计流程.全球数千所使用 Xilinx 系统进行教 ...查看


  • 频率特性测试仪的设计
  • 第17卷第2期 V01.17 No.2 电子设计工程 ElectronicDesignEngineering 2009年2月 Feb.2009 频率特性测试仪的设计 伍玉.夏新凡 (武汉大学电子信息学院,湖北武汉430079) 摘要:以89 ...查看


  • 基于单片机的恒温控制系统 1
  • 摘要:在工业生产中,电流.电压.温度.压力.流量.流速和开关量都是常用的主要被控参数.其中,温度控制也越来越重要.在工业生产的很多领域中,人们都需要对各类加热炉.热处理炉.反应炉和锅炉中的温度进行检测和控制.采用单片机对温度进行控制不仅具有 ...查看


  • 一种宽带数字信道化接收机
  • 2010年6月 第37卷 第3期 西安电子科技大学学报(自然科学版) JOUR NAL OF XIDI AN UNIV ER SI TY Jun. 2010 Vol. 37 No. 3 doi:10. 3969/j. issn. 1001 ...查看


热门内容