打印
[FPGA]

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

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

     在第二个贴中,如不错意外,大家应该已经可以在示波器输出正弦信号了,那么接下来我们就要考虑怎么把正弦信号和三角波信号进行比较输出spwm了(完成这一步,那么整个设计就基本搞定了:lol)
    不过在此之前,有必要和大家说一下正弦信号的周期怎么算。周期就是输出一个完整正弦波所用的时间,也就说我们ROM中储存的512个正弦数据全部遍历完所用的时间。而每个数据都要和(0,255)这256个数据进行比较,所以正弦函数频率 f = 1 /(512 * 256 * t),t 为时钟周期(算出来可能和实际测量的不一样,那时因为时钟周期不准造成的,以测量的为准)。

    我们来看一下spwm生成示意图

   
   
即是用正弦函数和周期比其小得多的三级波函数值比较,若正弦函数大于三角波,则输出高电平,反则输出低电平。而三角波数据同样存在ROM中(方法同(一)),峰峰值和正弦波相同,同样为256。而数据长度设置这里就要讲技巧了,因为要保证三角波的周期要小于正弦波,大家应该记得我们当初正弦波的数据长度为512,所以这里我们可以吧三角波数据长度设为64,然后我们以同步的时钟周期来同时读它们,这样正弦数据遍历一遍时,三角波已经遍历了16遍了,也即是正弦波的周期是三角波的16倍。下面是三角波ROM元件代码
LIBRARY ieee;
USE ieee.std_logic_1164.all;

LIBRARY altera_mf;
USE altera_mf.all;

ENTITY sanjiaobo IS
        PORT
        (
                address                : IN STD_LOGIC_VECTOR (5 DOWNTO 0);
                clock                : IN STD_LOGIC  := '1';
                q                : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
        );
END sanjiaobo;


ARCHITECTURE SYN OF sanjiaobo IS

        SIGNAL sub_wire0        : STD_LOGIC_VECTOR (7 DOWNTO 0);



        COMPONENT altsyncram
        GENERIC (
                clock_enable_input_a                : STRING;
                clock_enable_output_a                : STRING;
                init_file                : STRING;
                intended_device_family                : STRING;
                lpm_hint                : STRING;
                lpm_type                : STRING;
                numwords_a                : NATURAL;
                operation_mode                : STRING;
                outdata_aclr_a                : STRING;
                outdata_reg_a                : STRING;
                widthad_a                : NATURAL;
                width_a                : NATURAL;
                width_byteena_a                : NATURAL
        );
        PORT (
                        address_a        : IN STD_LOGIC_VECTOR (5 DOWNTO 0);
                        clock0        : IN STD_LOGIC ;
                        q_a        : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
        );
        END COMPONENT;

BEGIN
        q    <= sub_wire0(7 DOWNTO 0);

        altsyncram_component : altsyncram
        GENERIC MAP (
                clock_enable_input_a => "BYPASS",
                clock_enable_output_a => "BYPASS",
                init_file => "sanjiaobo.mif",
                intended_device_family => "Cyclone II",
                lpm_hint => "ENABLE_RUNTIME_MOD=NO",
                lpm_type => "altsyncram",
                numwords_a => 64,
                operation_mode => "ROM",
                outdata_aclr_a => "NONE",
                outdata_reg_a => "CLOCK0",
                widthad_a => 6,
                width_a => 8,
                width_byteena_a => 1
        )
        PORT MAP (
                address_a => address,
                clock0 => clock,
                q_a => sub_wire0
        );



END SYN;

三角波ROM元件建好后,我们需要的就是同步把正弦波和三角波中的ROM数据读出来,比较他们,根据比较结果即可生成spwm。修改一下(二)中的数据即可获得下面程序:

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

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

ARCHITECTURE rlt OF spwm 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;

COMPONENT sanjiaobo IS
        PORT
        (
                address                : IN STD_LOGIC_VECTOR (5 DOWNTO 0);
                clock                : IN STD_LOGIC  := '1';
                q                : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
        );
END COMPONENT;

SIGNAL counter :INTEGER RANGE 0 TO 256;   --用于计数
SIGNAL sin_addr :STD_LOGIC_VECTOR (8 DOWNTO 0) ;   --sin ROM地址
SIGNAL sin_rom_data :STD_LOGIC_VECTOR (7 DOWNTO 0) ;  --sin ROM数据
SIGNAL san_addr :STD_LOGIC_VECTOR (5 DOWNTO 0) ;   --三角波ROM地址
SIGNAL san_rom_data :STD_LOGIC_VECTOR (7 DOWNTO 0) ;  --三角波ROM数据
BEGIN

u1: sanjiaobo PORT MAP(san_addr, sysclk, san_rom_data);
u2: sin_512 PORT MAP(sin_addr, sysclk, sin_rom_data);  --实例化ROM元件

PROCESS(sysclk) IS
        
        BEGIN
                IF(sysclk'EVENT AND sysclk = '1') THEN
                        counter <= counter + 1;   
                        IF(counter = 256) THEN
                                counter <= 0;
                                sin_addr <= sin_addr + 1;    -- 比较完256个数据后sin ROM地址加1
                                                                                  san_addr <= san_addr + 1;    -- 三角波ROM地址跟随sin ROM地址变化
                        END IF;
                        IF(sin_rom_data > counter)THEN  --输出sin        
                                pwm_output <= '1';
                        ELSE
                                pwm_output <= '0';
                        END IF;
                                                                IF(sin_rom_data > san_rom_data)THEN  --输出spwm      
                                spwm_output <= '1';
                        ELSE
                                spwm_output <= '0';
                        END IF;
                END IF;
        END PROCESS;        
END ARCHITECTURE;
   到此为止,课程的基本内容已经完成,编程思路有千万种,我的程序只是供大家参考,请勿直接套用,大家有什么问题欢迎回帖提问,我会尽快回答。

相关帖子

沙发
505091994| | 2015-5-16 23:22 | 只看该作者
请问楼主单身吗?

使用特权

评论回复
板凳
lzayoi| | 2015-5-16 23:26 | 只看该作者
wenjugege,你的计数器是不是设置错了?应该是0~255吧?你设成0~256,求解

使用特权

评论回复
地板
IT举人|  楼主 | 2015-5-16 23:36 | 只看该作者
lzayoi 发表于 2015-5-16 23:26
wenjugege,你的计数器是不是设置错了?应该是0~255吧?你设成0~256,求解

等于256就清零,也就是只到255了,其实这1个值也不影响的

使用特权

评论回复
5
lzayoi| | 2015-5-16 23:41 | 只看该作者
IT举人 发表于 2015-5-16 23:36
等于256就清零,也就是只到255了,其实这1个值也不影响的

啊里卡多,wenjugeg威武,如果频率很快,每次多计一个值还是会有影响吧?

使用特权

评论回复
6
wangjakn| | 2015-5-18 10:48 | 只看该作者
怎么还用的是VHDL,国内已经被verilog占领了

使用特权

评论回复
7
IT举人|  楼主 | 2015-5-18 19:19 | 只看该作者
wangjakn 发表于 2015-5-18 10:48
怎么还用的是VHDL,国内已经被verilog占领了

学校教的就是这个,没办法

使用特权

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

本版积分规则

4

主题

11

帖子

3

粉丝