找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 15762|回复: 33
打印 上一主题 下一主题
收起左侧

DA9833+51单片机DDS信号发生器的设计(含源码+PCB+仿真)高精度频率

  [复制链接]
跳转到指定楼层
楼主
DDS信号发生器硬件电路主要包括:主控电路、DA9833模块电路、独立按键、液晶显示等。

     本方案选择了AD9833(AD9833数据手册)作为核心芯片,并与单片机STC89C52(STC89C52数据手册)结合,设计一款简易的高精度频率信号发生器,具有体积小功耗低等优点。AD9833是AD公司生产的一款采用DDS技术、低功耗、可编程波形发生器。
     可产生正弦波,三角波,方波三种波形,正弦波0~4MHz,三角波0~3MHz,方波0~2MHz;任意调节幅度范围0~15V;
     仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


电路原理图如下:


Altium Designer画的DDS信号发生器原理图和PCB图如下:(51hei附件中可下载工程文件)


幅度的放大电路:


单片机源码:
  1. #include <reg52.h>                //头文件
  2. #include <intrins.h>
  3. #include <stdio.h>
  4. #include <math.h>  
  5. #define uint unsigned int
  6. #define uchar unsigned char
  7. #define ulong unsigned long

  8. uchar s1num,shape,num,a,b,c,d,e,f,h,boxing;
  9. ulong Freq,g;
  10. uint Config_Data[8];

  11. uchar code table1[]="波形选择 :  SIN ";
  12. uchar code table2[]="波形频率 :      ";
  13. uchar code table3[]="0 0 0 0 0 0 0 HZ";
  14. uchar code table4[]="DDS 信号发生器  ";

  15. sbit rs=P2^7;                   //12864液晶端口的定义
  16. sbit rw=P2^6;
  17. sbit ep=P2^5;
  18. sbit lcd_psb=P2^4;

  19. sbit  FSYNC=P1^4;           //AD9833端口的定义
  20. sbit  SCLK =P1^3;   
  21. sbit  SDATA=P1^2;

  22. sbit s1=P2^0;          //光标键
  23. sbit s2=P2^1;          //上调键
  24. sbit s3=P2^2;          //下调键

  25. void  Wave_Generate(ulong,uchar);            //波形的频率和波形的选择
  26. void AD9833_Send_Word(uint);           //AD9833的数据接收函数
  27. void delay(uint);               //延时函数

  28. void delay(uint xms)     
  29. {
  30.         uint i,j;
  31.         for(i=xms;i>0;i--)
  32.                  for(j=110;j>0;j--);
  33. }

  34. void lcd_cmd(uchar cmd)          //12864写入的指令
  35. {
  36.     rs=0;
  37.         rw=0;
  38.         ep=0;
  39.         P0=cmd;
  40.         delay(5);
  41.         ep=1;
  42.         delay(5);
  43.         ep=0;
  44. }

  45. void lcd_dat(uchar dat)          //12864写入的数据
  46. {
  47.     rs=1;
  48.         rw=0;
  49.         ep=0;
  50.         P0=dat;
  51.         delay(5);
  52.         ep=1;
  53.         delay(5);
  54.         ep=0;
  55. }

  56. void lcd_init()                 //12864液晶的初始化
  57. {
  58.    
  59.         lcd_psb=1;
  60.         delay(5);

  61.         lcd_cmd(0x34);
  62.         delay(5);
  63.         lcd_cmd(0x30);
  64.         delay(5);
  65.         lcd_cmd(0x0c);
  66.         delay(5);
  67.         lcd_cmd(0x01);
  68.         delay(5);
  69.    
  70. }


  71. void display()
  72. {                  
  73.             uint i;
  74.                 lcd_cmd(0x80);            //第一行显示
  75.                 while(table1[i]!='\0')
  76.                 {
  77.                          lcd_dat(table1[i]);
  78.                          i++;
  79.                 }
  80.         
  81.                 i=0;
  82.                 lcd_cmd(0x90);                //第二行显示
  83.                 while(table2[i]!='\0')
  84.                 {
  85.                          lcd_dat(table2[i]);
  86.                          i++;
  87.                 }
  88.         
  89.                 i=0;
  90.                 lcd_cmd(0x88);                //第三行显示
  91.                 while(table3[i]!='\0')
  92.                 {
  93.                          lcd_dat(table3[i]);
  94.                          i++;
  95.                 }
  96.         
  97.                 i=0;
  98.                 lcd_cmd(0x98);                //第四行显示
  99.                 while(table4[i]!='\0')
  100.                 {
  101.                          lcd_dat(table4[i]);
  102.                          i++;
  103.                 }

  104. }

  105. void input_freq()    //矩形键盘扫描函数                          
  106. {
  107.         if(s1==0)                    //光标键
  108.         {
  109.             delay(5);
  110.                 if(s1==0)
  111.                 {
  112.                         s1num++;
  113.                             while(!s1);
  114.                                 lcd_cmd(0x0f);
  115.                                  if(s1num==1)
  116.                                 {
  117.                                      lcd_cmd(0x80+7);
  118.                                 }
  119.                                 if(s1num==2)
  120.                                 {
  121.                                      lcd_cmd(0x88+6);
  122.                                 }
  123.                                 if(s1num==3)
  124.                                 {
  125.                                      lcd_cmd(0x88+5);
  126.                                 }
  127.                                 if(s1num==4)
  128.                                 {
  129.                                      lcd_cmd(0x88+4);
  130.                                 }
  131.                                 if(s1num==5)
  132.                                 {
  133.                                      lcd_cmd(0x88+3);
  134.                                 }
  135.                                 if(s1num==6)
  136.                                 {
  137.                                      lcd_cmd(0x88+2);
  138.                                 }
  139.                                 if(s1num==7)
  140.                                 {
  141.                                      lcd_cmd(0x88+1);
  142.                                 }
  143.                                 if(s1num==8)
  144.                                 {
  145.                                      lcd_cmd(0x88+0);
  146.                                 }
  147.                                 if(s1num==9)
  148.                                 {
  149.                                      s1num=0;
  150.                                      lcd_cmd(0x0c);
  151.                                          g=a+10*b+100*c+1000*d+10000*e+100000*f+1000000*h;
  152.                                          Freq=g;
  153.                                          boxing=shape;
  154.                                          Wave_Generate(Freq,boxing);
  155.                                 }
  156.                 }
  157.         }
  158.         if(s1num!=0)             //上调键
  159.         {
  160.                 if(s2==0)
  161.                 {
  162.                     delay(5);
  163.                         if(s2==0)
  164.                         {
  165.                     while(!s2);               
  166.                             if(s1num==1)
  167.                                 {
  168.                                      shape++;
  169.                                          if(shape==3)
  170.                                                 shape=0;
  171.                                          lcd_cmd(0x80+6);
  172.                                          switch(shape)
  173.                                            {
  174.                         
  175.                                              case 0:
  176.                                                          lcd_dat('S');          //按0为正弦波
  177.                                                                  delay(5);
  178.                                                                  lcd_dat('I');
  179.                                                                  delay(5);
  180.                                                                  lcd_dat('N');
  181.                                                                  delay(5);
  182.                                                      break;
  183.                                              case 1:
  184.                                                          lcd_dat('T');          //按1为三角波
  185.                                                                  delay(5);
  186.                                                                  lcd_dat('R');
  187.                                                                  delay(5);
  188.                                                                  lcd_dat('I');
  189.                                                                  delay(5);
  190.                                                      break;
  191.                                              case 2:
  192.                                                          lcd_dat('D');           //按2为方波
  193.                                                                  delay(5);
  194.                                                                  lcd_dat('A');
  195.                                                                  delay(5);
  196.                                                                  lcd_dat('C');
  197.                                                                  delay(5);
  198.                                                      break;
  199.                                          }
  200.                                 }
  201.                                 if(s1num==2)
  202.                                 {
  203.                                      a++;
  204.                                          if(a==10)
  205.                                                a=0;
  206.                                          lcd_cmd(0x88+6);
  207.                                          lcd_dat(0x30+a);
  208.                                 }
  209.                             if(s1num==3)
  210.                                 {
  211.                                      b++;
  212.                                          if(b==10)
  213.                                                b=0;
  214.                                          lcd_cmd(0x88+5);
  215.                                          lcd_dat(0x30+b);
  216.                                 }
  217.                                 if(s1num==4)
  218.                                 {
  219.                                      c++;
  220.                                          if(c==10)
  221.                                                c=0;
  222.                                          lcd_cmd(0x88+4);
  223.                                          lcd_dat(0x30+c);
  224.                                 }
  225.                                 if(s1num==5)
  226.                                 {
  227.                                      d++;
  228.                                          if(d==10)
  229.                                                d=0;
  230.                                          lcd_cmd(0x88+3);
  231.                                          lcd_dat(0x30+d);
  232.                                 }
  233.                                 if(s1num==6)
  234.                                 {
  235.                                      e++;
  236.                                          if(e==10)
  237.                                                e=0;
  238.                                          lcd_cmd(0x88+2);
  239.                                          lcd_dat(0x30+e);
  240.                                 }
  241.                                 if(s1num==7)
  242.                                 {
  243.                                      f++;
  244.                                          if(f==10)
  245.                                                f=0;
  246.                                          lcd_cmd(0x88+1);
  247.                                          lcd_dat(0x30+f);
  248.                                 }
  249.                                 if(s1num==8)
  250.                                 {
  251.                                      h++;
  252.                                          if(h==10)
  253.                                                h=0;
  254.                                          lcd_cmd(0x88+0);
  255.                                          lcd_dat(0x30+h);
  256.                                 }
  257.                         
  258.                         }

  259.                 }

  260.         }
  261.         if(s1num!=0)
  262.         {
  263.             if(s3==0)
  264.                 {
  265.                      delay(5);
  266.                      if(s3==0)
  267.                          {
  268.                                   while(!s3);
  269.                                   if(s1num==1)
  270.                                  {
  271.                                            shape--;
  272.                                           if(shape==-1)
  273.                                                shape=2;
  274.                                           lcd_cmd(0x80+6);
  275.                                           switch(shape)
  276.                                             {
  277.                         
  278.                                              case 0:
  279.                                                          lcd_dat('S');          //按0为正弦波
  280.                                                                  delay(5);
  281.                                                                  lcd_dat('I');
  282.                                                                  delay(5);
  283.                                                                  lcd_dat('N');
  284.                                                                  delay(5);
  285.                                                      break;
  286.                                              case 1:
  287.                                                          lcd_dat('T');          //按1为三角波
  288.                                                                  delay(5);
  289.                                                                  lcd_dat('R');
  290.                                                                  delay(5);
  291.                                                                  lcd_dat('I');
  292.                                                                  delay(5);
  293.                                                      break;
  294.                                              case 2:
  295.                                                          lcd_dat('D');           //按2为方波
  296.                                                                  delay(5);
  297.                                                                  lcd_dat('A');
  298.                                                                  delay(5);
  299.                                                                  lcd_dat('C');
  300.                                                                  delay(5);
  301.                                                      break;
  302.                                           }
  303.                                  }
  304.                                  if(s1num==2)
  305.                                  {
  306.                                      a--;
  307.                                          if(a==-1)
  308.                                                a=9;
  309.                                          lcd_cmd(0x88+6);
  310.                                          lcd_dat(0x30+a);
  311.                                  }
  312.                                   if(s1num==3)
  313.                                 {
  314.                                      b--;
  315.                                          if(b==-1)
  316.                                                b=9;
  317.                                          lcd_cmd(0x88+5);
  318.                                          lcd_dat(0x30+b);
  319.                                 }
  320.                                 if(s1num==4)
  321.                                 {
  322.                                      c--;
  323.                                          if(c==-1)
  324.                                                c=9;
  325.                                          lcd_cmd(0x88+4);
  326.                                          lcd_dat(0x30+c);
  327.                                 }
  328.                                 if(s1num==5)
  329.                                 {
  330.                                      d--;
  331.                                          if(d==-1)
  332.                                                d=9;
  333.                                          lcd_cmd(0x88+3);
  334.                                          lcd_dat(0x30+d);
  335.                                 }
  336.                                 if(s1num==6)
  337.                                 {
  338.                                      e--;
  339.                                          if(e==-1)
  340.                                                e=9;
  341.                                          lcd_cmd(0x88+2);
  342.                                          lcd_dat(0x30+e);
  343.                                 }
  344.                                 if(s1num==7)
  345.                                 {
  346.                                      f--;
  347.                                          if(f==-1)
  348.                                                f=9;
  349.                                          lcd_cmd(0x88+1);
  350.                                          lcd_dat(0x30+f);
  351.                                 }
  352.                                 if(s1num==8)
  353.                                 {
  354.                                      h--;
  355.                                          if(h==-1)
  356.                                                h=9;
  357.                                          lcd_cmd(0x88+0);
  358.                                          lcd_dat(0x30+h);
  359.                                 }
  360.                          }
  361.                

  362.                 }
  363.         

  364.         }


  365. }


  366. void main()
  367. {        
  368.                    P0=0xff;
  369.             P1=0xff;
  370.                 P2=0xff;
  371.                 P3=0xff;
  372.                 //delay(10000);
  373.         
  374.                 lcd_init();
  375.                 display();
  376.                 FSYNC=1;
  377.                   SCLK=0;
  378.                 delay(5);
  379.                 Wave_Generate(1000,0);
  380.                 while(1)
  381.                 {        
  382.                       input_freq();                                 
  383.                 }

  384. }

  385. void AD9833_Send_Word(uint Data_In)

  386. {

  387.                    uchar i;
  388.                    SCLK=1;
  389.                    FSYNC=0;                        
  390.                    for(i=0;i<16;i++)

  391.                    {

  392.                              SCLK=1;
  393.                              SDATA=(bit)((Data_In & 0x8000)>>15);
  394.                              SCLK=0;
  395.                              Data_In=Data_In<<1;

  396.                    }
  397.                    FSYNC=1;
  398.                    SCLK=0;

  399. }


  400. void  Wave_Generate(ulong Freq,uchar shape)
  401. {                                

  402.                    ulong temp;
  403.                    uchar k;
  404.                    if(Freq>12000000) Freq=12000000;
  405.                    switch(shape)
  406.                    {

  407.                      case 0:
  408.                                  Config_Data[0]=0x2108;           //按0为正弦波
  409.                              Config_Data[7]=0x2008;
  410.                              break;
  411.                      case 1:
  412.                                  Config_Data[0]=0x210A;           //按1为三角波
  413.                              Config_Data[7]=0x200A;
  414.                              break;
  415.                      case 2:
  416.                                  Config_Data[0]=0x2128;           //按2为方波
  417.                              Config_Data[7]=0x2028;
  418.                              break;
  419.                      default:
  420.                                  Config_Data[0]=0x2108;
  421.                              Config_Data[7]=0x2008;

  422.                    }

  423.                    temp=Freq*10.73;          //temp=Freq*(0x10000000/20000000);
  424.                    Config_Data[1]=temp&0x00003fff;
  425.                    Config_Data[3]=Config_Data[1];
  426.                    Config_Data[2]=(temp&0x0fffc000)>>14;
  427.                    Config_Data[4]=Config_Data[2];
  428.                                                                                     
  429.                    Config_Data[1]=Config_Data[1]|0x4000;
  430.                    Config_Data[2]=Config_Data[2]|0x4000;
  431.                    Config_Data[3]=Config_Data[3]|0x8000;
  432.                    Config_Data[4]=Config_Data[4]|0x8000;
  433.                    Config_Data[5]=0xC000;
  434.                    Config_Data[6]=0xE000;

  435.                    for(k=0;k<8;k++)
  436.                   {
  437.                   AD9833_Send_Word(Config_Data[k]);
  438.                   }

  439. }
复制代码



全部资料51hei下载地址:
信号发生器仿真图及AD原理图.zip (14.2 MB, 下载次数: 867)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏27 分享淘帖 顶3 踩
回复

使用道具 举报

沙发
ID:73182 发表于 2018-10-31 11:06 | 只看该作者
good~~~~
回复

使用道具 举报

板凳
ID:92810 发表于 2018-11-4 22:18 | 只看该作者
学习学习了,谢谢分享了
回复

使用道具 举报

地板
ID:330924 发表于 2019-1-14 22:10 | 只看该作者
谢谢分享,感恩
回复

使用道具 举报

5#
ID:328121 发表于 2019-1-25 16:43 | 只看该作者
好资料,谢谢分享
回复

使用道具 举报

6#
ID:138990 发表于 2019-3-8 21:47 | 只看该作者
牛逼
回复

使用道具 举报

7#
ID:508300 发表于 2019-4-13 08:00 来自手机 | 只看该作者
谢谢分享
回复

使用道具 举报

8#
ID:283207 发表于 2019-5-1 05:34 | 只看该作者
谢谢分享,学习了。
回复

使用道具 举报

9#
ID:250209 发表于 2019-5-1 19:13 | 只看该作者
谢谢分享,好好学习学习。
回复

使用道具 举报

10#
ID:537530 发表于 2019-5-13 23:20 | 只看该作者
楼上运行成功吗
回复

使用道具 举报

11#
ID:542896 发表于 2019-5-20 15:34 | 只看该作者
谢谢分享
回复

使用道具 举报

12#
ID:586972 发表于 2019-7-19 16:30 | 只看该作者
谢谢分享
回复

使用道具 举报

13#
ID:593509 发表于 2019-8-1 18:09 | 只看该作者
小白来学习
回复

使用道具 举报

14#
ID:268118 发表于 2019-9-12 22:42 | 只看该作者
感謝樓主的分享。
回复

使用道具 举报

15#
ID:168431 发表于 2019-10-6 17:09 来自手机 | 只看该作者
op07带宽才500KHZ,接近和超过500KHZ时波形失真衰减严重,根本做不到1M以上,用高速运放可以。
回复

使用道具 举报

16#
ID:250209 发表于 2019-10-6 17:54 | 只看该作者
谢谢分享,好好学习学习。
回复

使用道具 举报

17#
ID:629342 发表于 2019-10-24 11:46 | 只看该作者
这款程序非常不错
回复

使用道具 举报

18#
ID:599674 发表于 2019-10-25 10:54 | 只看该作者
感谢楼主分享
回复

使用道具 举报

19#
ID:662569 发表于 2019-12-13 08:59 来自手机 | 只看该作者
谢谢分享
回复

使用道具 举报

20#
ID:663093 发表于 2019-12-13 10:44 | 只看该作者
感谢分享
回复

使用道具 举报

21#
ID:675023 发表于 2019-12-29 02:18 | 只看该作者
为什么我的源码用不了显示没有权限呢 楼主
回复

使用道具 举报

22#
ID:360351 发表于 2020-1-2 16:53 | 只看该作者
我打不开PCB
回复

使用道具 举报

23#
ID:447388 发表于 2020-1-21 15:17 | 只看该作者
感谢感谢
回复

使用道具 举报

24#
ID:522799 发表于 2020-2-5 14:32 | 只看该作者
有人做成功了吗?感觉它那个pcb不对lcd12864少了个焊盘,周围为啥要打一堆叉
回复

使用道具 举报

25#
ID:864135 发表于 2022-1-9 16:15 | 只看该作者
ad9833和dac0832,到底哪个?
回复

使用道具 举报

26#
ID:205485 发表于 2022-7-31 20:30 | 只看该作者
这个资料不错,谢谢分享,但还是有一些地方不够清楚:
1,仿真的和资料里的不是同一套电路;
2,预留了7个PIN的9833模块接口,却没说是哪种模块,按照原理图理解应是自带有幅值调节电位器的那种。
3,OP07只能对1MHz以下的信号进行运放,这个最好说一下,毕竟9833产生的信号大概能跑到8M呢。
回复

使用道具 举报

27#
ID:1053263 发表于 2023-4-1 22:28 | 只看该作者
你好,我根据电路图进行了打板,但是烧录时12864无显示,请问是有什么位置可能不对吗
回复

使用道具 举报

28#
ID:1053263 发表于 2023-4-2 01:06 | 只看该作者
红花无常 发表于 2022-7-31 20:30
这个资料不错,谢谢分享,但还是有一些地方不够清楚:
1,仿真的和资料里的不是同一套电路;
2,预留了7 ...

能指导一下为什么电源接通了而不能显示
回复

使用道具 举报

29#
ID:1077459 发表于 2023-6-12 17:31 | 只看该作者
可调节频率吗
回复

使用道具 举报

30#
ID:1085296 发表于 2023-6-21 09:34 | 只看该作者
有人做成功了吗

回复

使用道具 举报

31#
ID:225615 发表于 2023-6-23 11:21 | 只看该作者
感谢分享,我就是冲着代码来学习的!
回复

使用道具 举报

32#
ID:1058687 发表于 2023-7-6 20:02 | 只看该作者
感谢分享,请问代码要在哪个软件上写
回复

使用道具 举报

33#
ID:372579 发表于 2023-8-12 08:25 | 只看该作者
这个很不错,有时间做一个,谢谢分享
回复

使用道具 举报

34#
ID:146771 发表于 2024-6-30 12:59 | 只看该作者
没仔细看,这个仿真是DA0832,频率比较低的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表