打印
[FPGA]

基于FPGA的正弦脉宽调制波设计(二)

[复制链接]
1202|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
IT举人|  楼主 | 2015-5-16 20:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 IT举人 于 2015-5-16 21:24 编辑

    在上一篇帖子中我们已经保存了我们所需的正弦波数据点,现在我们需要的就是把它输出来。由于实验板上无数模转换(D/A)芯片,因此需设计一PWM发生器。正弦波数据输入PWM发生器,产生PWM信号,PWM信号经过RC低通滤波器输出模拟电压。如图2-1所示
图2-1
    低通滤波器选取R 为108欧,C选104,即可。
    好,接下来说说怎么根据正弦波数据产生PWM,即是完成PWM发生器部分。在这里再说一下,这个PWM实际上也是SPWM来的,即是脉冲宽度时间占空比按正弦规律排列。那么它和上面那个由三角波比较产生的spwm有什么不同呢?不同在于三角波比较获得的spwm频率比较低,从而可以在示波器上显示出来,但不能通过低通滤波器产生模拟正弦波。相反PWM发生器产生的spwm频率比较高,在示波器上不能很好地显示出来,但可以通过低通滤波器产生模拟正弦波。

    大家看回我们上一贴中产生的正弦波

图2-2
这个波形的峰顶值为256,峰谷为0。那么大家想象一下就能知道,它的峰顶值对应的PWM的占空比为100%,峰谷对应PWM的占空比为0%,那么设一数据78对应的占空比呢?理想当然是78/256 。所以这里我们就可以很自然地设定我们的PWM输出的周期为256个时钟周期,那么任一数据点对应的占空比就为Yn/256(Yn/为上一贴中存储在ROM中的sin的值)。
好,接下来就是重点,程序实现了。其实也不是很难,我们只需要设置一个计数值counter,每个时钟周期来就自加1(从0加到256),然后再和Yn比较,当Yn > counter时,PWM输出端口(即是一个普通的io口,我们用它来输出PWM)置‘1’,当Yn  < counter时,PWM输出端口置‘0’。例如当Yn = 78时,那么PWM输出端口就有78个时钟周期处于高电平,178个时钟周期处于低电平,它的占空比是不是就是78/256了呢?比较完256个数据后,ROM的地址加1,读取出另一个正弦值Yn+1;重复上述比较即可。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY spwm_test IS
PORT(sysclk :IN STD_LOGIC;
                pwm_output :OUT STD_LOGIC);
END ENTITY spwm_test;

ARCHITECTURE rlt OF spwm_test IS

COMPONENT sin_512 IS   --声明ROM元件
        PORT
        (
                address                : IN STD_LOGIC_VECTOR (8 DOWNTO 0);  --ROM地址信号
                clock                : IN STD_LOGIC  := '1';            --时钟信号
                q                : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)   ---输出信号
        );
END COMPONENT;

SIGNAL counter :INTEGER RANGE 0 TO 256;   --用于计数
SIGNAL addr :STD_LOGIC_VECTOR (8 DOWNTO 0) ;   --ROM地址
SIGNAL rom_data :STD_LOGIC_VECTOR (6 DOWNTO 0) ;  --ROM数据
BEGIN

u2: sin_512 PORT MAP(addr, sysclk, rom_data);  --实例化ROM元件

PROCESS(sysclk) IS
        
        BEGIN
                IF(sysclk'EVENT AND sysclk = '1') THEN
                        counter <= counter + 1;   
                        IF(counter = 256) THEN
                                counter <= 0;
                                addr <= addr + 1;    -- 比较完256个数据后ROM地址加1,读取下一ROM单元中的储存数据
                        END IF;
                        IF(rom_data > counter)THEN  --比较生成PWM        
                                pwm_output <= '1';
                        ELSE
                                pwm_output <= '0';
                        END IF;
                END IF;
        END PROCESS;        
END ARCHITECTURE;


相关帖子

沙发
lzayoi| | 2015-5-16 22:34 | 只看该作者
学渣的我早已夺下沙发

使用特权

评论回复
板凳
IT举人|  楼主 | 2015-5-16 22:35 | 只看该作者
lzayoi 发表于 2015-5-16 22:34
写的好详细,6666666,而且这方法好简单(不要问我是谁,我只是路过的学渣) ...

等等会更简单:lol

使用特权

评论回复
地板
lzayoi| | 2015-5-16 23:04 | 只看该作者

擦,我明明修改成抢沙发了,你收到的居然还是原版

使用特权

评论回复
5
IT举人|  楼主 | 2015-5-16 23:12 | 只看该作者
lzayoi 发表于 2015-5-16 23:04
擦,我明明修改成抢沙发了,你收到的居然还是原版

去抢第三个的沙发吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

11

帖子

3

粉丝