找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 17079|回復(fù): 33
打印 上一主題 下一主題
收起左側(cè)

DA9833+51單片機(jī)DDS信號(hào)發(fā)生器的設(shè)計(jì)(含源碼+PCB+仿真)高精度頻率

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:418270 發(fā)表于 2018-10-31 00:32 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
DDS信號(hào)發(fā)生器硬件電路主要包括:主控電路、DA9833模塊電路、獨(dú)立按鍵、液晶顯示等。

     本方案選擇了AD9833(AD9833數(shù)據(jù)手冊(cè))作為核心芯片,并與單片機(jī)STC89C52(STC89C52數(shù)據(jù)手冊(cè))結(jié)合,設(shè)計(jì)一款簡(jiǎn)易的高精度頻率信號(hào)發(fā)生器,具有體積小功耗低等優(yōu)點(diǎn)。AD9833是AD公司生產(chǎn)的一款采用DDS技術(shù)、低功耗、可編程波形發(fā)生器。
     可產(chǎn)生正弦波,三角波,方波三種波形,正弦波0~4MHz,三角波0~3MHz,方波0~2MHz;任意調(diào)節(jié)幅度范圍0~15V;
     仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


電路原理圖如下:


Altium Designer畫(huà)的DDS信號(hào)發(fā)生器原理圖和PCB圖如下:(51hei附件中可下載工程文件)


幅度的放大電路:


單片機(jī)源碼:
  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 信號(hào)發(fā)生器  ";

  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;          //光標(biāo)鍵
  23. sbit s2=P2^1;          //上調(diào)鍵
  24. sbit s3=P2^2;          //下調(diào)鍵

  25. void  Wave_Generate(ulong,uchar);            //波形的頻率和波形的選擇
  26. void AD9833_Send_Word(uint);           //AD9833的數(shù)據(jù)接收函數(shù)
  27. void delay(uint);               //延時(shí)函數(shù)

  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寫(xiě)入的指令
  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寫(xiě)入的數(shù)據(jù)
  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()    //矩形鍵盤(pán)掃描函數(shù)                          
  106. {
  107.         if(s1==0)                    //光標(biāo)鍵
  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)             //上調(diào)鍵
  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. }
復(fù)制代碼



全部資料51hei下載地址:
信號(hào)發(fā)生器仿真圖及AD原理圖.zip (14.2 MB, 下載次數(shù): 867)



評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏28 分享淘帖 頂3 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:73182 發(fā)表于 2018-10-31 11:06 | 只看該作者
good~~~~
回復(fù)

使用道具 舉報(bào)

板凳
ID:92810 發(fā)表于 2018-11-4 22:18 | 只看該作者
學(xué)習(xí)學(xué)習(xí)了,謝謝分享了
回復(fù)

使用道具 舉報(bào)

地板
ID:330924 發(fā)表于 2019-1-14 22:10 | 只看該作者
謝謝分享,感恩
回復(fù)

使用道具 舉報(bào)

5#
ID:328121 發(fā)表于 2019-1-25 16:43 | 只看該作者
好資料,謝謝分享
回復(fù)

使用道具 舉報(bào)

6#
ID:138990 發(fā)表于 2019-3-8 21:47 | 只看該作者
牛逼
回復(fù)

使用道具 舉報(bào)

7#
ID:508300 發(fā)表于 2019-4-13 08:00 來(lái)自手機(jī) | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

8#
ID:283207 發(fā)表于 2019-5-1 05:34 | 只看該作者
謝謝分享,學(xué)習(xí)了。
回復(fù)

使用道具 舉報(bào)

9#
ID:250209 發(fā)表于 2019-5-1 19:13 | 只看該作者
謝謝分享,好好學(xué)習(xí)學(xué)習(xí)。
回復(fù)

使用道具 舉報(bào)

10#
ID:537530 發(fā)表于 2019-5-13 23:20 | 只看該作者
樓上運(yùn)行成功嗎
回復(fù)

使用道具 舉報(bào)

11#
ID:542896 發(fā)表于 2019-5-20 15:34 | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

12#
ID:586972 發(fā)表于 2019-7-19 16:30 | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

13#
ID:593509 發(fā)表于 2019-8-1 18:09 | 只看該作者
小白來(lái)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

14#
ID:268118 發(fā)表于 2019-9-12 22:42 | 只看該作者
感謝樓主的分享。
回復(fù)

使用道具 舉報(bào)

15#
ID:168431 發(fā)表于 2019-10-6 17:09 來(lái)自手機(jī) | 只看該作者
op07帶寬才500KHZ,接近和超過(guò)500KHZ時(shí)波形失真衰減嚴(yán)重,根本做不到1M以上,用高速運(yùn)放可以。
回復(fù)

使用道具 舉報(bào)

16#
ID:250209 發(fā)表于 2019-10-6 17:54 | 只看該作者
謝謝分享,好好學(xué)習(xí)學(xué)習(xí)。
回復(fù)

使用道具 舉報(bào)

17#
ID:629342 發(fā)表于 2019-10-24 11:46 | 只看該作者
這款程序非常不錯(cuò)
回復(fù)

使用道具 舉報(bào)

18#
ID:599674 發(fā)表于 2019-10-25 10:54 | 只看該作者
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

19#
ID:662569 發(fā)表于 2019-12-13 08:59 來(lái)自手機(jī) | 只看該作者
謝謝分享
回復(fù)

使用道具 舉報(bào)

20#
ID:663093 發(fā)表于 2019-12-13 10:44 | 只看該作者
感謝分享
回復(fù)

使用道具 舉報(bào)

21#
ID:675023 發(fā)表于 2019-12-29 02:18 | 只看該作者
為什么我的源碼用不了顯示沒(méi)有權(quán)限呢 樓主
回復(fù)

使用道具 舉報(bào)

22#
ID:360351 發(fā)表于 2020-1-2 16:53 | 只看該作者
我打不開(kāi)PCB
回復(fù)

使用道具 舉報(bào)

23#
ID:447388 發(fā)表于 2020-1-21 15:17 | 只看該作者
感謝感謝
回復(fù)

使用道具 舉報(bào)

24#
ID:522799 發(fā)表于 2020-2-5 14:32 | 只看該作者
有人做成功了嗎?感覺(jué)它那個(gè)pcb不對(duì)lcd12864少了個(gè)焊盤(pán),周?chē)鸀樯兑蛞欢巡?/td>
回復(fù)

使用道具 舉報(bào)

25#
ID:864135 發(fā)表于 2022-1-9 16:15 | 只看該作者
ad9833和dac0832,到底哪個(gè)?
回復(fù)

使用道具 舉報(bào)

26#
ID:205485 發(fā)表于 2022-7-31 20:30 | 只看該作者
這個(gè)資料不錯(cuò),謝謝分享,但還是有一些地方不夠清楚:
1,仿真的和資料里的不是同一套電路;
2,預(yù)留了7個(gè)PIN的9833模塊接口,卻沒(méi)說(shuō)是哪種模塊,按照原理圖理解應(yīng)是自帶有幅值調(diào)節(jié)電位器的那種。
3,OP07只能對(duì)1MHz以下的信號(hào)進(jìn)行運(yùn)放,這個(gè)最好說(shuō)一下,畢竟9833產(chǎn)生的信號(hào)大概能跑到8M呢。
回復(fù)

使用道具 舉報(bào)

27#
ID:1053263 發(fā)表于 2023-4-1 22:28 | 只看該作者
你好,我根據(jù)電路圖進(jìn)行了打板,但是燒錄時(shí)12864無(wú)顯示,請(qǐng)問(wèn)是有什么位置可能不對(duì)嗎
回復(fù)

使用道具 舉報(bào)

28#
ID:1053263 發(fā)表于 2023-4-2 01:06 | 只看該作者
紅花無(wú)常 發(fā)表于 2022-7-31 20:30
這個(gè)資料不錯(cuò),謝謝分享,但還是有一些地方不夠清楚:
1,仿真的和資料里的不是同一套電路;
2,預(yù)留了7 ...

能指導(dǎo)一下為什么電源接通了而不能顯示
回復(fù)

使用道具 舉報(bào)

29#
ID:1077459 發(fā)表于 2023-6-12 17:31 | 只看該作者
可調(diào)節(jié)頻率嗎
回復(fù)

使用道具 舉報(bào)

30#
ID:1085296 發(fā)表于 2023-6-21 09:34 | 只看該作者
有人做成功了嗎

回復(fù)

使用道具 舉報(bào)

31#
ID:225615 發(fā)表于 2023-6-23 11:21 | 只看該作者
感謝分享,我就是沖著代碼來(lái)學(xué)習(xí)的!
回復(fù)

使用道具 舉報(bào)

32#
ID:1058687 發(fā)表于 2023-7-6 20:02 | 只看該作者
感謝分享,請(qǐng)問(wèn)代碼要在哪個(gè)軟件上寫(xiě)
回復(fù)

使用道具 舉報(bào)

33#
ID:372579 發(fā)表于 2023-8-12 08:25 | 只看該作者
這個(gè)很不錯(cuò),有時(shí)間做一個(gè),謝謝分享
回復(fù)

使用道具 舉報(bào)

34#
ID:146771 發(fā)表于 2024-6-30 12:59 | 只看該作者
沒(méi)仔細(xì)看,這個(gè)仿真是DA0832,頻率比較低的
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表