文档库 最新最全的文档下载
当前位置:文档库 › 脉宽调制PWM的VHDL实现

脉宽调制PWM的VHDL实现

PWM
的设计


一、实验原理


脉宽调制是工业上常见的电机控制方法。其基本原理是用脉冲的宽度表征被测量的大小。实现上
常用一个等幅周期信号去采样调制信号,比较调制信号和载波信号的大小,将其转化为零一的数字信
号,即实现了脉宽调制。


二、系统描述



三角波发生器
比较器
CLKData[0...7]输出


1
PWM
原理图





一个基本的
PWM
发生器需要一个标准信号和目标信号进行比较,这里选择常用的三角波信号,
这样系统的描述就至少一个三角波发生器和一个比较器。其结构如图所示。


三、模块设计
1.
三角波发生器




三角波发生器实质上是一个计数器,
在时钟信号下,计数器不断进行进行加一和减一的操作,通
过另一个信号逻辑,其在零和一是分别进行加一和减一;在计数值达到最大时该逻辑变反,在此基础
上定义好电路的初始条件,就能实现周期三角波了。


定义
复位端口
rst
、时钟
端口
clk

输出端口
tri_data
;定义标示加或减的逻辑信号
updown

输出寄存器
tri_data_temp
。在行为中分别定义两个
process
描述计数器累加和递减的过程。


用语言写的时候需要注意的是输出初值的选取,选择零或者一要根据判断跳转条件对应,否则可
能会持续在零或者三角波最大值处而无法跳转。


2.
比较器




比较器
调用
QuatusII

MegaWizard Plug
-
In Manager
库中的比较器
LPM_COMPARE

置为八位,比较输出为大于的信号,定义输出
VHDL
语言源文件



3.
顶层工程





捕获.PNG
在顶层工程中,调用先前写好的三角波发生器和比较器。定义系统端口为复位信号
rst
、时钟信

clk
,输入调制信号
ADC_data(
来自模数转换的调制信号
)
和系统输出
pwm_output
。定义中间信

Triangle_data

pwm_data
连接器件。


通过
component
语句引用三角波发生器和比较器模块,通过
port map
连接器件。就将系统连
接好了。


四、实验结果


方便起见,测试信号输入给出一个周期
256
倍于时钟信号的三角波信号作为调制信号,进而得
到仿真结果如图
2
所示。


五、问题与展望



2
PWM
仿真波形图


这个实验
比较简单,
整个系统逻辑非常清晰,系统结构也不复杂,所以这个实验过程比较顺利就
完成了
。测试的波形经过简单的代码修改,就得到了正确的仿真结果。但是我想它的主要问题就在于
它真的有点简单了。我想一个实际的用作控制的
PWM
发生器,加入采集的信号我们事先不是很清楚,
那么电路比较器的同步就比较难于控制,这样实际的电

路我想还需要一个频率计来测试输入信号,将
频率反馈结果用于控制三角波发生器以得到相应的
PWM
波形。不过通过频率计测频率以控制电路,
电路
中相当加入
反馈环节,实现起来比较困难,就没有去做了。不过这个简单的系统还是体现出了
PWM
的核心思想的。



附源代码


1.
Triangle.vhd




LIBRARY ieee;


USE ieee.std_logic_1164.all;


USE ieee.std_logic_arith.all;


USE ieee.std_logic_unsigned.all;





ENTITY Triangle IS



port(



rst
: in std_logic;



clk
: in std_logic;



tri_data: out std_logic_vector( 7 downto 0 )



);



end Triangle;





architecture behav of Triangle is






constant up
: std_logic := '0';
--
* rising slope *
--



constant down : std_logic := '1';
--
* descending slope *
--



signal updown : std_logic;



signal
tri_data_temp : std_logic_vector(7 downto 0);





begin






process( rst, clk )



begin



if rst = '0' then



updown <= up;



elsif clk'event and clk = '1' then



case updown is



when up =>



if tri_data_temp >= B"11111110" then



updown <= down;



end if;



when down =>



if tri_data_temp <= B"00000001" then



updown <= up;



end if;



when others =>



end case;



end if;



tri_data <= tri_data_temp;



end process;









process ( rst, clk )



begin



if rst = '0' then



tri_data_temp <= B"00000001";



elsif clk'event and clk = '1' then



case updown is



when up =>



tri_data_temp <= tri_data_temp + 1;



when down =>



tri_data_temp <= tri_data_temp
-
1;



when others =>



end case;



end if;



--
tri_data <=
tri_data_temp;



end process;





end behav;


2.
Compare.vhd




LIBRARY ieee;


USE ieee.std_logic_1164.all;





LIBRARY lpm;


USE lpm.all;





ENTITY Compare IS



PORT



(



dataa
: IN STD_LOGIC_VECTOR (7 DOWNTO 0);



datab
: IN STD_LOGIC_VECTOR (7 DOWNTO 0);



AgB
: OUT STD_LOGIC



);


END Compare;





ARCHITECTURE SYN OF compare IS






SIGNAL sub_wire0
: STD_LOGIC ;






COMPONENT lpm_compare



GENERIC (



lpm_representation
: STRING;



lpm_type
: STRING;



lpm_width
: NATURAL



);



PORT (



dataa
: IN STD_LOGIC_VECTOR (7
DOWNTO 0);



datab
: IN STD_LOGIC_VECTOR (7 DOWNTO 0);



AgB
: OUT STD_LOGIC



);



END COMPONENT;





BEGIN



AgB <= sub_wire0;






lpm_compare_component : lpm_compare



GENERIC MAP (



lpm_representation => "UNSIGNED",




lpm_type => "LPM_COMPARE",



lpm_width => 8



)



PORT MAP (



dataa => dataa,



datab => datab,



AgB => sub_wire0



);





END SYN;


3.
PWM.vhd




LIBRARY ieee;


USE ieee.std_logic_1164.all;


USE ieee.std_logic_arith.all;


USE ieee.std_logic_unsigned.all;





entity PWM is



port(



clk : in std_logic;



rst : in std_logic;



ADC_data : in std_logic_vector ( 7 downto 0 );



--
Triangle_data : in std_logic_vector ( 7 downto 0 );






pwm_output : out std_logic



);


end PWM;





architecture behav of PWM is






signal Triangle_data : std_logic_vector( 7 downto 0
);



signal pwm_data : std_logic;






component Triangle is



port(



rst : in std_logic;



clk : in std_logic;



tri_data : out std_logic_vector ( 7 downto 0 )



);



end component;






component Compare is



port(



dataa : in std_logic_vector( 7 downto
0 );



datab : in std_logic_vector( 7 downto 0 );



AgB : out std_logic



);



end component;





begin






Triangel_inst : Triangle



port map(



rst => rst,



clk => clk,



tri_data => Triangle_data



);






Compare_inst : Compare



port map(



dataa
=> ADC_data,



datab => Triangle_data,



AgB => pwm_data



);






pwm_output <= pwm_data;


end behav;


A Work By TX




相关文档