PWM信号发生器的研制
前言
脉冲宽度调制(Pulse Width Modulation.PWM)控制技术以其控制简单、灵活和动态响应好的优点而成为电力电子技术和模拟信号数字传输通信领域最广泛应用的控制方式,因此研究基于PWM技术的脉冲宽度及周期可调的信号发生器具有十分重要的现实意义。
本文主要讨论了脉冲占空比可调信号的产生方法,采用三种不同的方案使用VHDL语言编程实现了信号的产生。其中方案一的原理是分频,即用计数器计算时钟脉冲的上升沿个数,再通过输出电平反复翻转得到计数个数(脉冲宽度)可控的PWM信号;方案二的原理是锯齿波比较法,首先编程产生阶梯状的锯齿波,再通过锯齿波与输入占空比值(数值可控的直线)比较产生脉冲宽度随输入占空比数值变化的PWM信号;方案三是用有限状态机产生有用信号,首先定义两个状态,再通过计数器值与输入占空比值比较控制状态的切换,产生PWM信号。本文详细介绍方案二和方案三两种方法。
通过使用QuartusII9.0软件采用VHDL语言编程并用功能仿真证实了上文提到的三种PWM信号产生方案都是可行的,都能产生切实可用的PWM信号,三种方案中均可以通过修改输入端口占空比来控制产生信号的脉宽,且可以通过在程序中修改计数器的计数上限和分频模块的分频比改变信号的周期及频率,实现了多参数可调,使整体设计具有灵活的现场可更改性和较好的可移植性。且实现功能的程序简单易懂,设计过程中思路阐述清晰,流程介绍明了,且程序易于修改,可读性好。
1
PWM信号发生器的研制
第一章 设计要求
1.1 研究课题
PWM信号发生器的研制
1.2设计要求
用CPLD可编程模块产生下列信号(特殊芯片:EPM570T100C5) (1) 采用VHDL编写相关程序,PWM信号的工作频率为500Hz(1000Hz); (2) 时钟信号通过分频器后,由输入开关量控制占空比可调。
2
PWM信号发生器的研制
第二章 系统组成及工作原理
本次设计采用的是Altera公司开发的QuartusII设计平台,设计采用特殊芯片EPM570T100C5进行仿真,在原理设计方面,本设计采用自顶向下、层次化、模块化的基本程序设计思想,这种设计思想的优点符合人们先抽象后具体,先整体后局部的思维习惯,其设计出的模块修改方便,不影响其他模块,且可重复使用,利用率高。
2.1 系统组成
为了使本次设计产生的PWM信号能用于频率稳定度高的晶振,故在系统设计中添加了一个分频模块,因此PWM信号发生器由分频器和信号发生器两个部分组成。其组成框图如图2.1所示
clk信号(ns)分频器clk信号(ms)PWM信号发生器pwm信号图2.1 PWM信号产生框图
2.2 系统设计流程图
PWM信号发生器的总体设计流程图如图2.2所示:
开始分频模块对输入时钟进行分频Y复位信号有效?N输出为 0PWM信号发生器输出PWM信号结束
图2.2 系统设计流程图
3
PWM信号发生器的研制
2.3 系统工作原理
如上图的框图所示,输入是纳秒(ns)级的高频时钟信号,经过分频模块后产生毫秒(ms)级的低频时钟,然后由低频时钟控制信号发生器,产生一定周期的矩形波,再经过具体的设计形成占空比可调的PWM信号。
本次设计中,设计要求是产生1KHz的脉冲宽度可调的矩形信号,仿真中输入时钟clk的周期为10ns,经过1000分频器后变成周期为10us(频率为0.1MHz)的时钟,再通过信号发生器模块中的计数上限为100计数器,产生周期为1ms(频率为1KHz)的周期矩形信号,再有输入端口控制占空比,产生宽度可调的PWM信号,实现设计要求的功能。
4
PWM信号发生器的研制
第三章 模块的具体实现
3.1 分频模块的设计
3.1.1 基本设计思想
分频实际就是一个计数的过程,通过计数个数来控制输出高低电平的时间,最重要的是高低电平的维持时间相等,即产生方波信号。
3.1.2 设计流程图
使用时钟分频方法产生可用时钟频率的设计流程图如图3.1所示:
开始每来一个时钟上升沿计数器加1计数器值>500?Y输出为 0NN计数器值>=999?Y计数器清零输出为 1结束
图3.1 设计流程图
3.1.3 主要程序代码
if clkin='1' and clkin'event then --时钟上升沿触发 if count=1000 then count:=0; --计数计到999则清零
5
PWM信号发生器的研制
elsifcount<=500 then clkout<='1'; --计数到500电平翻转 elseclkout<='0'; end if;
count:=count+1; --时钟上升沿计数 end if;
3.1.4模块工作原理
定义实体之后,在由输入时钟(ns)触发的进程中实现分频,首先定义一个中间计数变量,当计算输入时钟上升沿个数从0至500时输出高电平,从500至1000时输出低电平,从而产生周期为输入信号1000倍的方波信号,分频比可由下式得到:
A= To ÷Ti (3.1)
其中,To为输出时钟的周期,Ti为输入时钟的周期
3.2 用锯齿波比较法生成PWM信号
3.2.1 基本设计思想
锯齿波比较法生成占空比不同且一个波形中周期固定的PWM信号的思想来源于锯齿波自身具有的独特性质:斜率单一、周期固定、用斜率为0的直线与之相切割所得波形周期一定,因此,将希望得到的波形的占空比值作为输入决定与锯齿波相割的直线,可得到周期相等的矩形波,改变输入占空比即改变直线的幅值就可以改变信号的脉冲宽度,其基本原理如图3.2所示:
图3.2 锯齿波比较法产生脉宽可调波的原理
6
PWM信号发生器的研制
3.2.2 设计流程图
(1)锯齿波发生器设计的流程图如图3.3所示:
开始Y复位信号有效?N每来一个时钟上升沿锯齿波幅值加1N锯齿波的最大幅值>100?Y锯齿波的幅值赋0结束
图3.3 锯齿波发生器的流程
(2)锯齿波比较法产生PWM信号的流程图如图3.4所示:
开始YN占空比值大于锯齿波的值?输出为 1结束输出为 0 图3.4 锯齿波比较法产生PWM信号流程图
3.2.3 主要程序代码 ifrst = '0' then
7
PWM信号发生器的研制
saw_teeth<=\"0000000\"; --异步复位 elsifclk'event and clk = '1' then
saw_teeth<=saw_teeth+1; --产生阶梯状的锯齿波 ifsaw_teeth>=\"1100011\" then
saw_teeth<=\"0000000\"; --锯齿波的最大幅值为100 end if; end if;
pwm<='1' when perc>saw_teeth else --锯齿波与常数信号相比较,产生占空比由常
--数(perc)决定的pwm信号
'0' when perc<= saw_teeth;
3.2.4 模块工作原理
锯齿波比较法产生PWM信号的程序结构体中含有一个产生锯齿波的进程,该锯齿波的周期为100,对应到占空比的取值范围0-100,且锯齿波的幅值最大为100,因此当输入的占空比值大于等于100时,输出全高电平波形,同理,当输入占空比值小于等于0时,输出全低电平波形,所以,当输入的占空比值处于正常允许的范围时,对应于图3.2所示的占空比直线切割锯齿波,由于产生锯齿波的时钟与系统同步,从而使产生的PWM信号的脉宽严格对应于输入的占空比值,这样就可以使PWM信号的脉冲宽度精确可调,以达到实验目的。以下两种方法的占空比可用下式求得:
V= T1 ÷ T (3.2)
其中,T1为PWM信号一个周期中高电平持续的时间,T为PWM信号的周期
3.3 用有限状态机生成PWM信号
3.3.1 基本设计思想
考虑到设计所要的PWM信号一个周期之内只有两个不同的持续状态,故可以使用有限状态机来实现电平的切换,切换条件就是输入的占空比,一个状态就是一个电平,因此通过状态转换就可以实现电平的翻转,产生矩形波,再通过改变输入的占空比就可以改变生成信号的脉冲宽度。
3.3.2 设计流程图
用有限状态机设计PWM信号发生器的状态之间的转换及转换条件如图3.5所示:
8
PWM信号发生器的研制
计数器值>占空比值计数器值<=占空比值输出为 1st1st0占空比值<=计数器值<100输出为 0计数器值<占空比值图3.5 有限状态机方法产生PWM信号状态转换
有限状态机的进程分为两个,如图3.6所示即为有限状态机方法产生PWM信号流程图中的状态译码和输出译码部分流程图:
开始当前状态是st1?Y输出为 1N输出为 0计数器值>占空比值?N下一状态为st1计数器值>占空比值?Y下一状态为st0Y下一状态为st0N下一状态为st1
图3.6状态译码和输出译码进程流程图
图3.7所示为有限状态机产生PWM信号的第二个进程—时序逻辑进程的流程图:
9
PWM信号发生器的研制
开始Y计数器清0当前状态切换至st1复位信号有效?N每来一个时钟上升沿下一状态转换成当前状态计数器加1N计数器值>100?Y计数器清0结束
图3.7 时序逻辑进程流程图
3.3.3 主要程序代码
if reset='0' then count<=\"0000000\";current_state<=st1; --异步复位 elsif (clk'event and clk='1') then current_state<=next_state; --状态转换 count<=count+1;
if count>=\"1100100\" then count<=\"0000000\"; --计数器清零 end if;
process(current_state,count) --组合逻辑进程(状态译码和输出译码) case current_state is --确定当前状态的状态值 when st1=>pwm<='1'; --初始状态译码输出 if count if count>=perc and count<\"1100100\" then next_state<=st0; --转换到第二个状态 elsenext_state<=st1; 3.3.4 模块工作原理 一般有限状态机的结构体组成有两部分:时序进程和组合进程。时序进程(也叫状态转换)是指负责状态机运转和在时钟驱动下负责状态转换的进程,上述设计中时 10 PWM信号发生器的研制 序进程负责完成下一状态(next_state)向当前状态(current_state)的转换和计数器加1;组合进程(也叫状态译码和输出译码)的任务是根据外部输入的控制信号(包括来自状态机外部的信号和来自状态机内部其他信号),和当前状态的状态值确定下一状态(next_state)的去向,即next_state的取值内容,以及确定对外输出或对内部其他组合或时序进程输出控制信号的内容,上述设计中组合进程完成了一定条件下next_state转向st0或st1状态的功能以及在对应current_state下的相应输出(0或1)。 如图3.7所示,时序进程中在时钟clk的上升沿触发下进行状态转换和计数器加1。 如图3.6所示,组合进程完成状态译码和输出译码。如果current_state是st1,则输出为高电平‘1’,并且当计数器值大于输入占空比值时指定下一状态为st0,否则下一状态为st1;如果current_state是st0,则输出为低电平‘0’,并且当计数器值小于等于输入占空比值时指定下一状态为st1,否则下一状态为st0,这样就可以完成高低电平之间的转换了,从而可以改变输入占空比值来改变输出信号的脉冲宽度。 11 PWM信号发生器的研制 第四章 调试及结果分析 4.1程序调试仿真图及结果分析 4.1.1 千分频模块 为使仿真报告中显示多个周期的输出,需要修改终止时间,具体操作为:在.vwf界面单击Edit\\End Time,将Time 修改为1.0s. 在.vwf中设置clkin的周期为0.1ms,如图4.1所示: 图4.1 输入时钟设置 调试仿真图如图4.2和4.3所示: 图4.2 仿真运行结果(1) 图4.3 仿真运行结果(2) 在.vhd界面单击File\\Create/Update\\Create Symbol Files For Current File,则使得用VHDL语言编写的程序生成一个图元文件,成为一个可供原理图文件调用的元器件,使用时需将该图元文件所在工程中的各非文件夹文件复制到原理图所在工程的文件 12 PWM信号发生器的研制 夹下,然后就可以在原理图界面中选择元器件图标下的根目录Project,就可以找到该元件使用之。实验中生成的分频模块图元文件如图4.4所示: 图4.4 千分频模块图元文件 结果分析: 如上各图所示:clkin的周期:Ti = 100us =0.1ms clkout的周期起始值:to1 = 100.15ms clkout的周期终止值:to2 = 200.15ms 因此,clkout的周期:To = to2 - to1 = 100ms 由式3.1可知:分频比:A = To÷Ti = 1000 如上分析可知,分频模块达到了设计要求,可以将高频时钟分频成为低频时钟。 4.1.2 用锯齿波比较法生成PWM信号 新建工程和原理图文件后,按照上述方法使用生成的元器件,连线、修改输入输出端口名称,产生设计的顶层原理图,如图4.5所示: 图4.5 锯齿波比较法顶层原理图 注!占空比输入端口的名称必须改为perc[6..0],否则将出错。 当输入的占空比值perc=‘1000000’,即占空比为64%,其仿真结果如下各图所示: 13 PWM信号发生器的研制 图4.6仿真运行结果(1) 图4.7仿真运行结果(2) 图4.8仿真运行结果(3) 当输入perc=‘0001000’,即占空比为8%,其仿真结果如图4.9所示: 14 PWM信号发生器的研制 图4.9占空比为8%时的输出仿真结果 注! 仿真时复位信号rst必须置为高电平‘1’,否则输出全为‘0’。 结果分析: 由图4.7和4.8可知:clk的周期:tc = 10us = 0.01ms 一个周期PWM信号起始时间:t1= 995.0us 一个周期PWM信号起始时间:t2= 1.995ms = 1995.0us 因此:PWM信号的周期:T = t2 - t1 = 1ms 又因为高电平截止时间:t3 = 1.635ms 因此:高电平持续时间:T1 = t3 - t1 = 0.64ms 由式(3.2)可得占空比:V= T1 ÷T = (0.64÷1) ×100% = 64% 经过上述分析可知:PWM信号的频率为:f=1/T=1000Hz,与设计要求相符,此外占空比为64%,也与控制端输入的数值相符,再通过与图4.9比较,可知锯齿波比较法确实可以产生占空比任意(0%到100%之间)输入的PWM信号,而且一个波形中周期固定,是一个可行的方案。 4.1.3 用有限状态机生成PWM信号 用有限状态机方法设计信号发生器的顶层原理图如图4.10所示: 图4.10有限状态机法顶层原理图 15 PWM信号发生器的研制 当输入的占空比值perc=‘1000000’,即占空比为64%,其仿真结果如下图所示: 图4.11 占空比为64%时的仿真运行结果 当输入的占空比值perc=‘0001000’,即占空比为8%,其仿真结果如下图所示: 图4.12 占空比为8%时的仿真运行结果 结果分析: 通过与锯齿波比较法的对比可以发现,两种设计方法产生的结果是一样的,即有限状态机设计的PWM信号发生器也可以通过改变外部输入占空比值来控制输出PWM信号的脉冲宽度,且同一信号中周期固定,因此用有限状态机设计信号发生器也是一种行之有效的方案。 4.2 调试中出现的错误、原因及解决方法 (1)在设计分频器过程中,发现仿真计算后分频比达不到1000,而是999,同样 16 PWM信号发生器的研制 的,设计信号发生器时,仿真的结果也出现了信号周期与要求的周期和占空比总是少一个时钟脉冲的时间。 错误原因及解决:程序中有计数器的计数要求,例如:修改后的千分频程序中有语句elsif count<=500 then clkout<='1';若将count<=500改为count<500,则会出现分频比不对的结果,因为计数器还没有计到500就电平翻转了,肯定会出现高电平持续时间不够的现象,因此,在程序中有类似判断计数器的值然后选择电平跳变的情况时,应多留意电平跳变的临界值,此时应反复调试仿真,确保结果正确。 (2)在用锯齿波比较法设计信号发生器的程序的结构体中的比较部分使用语: ifperc>saw_teeth then pwm<='1'; elsifperc<= saw_teeth then pwm<='1';则在编译综合时系统提示错误:Error (10500): VHDL syntax error at pwm_signal_2.vhd(11) near text \"if\"; expecting \"end\an identifier (\"if\" is a reserved keyword), or a concurrent statement. 错误原因及解决:由于上述if语句直接写在结构体中,故会产生上述错误,因为if语句是顺序语句,只能在结构体的进程(process)或者子程序中使用,否则定会报错。所以在用VHDL语言编程过程中需要特别注意语句的使用规则,以保证程序正确有效。 (3)在观察设计信号发生器的仿真报告时发现本该是周期性波形的PWM输出信 号成了全高电平。 错误原因及解决:经过反复调试发现,仿真时输入的时钟是纳秒(ns)级别的,而仿真报告可显示的时间轴的单位也是纳秒(ns)级别的,而且最大时间是1000ns,即1us,由于信号发生器中都有千分频模块,因此要求正确显示多周期波形的时间轴应至少是ms的,故在时间轴为ns的情况下输出必定是全高电平,为了改变显示时间轴的单位,可以在.vwf界面单击Edit\\End Time,将Time 修改为1.0s。这样,就可以在程序正确的前提下使仿真结果清晰明了。 4.3使用VHDL语言编程的注意事项 (1)标识符的使用:标识符只能由大小写英文字母、数字0到9以及下划线‘_’组成,并且必须以字母开头,下划线‘_’不能两个及两个以上连用,标识符不能是保留字(关键字); (2)原理图中总线的表示:总线表示除了名称之外还有要标明总线宽度,例如:总线宽度为n,则宽度应表示为[n..0]; 17 PWM信号发生器的研制 (3)使用VHDL编程的操作流程:新建工程→新建vhdl文件.vhd→输入程序→编译综合→新建波形仿真文件.vwf→导入管脚→仿真,切记每次修改程序后必须综合,否则仿真必定会有问题; (4)程序包的定义:如果在程序中存在重载操作,如count<=count+1等,需要定义一个程序包:use ieee.std_logic_unsigned.all; (5)信号与变量的赋值区别:信号赋值用‘<=’,而变量赋值用‘:=’。 18 PWM信号发生器的研制 第五章 结论 本次课程设计是研制PWM信号发生器,PWM信号就是脉冲宽度可控的矩形信号,设计中涉及到的三种方案:分频、锯齿波比较和有限状态机都是VHDL语言实际应用很普遍的三种设计途径,其中,分频的核心思想是计数器在电平跳变时刻的临界计数值,是产生方波还是矩形波,都由计数值决定;锯齿波比较方案的选择是因为锯齿波与直线的比较可以产生周期固定的输出,如果将锯齿波改为三角波就达不到这种效果;有限状态机的选用主要是考虑到PWM信号一个周期内有有限个状态,可以将其一一列举出来,只要使各状态之间进行响应的转换和产生对应的输出就可以产生任意周期信号,而不仅仅只是PWM信号,比如用有限状态机还可以设计固定序列、m序列等信号发生器。 本课程设计的实现方式是软件编程,经过用VHDL语言和QuartusII软件设计PWM信号发生器,不难发现相对于硬件来说使用软件实现功能的优越性:首先,软件实现过程中有微小错误时可以反复修改,而硬件则不可以这么随意修改,因为一旦焊接好电路,则加上外部因素,不仅有误差,而且很难再修改了;其次,使用语言编程弹性大,可以有很大的延伸空间,实现方案也比较多,硬件实现则做不到这一点;最后,软件设计现象直观明了,测试相对硬件来讲比较简单。但是使用软件也有不好的方面,比如说软件编程都是程序编写着设计元件,则很容易让设计者忽略与当前流行芯片的接触和使用等,而且硬件操作可以锻炼一个人的耐心和细心等。 PWM信号发生器的研制具有实质性的意义,比如说,通过PWM可以实现AM、FM和SSB三种重要模拟通信信号的调制与解调,此外,脉冲宽度调制控制技术在电力电子装置中应用也十分广泛,因而研究PWM信号的产生对通信技术以及其他领域的发展具有重要意义。 19 PWM信号发生器的研制 参考文献 [1] 谭会生,张昌凡.EDA技术及应用[M].西安:西安电子科技大学出版社,2011 [2] 潘松,黄继业.EDA技术实用教程[M].北京:科技出版社,2002 [3] 甘历.VHDL应用与开发实践[M].北京:科学出版社,2003 [4] 朱正伟.EDA技术及应用[M].北京:清华大学出版社,2005.10 [5] 吴泽民,王俊,王景.利用单片机产生PWM信号的软件实现方法[J].机电技 术,2008,第1期 [6] 刘昌华.论VHDL语言的程序结构和描述风格[J].计算机与数字工程,2010,第12 期 [7] 樊昌信,曹丽娜.通信原理(第6版)[M].北京:国防工业出版社,2011.8 20 PWM信号发生器的研制 附录 程序清单及程序注释 (1)千分频模块 library ieee; --库的说明 use ieee.std_logic_1164.all; --程序包说明 entity fre_div_1k is --实体定义 port(clkin:instd_logic; clkout:outstd_logic); end entity; architecture behave of fre_div_1k is --结构体定义 begin process (clkin) --clkin的变化触发的进程 variable count:integer range 0 to 1000; --定义计数变量 begin ifclkin='1' and clkin'event then if count=1000 then count:=0; --计数计到1000则清零 elsif count<=500 then clkout<='1'; --计数到500电平翻转 elseclkout<='0'; end if; count:=count+1; --时钟上升沿计数 end if; end process; end behave; (2)锯齿波比较法设计PWM信号发生器 libraryieee; use ieee.std_logic_1164.all; useieee.std_logic_unsigned.all; entity pwm_signal_2 is port( rst:instd_logic; --复位信号,低电平有效 21 PWM信号发生器的研制 clk:instd_logic; perc:instd_logic_vector(6 downto 0); pwm: out std_logic); end entity; architecture behave of pwm_signal_2 is signal saw_teeth:std_logic_vector(6 downto 0); --实现锯齿波的产生信号 begin process( rst, clk ) --此进程由rst和clk的变化共同触发 begin ifrst = '0' then saw_teeth<=\"0000000\"; --异步复位 elsifclk'event and clk = '1' then saw_teeth<=saw_teeth+1; --产生幅值逐次+1的阶梯状锯齿波 if saw_teeth>=\"1100100\" then --锯齿波幅值最大是100 saw_teeth<=\"0000000\"; end if; end if; end process; pwm<='1' when perc>saw_teeth else '0' when perc<= saw_teeth; --锯齿波与常数信号相比较,产生占 --空比由常数perc决定的pwm信号 end behave; (3)有限状态机设计PWM信号发生器 libraryieee; use ieee.std_logic_1164.all; useieee.std_logic_unsigned.all; entity pwm_signal_3 is port(clk,reset:instd_logic; perc:instd_logic_vector(6 downto 0); pwm:outstd_logic); 22 PWM信号发生器的研制 end entity; architecture behave of pwm_signal_3 is type states is (st0,st1); --定义states为枚举类型 signal current_state,next_state:states; --这里的两个信号的来源是上面定义 --的枚举类型数据 signal count:std_logic_vector(6 downto 0); --计数器的定义 begin process(reset,clk) --时序逻辑进程(状态转换进程) begin if reset='0' then count<=\"0000000\";current_state<=st1; --异步复位 elsif (clk'event and clk='1') then current_state<=next_state; --状态转换 count<=count+1; --计数器计数 if count>=\"1100100\" then count<=\"0000000\"; --计数器清零 end if; end if; end process; process(current_state,count) --组合逻辑进程(状态译码和输出译码) begin case current_state is --确定当前状态的状态值 when st1=>pwm<='1'; --状态译码和输译码出 if count if count>=perc and count<\"1100100\" then next_state<=st0; --转换到第二个状态 elsenext_state<=st1; end if; end case; end process; end behave; 23 因篇幅问题不能全部显示,请点此查看更多更全内容