1.软件版本

matlab2013b,quartusii121.

2.本算法理论知识

带通滤波器在数字幅频均衡功率放大器中一个重要的组成部分,在介绍带通滤波器之前,我们首先来详细介绍一下数字幅频均衡功率放大器。

本系统要求的指标为:

本题要求在输入电压有效值为5mV的条件下,放大倍数达到400倍。而且20Hz到20kHz衰减不能超过1dB。-1 dB转化为信号幅值变化为11%,可以说指标要求很高。我们可以选择使用PGA或AD620实现这一指标。

整个系统的基本结构如下所示:

图1 系统总提结构框图

根据以上分析,系统的整体框图如图1所示。输入信号首先通过前置放大电路放大到一定幅度,经过带阻网络后,信号的幅频特性发生变化。由于AD输入幅度限制,信号先经过衰减网络衰减两倍,再经过抗混叠滤波并使用AD对输入信号进行采样,将采样结果送入FPGA做幅频均衡。最后通过DA输出并滤波,经过D类功放后即可得到大功率信号。

·前置放大电路的设计

输入信号电压放大倍数不小于400倍,单级运放的放大倍数难以做到这么高,所以采用两级运放的形式来做前级放大。由于系统频率为20Hz~20kHz,所以选用OP27运放完成电路。

·抗混叠滤波器电路设计

根据采样定理,为了使采样信号不发生频域混叠,必须在A/D采样电路的前端加入抗混叠滤波器电路,滤波器截止频率为采样频率的一半。由于本系统主要处理20kHz以内的信号,所以选用开关电容滤波器LTC1068—25设计一个八阶椭圆滤波器,其截至频率为25kHz。

·A/D采样电路的设计

根据题目的指标及系统频率的要求,我们需要一款采样率超过40KHz的采样芯片。AD9223是一款12bits、最高采样频率10MHz的性能优良的AD采样器件,由于以前使用过该芯片,为了更快的完成题目,所以选用AD9223作为采样芯片。

·数字幅频均衡模块设计

数字幅频均衡模块的原理图如图4-3所示,如果要实现对带阻网络的完全补偿,那么FIR滤波器应与带阻网络互为逆系统.带阻网络的系统函数可以通过点频法测得,然后使用MATLAB求出加窗后FIR滤波器应该具有的单位脉冲响应。因为FIR系统具有线性相位特性,所以由其幅频响应就可以求得其系统函数。

图2 数字幅频均衡模块的原理图

·D/A输出电路设计

根据题目的指标及系统频率的要求,我们需要一款频率超过40KHz的模数输出芯片。DAC904是一款14bits、最高采样频率165MHz的的DA器件,由于以前使用过该芯片,所以仍选用DAC904作为数模输出芯片。

·功率放大电路设计

D类功放第一部分为调制器,输入信号接比较器的正输入端,与三角波相比较。当正端上的电位高于负端三角波电位时,比较器输出为高电平,反之则输出低电平。这样,比较器输出的波形就是一个脉冲宽度被音频信号幅度调制后的波形,称为SPWM波。D类功放后级输出电路是一个脉冲控制的大电流开关放大器,正半周期比较器输出高电平,MOSFET晶体管Q1导通,且Q2截止,负半周期比较器输出高电平Q2导通,且Q1截止,这样它就把比较器输出的PWM信号变成高电压、大电流的大功率PWM信号,最后只需要通过一个二阶低通滤波器就可以把声音信息还原出来。

3.部分源码

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
entity tb_firs is
--START MEGAWIZARD INSERT CONSTANTSconstant FIR_INPUT_FILE_c  : string := "firs_input.txt";constant FIR_OUTPUT_FILE_c : string := "firs_output.txt";constant NUM_OF_CHANNELS_c        : natural := 1;constant DATA_WIDTH_c             : natural := 16;constant CHANNEL_OUT_WIDTH_c      : natural := 0;constant OUT_WIDTH_c              : natural := 35;constant COEF_SET_ADDRESS_WIDTH_c : natural := 0;constant COEF_RELOAD_BIT_WIDTH_c  : natural := 35;--END MEGAWIZARD INSERT CONSTANTS
end entity tb_firs;--library work;
--library auk_dspip_lib;-------------------------------------------------------------------------------architecture rtl of tb_firs issignal ast_sink_data    : std_logic_vector (DATA_WIDTH_c-1 downto 0) := (others => '0');signal ast_source_data  : std_logic_vector (OUT_WIDTH_c-1 downto 0);signal ast_sink_error   : std_logic_vector (1 downto 0)              := (others => '0');signal ast_source_error : std_logic_vector (1 downto 0);signal ast_sink_valid   : std_logic                                  := '0';signal ast_source_valid : std_logic;signal ast_source_ready : std_logic                                  := '0';signal clk            : std_logic := '0';signal reset_testbench        : std_logic := '0';signal reset_design   : std_logic;signal eof            : std_logic;signal ast_sink_ready : std_logic;signal start : std_logic;signal cnt   : natural range 0 to NUM_OF_CHANNELS_c;constant tclk           : time := 10 ns;constant time_lapse_max : time := 60 us;signal time_lapse       : time;function div_ceil(a : natural; b : natural) return natural isvariable res : natural := a/b;beginif res*b /= a thenres := res +1;end if;return res;end div_ceil;function to_hex (value : in signed) return string isconstant ne     : integer        := (value'length+3)/4;constant NUS    : string(2 to 1) := (others => ' ');  variable pad    : std_logic_vector(0 to (ne*4 - value'length) - 1);variable ivalue : std_logic_vector(0 to ne*4 - 1);variable result : string(1 to ne);variable quad   : std_logic_vector(0 to 3);beginif value'length < 1 thenreturn NUS;elseif value (value'left) = 'Z' thenpad := (others => 'Z');elsepad := (others => value(value'high));             end if;ivalue := pad & std_logic_vector (value);for i in 0 to ne-1 loopquad := To_X01Z(ivalue(4*i to 4*i+3));case quad iswhen x"0"   => result(i+1) := '0';when x"1"   => result(i+1) := '1';when x"2"   => result(i+1) := '2';when x"3"   => result(i+1) := '3';when x"4"   => result(i+1) := '4';when x"5"   => result(i+1) := '5';when x"6"   => result(i+1) := '6';when x"7"   => result(i+1) := '7';when x"8"   => result(i+1) := '8';when x"9"   => result(i+1) := '9';when x"A"   => result(i+1) := 'A';when x"B"   => result(i+1) := 'B';when x"C"   => result(i+1) := 'C';when x"D"   => result(i+1) := 'D';when x"E"   => result(i+1) := 'E';when x"F"   => result(i+1) := 'F';when "ZZZZ" => result(i+1) := 'Z';when others => result(i+1) := 'X';end case;end loop;return result;end if;end function to_hex;
beginDUT : entity work.firsport map (clk                => clk,reset_n            => reset_design,ast_sink_ready     => ast_sink_ready,ast_sink_data      => ast_sink_data,ast_source_data    => ast_source_data,ast_sink_valid     => ast_sink_valid,ast_source_valid   => ast_source_valid,ast_source_ready   => ast_source_ready,ast_sink_error   => ast_sink_error,ast_source_error => ast_source_error);-- for example purposes, the ready signal is always asserted.ast_source_ready <= '1';-- no input errorast_sink_error <= (others => '0');-- start valid for first cycle to indicate that the file reading should start.start_p : process (clk, reset_testbench)beginif reset_testbench = '0' thenstart <= '1';elsif rising_edge(clk) thenif ast_sink_valid = '1' and ast_sink_ready = '1' thenstart <= '0';end if;end if;end process start_p;------------------------------------------------------------------------------------------------- Read input data from file                                                                 -----------------------------------------------------------------------------------------------source_model : process(clk) isfile in_file     : text open read_mode is FIR_INPUT_FILE_c;variable data_in : integer;variable indata  : line;beginif rising_edge(clk) thenif(reset_testbench = '0') thenast_sink_data  <= std_logic_vector(to_signed(0, DATA_WIDTH_c)) after tclk/4;ast_sink_valid <= '0' after tclk/4;eof            <= '0';elseif not endfile(in_file) and (eof = '0') theneof <= '0';if((ast_sink_valid = '1' and ast_sink_ready = '1') or(start = '1'and not (ast_sink_valid = '1' and ast_sink_ready = '0'))) thenreadline(in_file, indata);read(indata, data_in);ast_sink_valid <= '1' after tclk/4;ast_sink_data  <= std_logic_vector(to_signed(data_in, DATA_WIDTH_c)) after tclk/4;elseast_sink_valid <= '1' after tclk/4;ast_sink_data  <= ast_sink_data after tclk/4;end if;elseeof            <= '1';ast_sink_valid <= '0' after tclk/4;ast_sink_data  <= std_logic_vector(to_signed(0, DATA_WIDTH_c)) after tclk/4;end if;end if;end if;end process source_model;----------------------------------------------------------------------------------------------- Write FIR output to file                                               ---------------------------------------------------------------------------------------------sink_model : process(clk) isfile ro_file   : text open write_mode is FIR_OUTPUT_FILE_c;variable rdata : line;variable data_r : string(div_ceil(OUT_WIDTH_c,4) downto 1);beginif rising_edge(clk) thenif(ast_source_valid = '1' and ast_source_ready = '1') then-- report as hex representation of integer.data_r := to_hex(signed(ast_source_data));write(rdata, data_r);writeline(ro_file, rdata);end if;end if;end process sink_model;
-------------------------------------------------------------------------------
-- clock generator
-------------------------------------------------------------------------------      clkgen : processbegin  -- process clkgenif eof = '1' thenclk <= '0';assert FALSEreport "NOTE: Stimuli ended" severity note;wait;elsif time_lapse >= time_lapse_max thenclk <= '0';assert FALSEreport "ERROR: Reached time_lapse_max without activity, probably simulation is stuck!" severity Error;wait;      elseclk <= '0';wait for tclk/2;clk <= '1';wait for tclk/2;end if;end process clkgen;monitor_toggling_activity : process(clk, reset_testbench,ast_source_data, ast_source_valid)beginif reset_testbench = '0' thentime_lapse <= 0 ns;elsif ast_source_data'event or ast_source_valid'event thentime_lapse <= 0 ns;elsif rising_edge(clk) thenif time_lapse < time_lapse_max thentime_lapse <= time_lapse + tclk;end if;end if;end process monitor_toggling_activity;-------------------------------------------------------------------------------
-- reset generator
-------------------------------------------------------------------------------reset_testbench_gen : processbegin  -- process resetgenreset_testbench <= '1';wait for tclk/4;reset_testbench <= '0';wait for tclk*2;reset_testbench <= '1';wait;end process reset_testbench_gen;reset_design_gen : processbegin  -- process resetgenreset_design <= '1';wait for tclk/4;reset_design <= '0'; wait for tclk*2;reset_design <= '1';wait for tclk*80;reset_design <= '1';wait for tclk*128*2;reset_design <= '1';wait;end process reset_design_gen;-------------------------------------------------------------------------------
-- control signals
-------------------------------------------------------------------------------end architecture rtl;

4.仿真结论

我们在MATLAB中对该IIR滤波器进行验证。代码如下所示:

b=[1 -1.8986 08991];

a=[2 -3.192 1.193];

[h1,f1]=freqz(b,a,100,1000000);

plot(f1,20*log10(abs(h1)));

其仿真波形如下所示:

图3 IIR滤波器的特性曲线

从上图可以看到,其通带是从0开始的,虽然在整个通带范围20~20k中20hz误差很小,但是IIR由于本身的缺陷,并不能满足要求。

·基于FIR的方案验证

其代码如下所示:

fs=200000;

wn1=[0.02 0.2];

b = fir1(1024,wn1,'DC-0');

freqz(b,1,1024,fs);axis([0,30000,-100,30]);grid;

title('设计的FIR带通滤波器');

其仿真结果如下所示:

图4 带通FIR滤波器仿真图

这里由于20hz的起始带通频率非常低,为了能使仿真效果能够明显点,这里通带频率为2K~20K。在实际使用的时候:

图5 带通FIR滤波器仿真图

由此可见,采用FIR滤波器可以达到设计要求。

其仿真结果如下所示:

5.参考文献

[01]Mark Zwolinski.VHDL数字系统设计[M].电子工业出版社.2004

[02]褚振勇,翁木云.FPGA设计及应用.西安电子科技大学出版社[M].2002

[03]李玉山,来新泉.电子系统集成设计技术[M].电子工业出版社.2002.A25-15

【幅频均衡带通滤波器】基于FPGA的幅频均衡带通滤波器的设计相关推荐

  1. 基于FPGA的简易DDS信号发生器的设计与验证

    基于FPGA的简易DDS信号发生器的设计与验证 一,理论介绍 补充:举例理解 二,代码实现 1,实验目标 2,MATLAB代码 3,verilog代码及实现思路 一,理论介绍 DDS 是直接数字式频率 ...

  2. 基于FPGA的简易DDS信号发生器的设计(一)

    写这篇文章的本意不是为了探讨AD9767怎么使用,因为9767的控制实在是太简单了,准备好数据直接输出即可,和网上大多数的并行DA输出基本上一模一样,更麻烦的反而是硬件方面.发文的原因是最近一位很细心 ...

  3. 基于FPGA的CAN总线控制器的设计(下)

    今天给大侠带来基于FPGA的CAN总线控制器的设计,由于篇幅较长,分三篇.今天带来第三篇,下篇,程序的仿真与测试以及总结.话不多说,上货. 导读 CAN 总线(Controller Area Netw ...

  4. 基于 FPGA 的模拟 I²C协议设计(中)

    今天给大侠带来基于FPGA的 模拟 I²C 协议设计,由于篇幅较长,分三篇.今天带来第二篇,中篇,I²C 协议的具体实现.话不多说,上货. 之前也有相关文章介绍,这里超链接一下,仅供各位大侠参考. 源 ...

  5. 基于FPGA的双路低频信号发生器设计

    基于FPGA的双路低频信号发生器设计 系统结构框 本设计是以Altera公司的可编程芯片做载体,运用Verilog作为软件设计工具,从而实现DDS原理,即信号发生器的核心思想.再加上信号发生器的硬件电 ...

  6. 基于FPGA的除法器原理介绍及设计实现

    基于FPGA的除法器原理介绍及设计实现 引言应用 在FPGA的设计应用领域里,许多电路需要用到除法器,而在硬件描述语言里却没有直接的除法器"%","/"可以直接 ...

  7. 基于FPGA的CAN总线控制器的设计(上)

    今天给大侠带来基于FPGA的CAN总线控制器的设计,由于篇幅较长,分三篇.今天带来第一篇,上篇,CAN 总线协议解析以及 CAN 通信控制器程序基本框架.话不多说,上货. 导读 CAN 总线(Cont ...

  8. 基于FPGA的音频处理芯片的设计

    基于FPGA的音频处理芯片的设计 时间:2009-01-07 10:00:18 来源:维库电子市场 作者:刘虹 黄涛 徐成 1 引言 随着数字技术日益广泛的应用,以现场可编程门阵列FPGA(Field ...

  9. 基于FPGA的幅频均衡带通滤波器的设计

    目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 数字通信系统中,由于多径传输.信道衰落等影响,在接收端会产生严重的码间干扰,增大误码率.为了克服码间 ...

  10. 源码系列:基于FPGA的数字电压表(AD)设计

    今天给大侠带来基于FPGA的数字电压表设计,附源码,获取源码,请在"FPGA技术江湖"公众号内回复"数字电压表设计源码",可获取源码文件.话不多说,上货. 设计 ...

最新文章

  1. 基本CSS选择器,复合选择器,后代选择器
  2. 怎么给el-select两级联动赋值_医保改革:支付范围、支付标准、支付方式的联动,大有可为...
  3. 本来中午打算应付下随便吃点,可是连盐都没有放的辣椒炒蛋实在是令人不快...
  4. [剑指offer]面试题第[58]题[Leetcode][JAVA][第151题][翻转单词][字符串常用函数总结]
  5. 20.校准相机——纯粹的方式,简单的方式,多平面校准_4
  6. 二叉树层次遍历--广度遍历和深度遍历
  7. 为JavaScript日期添加天数
  8. 产品经理是“通”才还是“专”才
  9. ASP.NET面试题(推荐_有答案)
  10. axis2远程调用webservice例子(返回xml用dom4j解析)
  11. Exchange 2013学习(九),Autodiscover
  12. python椭圆花瓣_Python抓取花瓣网高清美图
  13. 2021年安徽无为中学高考成绩查询,安徽省无为中学2021届高三年级这些学生,被表彰了...
  14. excel表格换行快捷键_excel常用快捷键分享
  15. 严重: Unable to set localhost. This prevents creation of a GUID. Cause was: springtest: springtest
  16. linux中cpu_to_be32,Linux cpufreq framework(2)
  17. 哪些原因会导致头晕头痛,日常应该如何去注意呢?
  18. Unity模型动画骨骼错位解决办法
  19. ubuntu16.04挂载三星T5移动硬盘报错
  20. ImageMagick再爆严重漏洞,可导致雅虎邮箱用户邮件内容泄漏

热门文章

  1. 与孩子一起学编程01章
  2. 集体智慧编程--优化
  3. android实现简单进度条ProgressBar
  4. Quartus II 15详细安装教程
  5. vs2017官方下载路径
  6. CMMI5 2.0版本是什么 做什么
  7. 小程序调用API服务
  8. 三维重建之环境搭建1-VS2017安装
  9. redis的管理和监控工具treeNMS
  10. 金蝶oracle用鼎信诺取数,取数软件 审计取数软件?