论坛风格切换切换到宽版
  • 3711阅读
  • 16回复

做了一个DDS核,主频50M,输出381.492Hz相当稳定 [复制链接]

上一主题 下一主题
离线yuhang
 
发帖
1803
只看楼主 倒序阅读 0楼 发表于: 2009-06-06
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-------------------------------------------------------------------------------
--2009-6-4
-------------------------------------------------------------------------------
-- vhdl training hfdy
-- hardware = lt-cpld
-------------------------------------------------------------------------------
--entity
-------------------------------------------------------------------------------
entity test is
     port(
           clk:            in std_logic;
           clk2:            out std_logic;
           keys:                  in std_logic_vector(7 downto 0);
           dac:                  out std_logic_vector(7 downto 0)
           );
end test;
-------------------------------------------------------------------------------
architecture rtl of test is
     signal      acc:      std_logic_vector(31 downto 0);
     signal      sum:      std_logic_vector(31 downto 0);
     signal      add:      std_logic_vector(7 downto 0);
     signal      data:      std_logic_vector(7 downto 0);
     signal      bcc:      std_logic_vector(7 downto 0);
begin
-------------------------------------------------------------------------------
clk2<=Ƈ'
     bcc<=acc(31 downto 24);
-------------------------------------------------------------------------------
process(clk,acc,sum,keys)
begin
     if clk'event and clk=Ɔ' then
           acc<=sum;
     end if;
     sum<=acc+keys+"00000000000000001000000000000000";
end process;
-------------------------------------------------------------------------------
process(bcc,add,data)--sin_rom
begin
     if clk'event and clk=Ƈ' then
           if bcc<"01000000" then
                 add<=bcc;
                 dac<=data;
           elsif bcc<"10000000" then
                 add<="01111111"-bcc;
                 dac<=data;
           elsif bcc<"11000000" then
                 add<=bcc-"10000000";
                 dac<="11111111"-data;
           elsif bcc<="11111111" then
                 add<="11111111"-bcc;
                 dac<="11111111"-data;
           end if;
     
           case add is
                 when"00000000"=>data<="10000000";
                 when"00000001"=>data<="10000011";
                 when"00000010"=>data<="10000110";
                 when"00000011"=>data<="10001001";
                 when"00000100"=>data<="10001100";
                 when"00000101"=>data<="10001111";
                 when"00000110"=>data<="10010010";
                 when"00000111"=>data<="10010101";
                 when"00001000"=>data<="10011000";
                 when"00001001"=>data<="10011011";
                 when"00001010"=>data<="10011110";
                 when"00001011"=>data<="10100001";
                 when"00001100"=>data<="10100100";
                 when"00001101"=>data<="10100111";
                 when"00001110"=>data<="10101010";
                 when"00001111"=>data<="10101101";
                 when"00010000"=>data<="10110000";
                 when"00010001"=>data<="10110011";
                 when"00010010"=>data<="10110110";
                 when"00010011"=>data<="10111001";
                 when"00010100"=>data<="10111011";
                 when"00010101"=>data<="10111110";
                 when"00010110"=>data<="11000001";
                 when"00010111"=>data<="11000011";
                 when"00011000"=>data<="11000110";
                 when"00011001"=>data<="11001001";
                 when"00011010"=>data<="11001011";
                 when"00011011"=>data<="11001110";
                 when"00011100"=>data<="11010000";
                 when"00011101"=>data<="11010010";
                 when"00011110"=>data<="11010101";
                 when"00011111"=>data<="11010111";
                 when"00100000"=>data<="11011001";
                 when"00100001"=>data<="11011011";
                 when"00100010"=>data<="11011110";
                 when"00100011"=>data<="11100000";
                 when"00100100"=>data<="11100010";
                 when"00100101"=>data<="11100100";
                 when"00100110"=>data<="11100101";
                 when"00100111"=>data<="11100111";
                 when"00101000"=>data<="11101001";
                 when"00101001"=>data<="11101011";
                 when"00101010"=>data<="11101100";
                 when"00101011"=>data<="11101110";
                 when"00101100"=>data<="11101111";
                 when"00101101"=>data<="11110001";
                 when"00101110"=>data<="11110010";
                 when"00101111"=>data<="11110100";
                 when"00110000"=>data<="11110101";
                 when"00110001"=>data<="11110110";
                 when"00110010"=>data<="11110111";
                 when"00110011"=>data<="11111000";
                 when"00110100"=>data<="11111001";
                 when"00110101"=>data<="11111010";
                 when"00110110"=>data<="11111011";
                 when"00110111"=>data<="11111011";
                 when"00111000"=>data<="11111100";
                 when"00111001"=>data<="11111101";
                 when"00111010"=>data<="11111101";
                 when"00111011"=>data<="11111110";
                 when"00111100"=>data<="11111110";
                 when"00111101"=>data<="11111110";
                 when"00111110"=>data<="11111110";
                 when"00111111"=>data<="11111111";
                 when others=> null;
           end case;
     end if;
end process;
-------------------------------------------------------------------------------
end rtl;
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线yuhang
发帖
1803
只看该作者 1楼 发表于: 2009-06-06
采用压缩 正弦表

大概 不到80个les
离线永远的FM
发帖
12113
只看该作者 2楼 发表于: 2009-06-06
请问你用什么芯片?
离线yuhang
发帖
1803
只看该作者 3楼 发表于: 2009-06-06
[quote=永远的fm]请问你用什么芯片?[/quote]


epm240

呵呵
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线代洪波
发帖
4809
只看该作者 4楼 发表于: 2009-06-06
不懂,帮顶!!
离线小比尔/5
发帖
2582
只看该作者 5楼 发表于: 2009-06-06
这个频率我就直接用单片机做了
比指甲大一点
离线汤圆
发帖
1157
只看该作者 6楼 发表于: 2009-06-07
yuhang 原来你习惯vhdl啊 哈哈
离线FMer
发帖
2549
只看该作者 7楼 发表于: 2009-06-07
俺也正打算做这个东东,用epm570,嘎嘎。
离线bellstudio
发帖
2820
只看该作者 8楼 发表于: 2009-06-07
这个频率有什么特殊用途么?
小数点三位,恩,不容易
离线BD1CM
发帖
3306
只看该作者 9楼 发表于: 2009-06-17
单片机会抖,除非用预设置功能的定时器
离线小比尔/5
发帖
2582
只看该作者 10楼 发表于: 2009-06-17
单片机不会抖的,d/a可利用定时器硬件触发减少jitter,只是频率上不去而已
离线BD1CM
发帖
3306
只看该作者 11楼 发表于: 2009-06-17
看你用那种定时器了,要是光靠中断实现并且使用没有预存的定时器一定会抖,除非你没有别的任何程序在跑。有些单片机的定时器已经改进成有预存的了,dsp的定时器很早以前就是有预存的。
离线小比尔/5
发帖
2582
只看该作者 12楼 发表于: 2009-06-17
'
看你用那种定时器了,要是光靠中断实现并且使用没有预存的定时器一定会抖,除非你没有别的任何程序在跑。有些单片机的定时器已经改进成有预存的了,dsp的定时器很早以前就是有预存的。
'

那是当然,我只用单片机当dds核和dac,控制好时序,应该没有问题
而且,单片机利用定时器的溢出信号硬件控制dac的锁存,即使程序抖,输出信号也不会抖
唯一导致严重抖动的原因是相位累加器的截断误差,这个就是由dds的原理决定的了
左为单片机dac输出,右为经过简易的二阶lc滤波器的输出
单片机很便宜,贴片封装的只有5元,一个简单的dds核(不带lpf),采用贴片有源晶振,只有硬币大小,在要求不高,频率比较低的地方,特别是不需滤波器的地方(比如产生440hz拨号音送到pcm编码芯片)可以胜任;当然ad9833也可以胜任,体积也很小,只是贵了点(虽然说便宜没好货)。。。
本主题包含附件,请 登录 后查看, 或者 注册 成为会员
离线yuhang
发帖
1803
只看该作者 13楼 发表于: 2009-06-19
添个 图片 呵呵
离线一异
发帖
868
只看该作者 14楼 发表于: 2009-06-19
[quote=小比尔/5]那是当然,我只用单片机当dds核和dac,控制好时序,应该没有问题
而且,单片机利用定时器的溢出信号硬件控制dac的锁存,即使程序抖,输出信号也不会抖
唯一导致严重抖动的原因是相位累加器的截断误差,这个就是由dds的原理决定的了
左为单片机dac输出,右为经过简易的二阶lc滤波器的输出
单片机很便宜,贴片封装的只有5元,一个简单的dds核(不带lpf),采用贴片有源晶振,只有硬币大小,在要求不高,频率比较低的地方,特别是不需滤波器的地方(比如产生440hz拨号音送到pcm编码芯片)可以胜任;当然ad9833也可以胜任,体积也很小,只是贵了点(虽然说便宜没好货)。。。[/quote]

相位累加器不存在截断误差,也不会带来抖动。相位累加器的有限字长只影响频率分辨率。
真正带来误差的是波表/dac的有限字长。
另外一个问题就是输出端得低通滤波器的性能,特别是在输出频率高段,输出信号的质量很大程度上取决于这个滤波器。

另外,从你的波形图可以看出,你的dac输出信号没有经过脉冲整形,这样做的后果是频率高段幅度下降非常快。
从理论上讲,最好将dac输出变成零宽度的脉冲串,当然实际上这意味着输出电压为零。在实际电路中,最好用一个尽量窄的脉冲调制dac的输出。
具体用多宽的脉冲,需要在输出频响平坦度的要求和输出信噪比之间进行折衷。如果要求较高,往往采用一个适当的脉冲宽度+补偿滤波器来保证性能。
离线小比尔/5
发帖
2582
只看该作者 15楼 发表于: 2009-06-19
'
添个 图片 呵呵
'
这块板子好眼熟,嘿嘿,我也想买块玩,不过现在不在学校里了,恐怕会受到挺多限制的

对了,用这个板能不能做dsp?既然连dds都能做,不妨再做做dsp吧,这样就可以彻底把模拟振荡器扔了。
离线小比尔/5
发帖
2582
只看该作者 16楼 发表于: 2009-06-19
[quote=一异]
另外,从你的波形图可以看出,你的dac输出信号没有经过脉冲整形,这样做的后果是频率高段幅度下降非常快。
[/quote]

是的,但是这个问题解决了,整形太麻烦啦,小生做不到,不过频率不高(可输出0-256khz),于是就把数字电位器和5阶lpf做在一起,补偿它就是了。
高频段的性能通过过采样解决(本来的输出频率最高到50khz的,于是lpf从64khz开始切),这样对滤波器的要求就小了。只是lpf在200khz的时候出现一个谐振峰,那个伤心啊。。。