第7章数字系统设计实例第7章数字系统设计实例7.1半整数分频器的设计7.2音乐发生器7.32FSK/2PSK信号产生器7.4实用多功能电子表7.5交通灯控制器7.6数字频率计习题第7章数字系统设计实例7.1半整数分频器的设计在数字系统设计中,分频器是一种基本电路。分频器的实现非常简单,可采用标准的计数器,也可采用可编程逻辑器件来实现一个整数分频器。分频器通常用来对某个给定频率进行分频,得到所需的频率。在某些场合下,用户所需要的频率与频率时钟源不是整数倍关系,此时可采用小数分频器进行分频。第7章数字系统设计实例7.1.1小数分频的基本原理设有一个5MHz的时钟源,但电路中需要产生一个2MHz的时钟信号,由于分频比为2.5,因此整数分频器将不能胜任。采用可编程逻辑器件实现分频系数为2.5的分频器,可采用以下方法:设计一个模3的计数器,再设计一个扣除脉冲电路,加在模3计数器输出之后,每来两个脉冲就扣除一个脉冲(实际上是使被扣除的脉冲变成很窄的脉冲,可由异或门实现),就可以得到分频系数为2.5的小数分频器。采用类似方法,可以设计分频系数为任意半整数的分频器。第7章数字系统设计实例小数分频的基本原理为脉冲吞吐计数法:设计两个不同分频比的整数分频器,通过控制单位时间内两种分频比出现的不同次数,从而获得所需的小数分频值。例如设计一个分频系数为10.1的分频器,可以将分频器设计成9次10分频,1次11分频,这样总的分频值为(9×10+1×11)/(9+1)=10.1第7章数字系统设计实例从这种实现方法的特点可以看出,由于分频器的分频值在不断改变,因此分频后得到的信号抖动较大。当分频系数为N-0.5(N为整数)时,可控制扣除脉冲的时间,使输出为一个稳定的脉冲频率,而不是一次N分频,一次N-1分频。第7章数字系统设计实例7.1.2电路组成设需要设计一个分频系数为N-0.5的分频器,其电路可由一个模N计数器、一个二分频器和一个异或门组成,如图7-1所示。在实现时,模N计数器可设计成带预置的计数器,这样就可以实现任意分频系数为N-0.5的分频器。第7章数字系统设计实例图7-1通用半整数分频器异或门模N计数器f0/(N-0.5)二分频器f0/(2N-1)f0第7章数字系统设计实例7.1.3VHDL程序LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYdeccountISPORT(inclk:INSTD_LOGIC;--时钟源preset:INSTD_LOGIC_VECTOR(3DOWNTO0);--预置分频值N第7章数字系统设计实例outclk1:OUTSTD_LOGIC;outclk2:BUFFERSTD_LOGIC--输出时钟);ENDdeccount;ARCHITECTUREdeccount_archOFdeccountISSIGNALclk,divide2:STD_LOGIC;SIGNALcount:STD_LOGIC_VECTOR(3DOWNTO0);第7章数字系统设计实例BEGINclk=inclkXORdivide2;--inclk与divide2异或后作为模N计数器的时钟outclk1=inclk;PROCESS(clk)BEGINIF(clk'eventANDclk='1')THENIF(count=0000)THEN第7章数字系统设计实例count=preset-1;--置整数分频值Noutclk2='1';ELSEcount=count-1;--模N计数器减法计数outclk2='0';ENDIF;ENDIF;ENDPROCESS;PROCESS(outclk2)第7章数字系统设计实例BEGINIF(outclk2'eventANDoutclk2='1')THENdivide2=NOTdivide2;--输出时钟二分频ENDIF;ENDPROCESS;ENDdeccount_arch;第7章数字系统设计实例图7-2半整数分频器外部接口INCLKPRESET[3..0]OUTCLK1OUTCLK2第7章数字系统设计实例以上程序实现对时钟源inclk进行分频系数为N-0.5的分频,得到输出频率outclk2。preset输入端口是预置分频值N,本例中preset设为4位宽的位矢量,也即分频系数为16以内的半整数值。若分频系数大于16,需同时增大preset和count的位宽,两者的位宽则要求始终一致。本设计的外部接口如图7-2所示,程序中设置outclk1是为了方便观察输入信号的波形,以与输出信号outclk2比较。第7章数字系统设计实例7.1.4仿真结果上述半整数分频器的仿真波形如图7-3所示。第7章数字系统设计实例图7-3半整数分频器仿真波形图第7章数字系统设计实例7.1.5下载验证锁定引脚时将inclk连至CLK1,preset连至K0~K3,outclk1连至TESTOUT1(测试1脚),outclk2连至TESTOUT2(测试2脚),综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号,请参见附录的附图1),通过改变K0~K3状态观察测试1脚和测试2脚上的波形,测试结果与仿真结果一致。第7章数字系统设计实例7.2音乐发生器本设计利用可编程逻辑器件配以一个小扬声器设计了一个音乐发生器,其结构如图7-4所示。本例产生的音乐选自“梁祝”片段。第7章数字系统设计实例图7-4音乐产生器原理框图预置计数器初始计数值乐谱产生器二分频音名译扬声器数码管4MHz4Hz第7章数字系统设计实例7.2.1音名与频率的关系音乐的十二平均率规定:每两个八度音(如简谱中的中音1与高音1)之间的频率相差一倍。在两个八度音之间,又可分为十二个半音,每两个半音的频率比为。另外,音名A(简谱中的低音6)的频率为440Hz,音名B到C之间、E到F之间为半音,其余为全音。由此可以计算出简谱中从低音1至高音1之间每个音名的频率如表7-1所示。第7章数字系统设计实例表7-1简谱中的音名与频率的关系音名频率/Hz音名频率/Hz音名频率/Hz低音1261.63中音1523.25高音11046.50低音2293.67中音2587.33高音21174.66低音3329.63中音3659.25高音31318.51低音4349.23中音4698.46高音41396.92低音5391.99中音5783.99高音51567.98低音6440中音6880高音61760低音7493.88中音7987.76高音71975.52第7章数字系统设计实例由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。若基准频率过低,则由于分频系数过小,四舍五入取整后的误差较大。若基准频率过高,虽然误码差变小,但分频结构将变大。实际的设计应综合考虑两方面的因素,在尽量减小频率误差的前提下取合适的基准频率。本例中选取4MHz的基准频率。若无4MHz的时钟频率,则可以先分频得到4MHz或换一个新的基准频率。实际上,只要各个音名间的相对频率关系不变,C作1与D作1演奏出的音乐听起来都不会“走调”。第7章数字系统设计实例本例需要演奏的是“梁祝”片段,此片段内各音阶频率及相应的分频比如表7-2所示。为了减小输出的偶次谐波分量,最后输出到扬声器的波形应为对称方波,因此在到达扬声器之前,有一个二分频的分频器。表7-2中的分频比就是从4MHz频率二分频得到的2MHz频率基础上计算得出的。第7章数字系统设计实例表7-2各音阶频率对应的分频值音名分频系数初始值音名分频系数初始值低音360672124中音234054786低音551023089中音330345157低音645453646中音525515640低音740504141中音622735918中音138224369高音119116280第7章数字系统设计实例由于最大的分频系数为6067,故采用13位二进制计数器已能满足分频要求。在表7-2中,除给出了分频比以外,还给出了对应于各个音阶频率时计数器不同的初始值。对于不同的分频系数,只要加载不同的初始值即可。采用加载初始值而不是将分频输出译码反馈,可以有效地减少本设计占用可编程逻辑器件的资源,这也是同步计数器的一个常用设计技巧。对于乐曲中的休止符,只要将分频系数设为0,即初始值为213-1=8191即可,此时扬声器将不会发声。第7章数字系统设计实例7.2.2音长的控制本例演奏的“梁祝”片段,最小的节拍为1/4拍。将1拍的时长定为1秒,则只需要再提供一个4Hz的时钟频率即可产生1/4拍的时长。演奏的时间控制通过记谱来完成,对于占用时间较长的节拍(一定是1/4拍的整数倍),如2/4拍,只需将该音名连续记录两次即可。本例要求演奏时能循环进行,因此需另外设置一个时长计数器,当乐曲演奏完成时,保证能自动从头开始演奏。第7章数字系统设计实例7.2.3演奏时音名的动态显示如果有必要,可以通过一个数码管或LED来显示乐曲演奏时对应的音符。如用三个数码管,分别显示本例中的高、中、低音名,就可实现演奏的动态显示,且十分直观。本设计通过三个数码管来动态显示演奏时的音名,其中HIGH显示为高音区音阶(仅高音1),MED[2..0]显示的是中音区音阶(中音6,5,3,2,1),LOW[2..0]显示的是低音区音阶(低音7,6,5,3)。数码管显示的七段译码电路在此不作专门讨论。需要说明的是,七段译码电路输入为4位,而将HIGH、MED、LOW用作输入时,不足4位的高位均为低电平“0”。第7章数字系统设计实例图7-5音乐产生器外部接口CLK_4MHzCLK_4HzDIGIT[6..0]ZERO[4..0]SPEAKER第7章数字系统设计实例7.2.4VHDL程序本设计的外部接口如图7-5所示,程序中定义了一个5位宽的zero[4..0],这是由于实验平台上连向数码管的引脚在不赋值的情况下为高电平,这将导致显示音名错误,设置zero[4..0]就是要将没用到的引脚(高音的高3位、中音的高1位和低音的高1位)赋一个低电平,从而避免显示错误。第7章数字系统设计实例LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;USEIEEE.STD_LOGIC_UNSIGNED.ALL;ENTITYsongISPORT(clk_4MHz,clk_4Hz:INSTD_LOGIC;--预置计数器和乐谱产生器的时钟第7章数字系统设计实例digit:BUFFERSTD_LOGIC_VECTOR(6DOWNTO0);--高、中、低音数码管指示zero:OUTSTD_LOGIC_VECTOR(4DOWNTO0);--用于数码管高位置低speaker:outSTD_LOGIC--扬声器);ENDsong;ARCHITECTUREsong_archOFsongIS第7章数字系统设计实例SIGNALdivider,origin:STD_LOGIC_VECTOR(12DOWNTO0);--13位计数值和预置值SIGNALcounter:integerrange0to140;--7位计数器SIGNALcount:STD_LOGIC_VECTOR(1DOWNTO0);--记录1/4拍SIGNALcarrier:STD_LOGIC;BEGINzero=00000;PROCESS(clk_4MHz)第7章数字系统设计实例BEGINIF(clk_4MHz'eventANDclk_4MHz='1')THENIF(divider=1111111111111)THENcarrier='1';divider=origin;ELSEdivider=divider+'1';carrier='0';ENDIF;ENDIF;ENDPROCESS;第7章数字系统设计实例PROCESS(carrier)BEGINIF(carrier'eventANDcarr