久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3351|回復: 0
打印 上一主題 下一主題
收起左側

基于單片機+AD9850 DDS的波形發生器設計 附程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:913669 發表于 2021-5-7 23:11 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

頻率合成技術是將一個(或多個)基準頻率變換成另一個(或多個)合乎質量要求的所需頻率的技術。在通信、雷達、導航、電子偵察、干擾與抗干擾等眾多領域都有應用。隨著各種頻率合成器和頻率合成方案的出現,頻率合成技術得到了不斷的發展。

1971年3月美國學者J.Tierncy,C.M.Rader和B.Gold首次提出了直接數字頻率合成(DDS__Direct Digital Synthesis)技術。這是一種從相位概念出發直接合成所需要的波形的新的全數字頻率合成技術。同傳統的頻率合成技術相比,DDS技術具有極高的頻率分辨率、極快的變頻速度,變頻相位連續、相位噪聲低,易于功能擴展和全數字化便于集成,容易實現對輸出信號的多種調制等優點,滿足了現代電子系統的許多要求,因此得到了迅速的發展。

目前市面上的DDS芯片,價格昂貴、功能固定單一,應用受到限制。本綜合實驗項目采用基于FPGA的EDA技術設計實現DDS芯片,并可以根據實際需要對其功能進行靈活地修改,配置。


1.2 DDS 工作原理

   一個純凈的單頻信號可表示為:
                            (2-1)
只要它的幅度U和初始相位不變,它的頻譜就是位于的一條譜線。為了分析簡化起見,可令U=1,=0,這將不會影響對頻率的研究。即:
                                    (2-2)
如果對(2-2)的信號進行采樣,采樣周期為(即采樣頻率為),則可得到離散的波形序列:
                                (2-3)
相應的離散相位序列為:
                            (2-4)
式中:
                            (2-5)
是連續兩次采樣之間的相位增量。根據采樣定理:
                                       (2-6)
只要從(2-3)出來的離散序列即可唯一的恢復出(2-2)的模擬信號。從(2-2)可知,是相位函數的斜率決定了信號的頻率;從(2-5)可知,決定相位函數斜率的是兩次采樣之間的相位增量。因此,只要控制這個相位增量,就可以控制合成信號的頻率。現將整個周期的相位2分成M份,每一份為,若每次的相位增量選擇為的K倍,即可得到信號的頻率:
                                           (2-7)
相應的模擬信號為:
                                       (2-8)
式中K和M都是正整數,根據采樣定理的要求,K的最大值應小于M的1/2。
綜上所述,在采樣頻率一定的情況下,可以通過控制兩次采樣之間的相位增量(不得大于π)來控制所得離散序列的頻率,經保持、濾波之后可唯一的恢復出此頻率的模擬信號。
DDS工作原理框圖如圖2.1所示:
圖2.1 DDS原理框圖
其實質是以基準頻率源(系統時鐘)對相位進行等間隔的采樣。由圖2.1見,DDS 由相位累加器和波形存儲器(即,ROM查詢表)構成的數控振蕩器(NCO_ Numerically Controlled Oscillators)、數模轉換器(DAC)以及低通濾波器(LPF)三部分組成。在每一個時鐘周期,N位相位累加器與其反饋值進行累加,其結果的高L位作為查詢表的地址,然后從ROM中讀出相應的幅度值送到DAC。再由DAC將其轉換成為階梯模擬波形,最后由具有內插作用的LPF將其平滑為連續的正弦波形作為輸出。因此,通過改變頻率控制字K就可以改變輸出頻率
在這里
由上面的分析可得DDS的輸出頻率:
                              (2-9)
由上式可知,DDS的最小輸出頻率為:
                                        (2-10)
DDS的頻率分辨率為:
                                    (2-11)
DDS頻率輸入字的計算:
FW(N-1:0) = 2Nf0/fc                      (2-12)
1.3 DDS基本結構組成
一個基本的DDS系統由數控振蕩器(NCO)、數模轉換器(DAC)和低通濾波器(LPF)三部分構成,如圖3.1所示:
圖3.1  DDS的基本結構
數控振蕩器(NCO)產生頻率可控制的數字正弦載波,通過數模轉換器(DAC)得到模擬正弦波,最后經過低通濾波器(LPF)除去各種干擾信號。
本實驗項目中的設計主要針對數控振蕩器(NCO)部分,DAC部分直接采用實驗系統箱提供的數/模轉換電路。
1.4 DDS的設計

在DDS的設計中其最基本的構件是相位累加器和波形存貯器。通常也可在波形存貯器前面加一個相位調制器,使其具有相位調制的功能,為了防止頻率控制字、相位控制字改變時干擾相位累加器和相位調制器的正常工作,分別在這兩個模塊前面加入了兩組寄存器,從而靈活且穩定地控制頻率字和相位字的輸入。如圖4.1所示:

圖中相位累加器(phasea)是整個DDS的核心,在這里完成相位累加功能,其輸入是相位增量,又可稱為頻率控制字,由于與輸出頻率是簡單的線性關系:
                            (4-1)
事實上當基準時鐘時, 就等于

相位調制器(phasemod)接收相位累加器的相位輸出,在這里加一個相位偏移值,主要用于實現信號的相位調制,如PSK(相移鍵控)等,在不使用時可以去掉該部分,或加一個固定的相位控制字。

波形存儲器(即,正弦ROM查找表)(sinlup)把存儲在相位累加器中的抽樣值轉換成正弦波幅度的數字量函數,可理解為相位到幅度的轉換。它的輸入是相位調制器輸出的高M位(而并非全部N位)值,將其作為正弦ROM查找表的地址值;查詢表把輸入的地址相位信息映射成正弦波幅度信號;輸出送往DAC,轉化為模擬信號。


2    AD9850簡介

2.1芯片性能

隨著數字技術的飛速發展,用數字控制方法從一個參考頻率源產生多種頻率的技術,即直接數字頻率合成(DDS)技術異軍突起。美國AD公司推出的高集成度頻率合成器AD9850便是采用DDS技術的典型產品之一。AD9850采用先地蝗CMOS工藝,其功耗在3.3V供電時僅為155mW,擴展工業級溫度范圍為-40~80℃,采用28腳SSOP表面封裝形式。AD9850的引腳排列,圖2為其組成框圖。圖2中層虛線內是一個完整的可編程DDS系統,外層虛線內包含了AD9850的主要組成部分。AD9850內含可編程DDS系統和高速比較器,能實現全數字編程控制的頻率合成。可編程DDS系統的核心是相位累加器,它由一個加法器和一個N位相位寄存器組成,N一般為24~32。每來一個外部參考時鐘,相位寄存器便以步長M遞加。相位寄存器的輸出與相位控制字相加后可輸入到正弦查詢表地址上。正弦查詢表包含一個正弦波周期的數字幅度信息,每一個地址對應正弦波中0°~360°范圍的一個相位點。查詢表把輸入地址的相位信息映射成正弦波幅度信號,然后驅動DAC以輸出模式量。相位寄存器每過2N/M個外部參考時鐘后返回到初始狀態一次,相位地正弦查詢表每消費品一個循環也回到初始位置,從而使整個DDS系統輸出一個正弦波。輸出的正弦波周期To=Tc2N/M,頻率fout=Mfc/2N,Tc、fc分別為外部參考時鐘的周期和頻率。AD9850采用32位的相位累加器將信號截斷成14位輸入到正弦查詢表,查詢表的輸出再被截斷成10位后輸入到DAC,DAC再輸出兩個互補的電流。DAC滿量程輸出電流通過一個外接電阻RSET調節,調節關系為ISET=32(1.148V/RSET),RSET的典型值是3.9kΩ。將DAC的輸出經低通濾波后接到AD9850內部的高速比較器上即可直接輸出一個抖動很小的方波。AD9850在接上精密時鐘源和寫入頻率相位控制字之間后就可產生一個頻率和相位都可編程控制的模擬正弦波輸出,此正弦波可直接用作頻率信號源或經內部的高速比較器轉換為方波輸出。在125MHz的時鐘下,32位的頻率控制字可使AD9850的輸出頻率分辨率達0.0291Hz;并具有5位相位控制位,而且允許相位按增量180°、90°、45°、22.5°、11.25°或這些值的組合進行調整。流程如圖(2)。

2 .2AD9850 的控制字及控制時序
AD9850 的控制字有 40 位 ,其中 32 位是頻率控制位 ,5 位是相位控制位 ,1 位是電源休眠控制位 ,2 位是工作方式選擇控制位。在應用中 ,工作方式選擇位設為00 ,因為 01 ,10 ,11 已經預留作為工廠測試用。頻率控制位可通過下式計算得到:f out = ( f r ×W) / 232其中: f out 要輸出的頻率值; f r 為參考時鐘頻率;W 為相應的十進制頻率控制字, 然后轉換為十六進制即可。AD9850 有串行和并行兩種控制命令字寫入方式。其中串行寫入方式是采用 D7 作為數據輸入端 ,每次W_CL K的上升沿把一個數據串行移入到輸入寄存器40 位數據都移入后 ,FQ_UD 上升沿完成輸出信號頻率和相位的更新。串行控制字的寫入時序如圖 3 所示。但是要注意的是 ,此時數據輸入端的三個管腳不可懸空 ,其中D0 ,D1 腳接高電平 ,D2腳要接地。


                           圖(3)
2.3管腳定義

3 硬件部分
3.1基于AD9850的模塊原理圖

3.2硬件電路設計
AD9850 控制字的寫入方式有串行和并行兩種。并行寫入方式的優點是數據傳輸的速度快 ,能夠提升整個系統的處理速度 ,但占用的單片機的 I/ O 口資源太多。與并行方式相比 ,串行寫入方式在數據傳輸的速度上要慢些 ,但它更大優點是能節省很多 I/ O 口資源[8 ]。所以 ,本系統采用A T89S52 單片機作為控制核心 ,通過串行寫入控制字的方式控制 AD9850 芯片 ,加上鍵盤和L ED 顯示部分等外圍電路 ,構成整個系統電路。為了詳細介紹 AD9850 的用法 ,這里重點給出本系統中A T89S52 單片機與 AD9850 芯片連接電路 ,如圖 4 所示 ,其中 R1 = 1 kΩ, R2 = 10kΩ, R3 =1kΩ,單片機晶振選用12 MHz ,電容采用 30 p F 經典值。單片機采用12 MHz晶振時 ,它的高電平時間能夠滿足 AD9850 。


            圖(4)
4軟件部分
4.1 軟件部分設計
軟件程序的功能就是通過程序使整個系統按照人們的設想要求工作起來 ,本系統中最主要的部分就是將AD9850 的 40 位控制字通過單片機寫入到 AD9850 芯片內 ,系統的程序流程圖如圖 4 所示。要根據寫入控制字方式的不同嚴格按照 AD9850 的時序圖來編寫控制字寫入子程序。本文主要給出串行寫入方式的C源程序以供讀者調試參考。

4.2參考程序


  1. /*******************************************
  2. 函數:關于AD9850的DDS調頻
  3. ********************************************/
  4. #include <reg52.h>
  5. #include <intrins.h>
  6. #include <string.h>
  7. #define uchar unsigned char
  8. #define uint unsigned int
  9. #define WRITE_DATA_IO P1                               //定義AD9850數據端口
  10. #define LED_DATA_IO P0                                             //定義LED燈數據端口
  11. Unsigned char code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80};                            //設置數碼管段碼0-9
  12. unsigned char code weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};                                                                                    //設置數碼管位碼
  13. uchar WRITE_DATA[5];   //9850頻率和控制字,WRITE_DATA[5]為控制字,其他32位為頻率字
  14. uchar display_data[8];                            //8位數碼管的數值
  15. unsigned long frequence;              //無符號長整形數值,我們需要輸入的頻率
  16. uint MHZ, KHZ , HZ;                                          //將需要的頻率分解為MHZ,KHZ,HZ
  17. uchar AD9850_temp;                                                                      //AD9850工作標志位

  18. sbit W_SLK = P2^0;                                          //AD9850字節輸入,上升沿有效
  19. sbit DQ_VD = P2^1;                                          //AD9850四字節輸入后,上升沿有效
  20. sbit key_unit = P2^2;              //按鍵的個位
  21. sbit key_decade = P2^3;              //按鍵的十位
  22. sbit key_power = P2^4;              //按鍵的十次冪
  23. sbit key_sure = P2^5;   //按鍵確認
  24. sbit weila = P2^6;                            //LED數碼管的位碼
  25. sbit duanla = P2^7;                            //LED數碼管的段碼
  26. /*******************************************
  27. 函    數:延時函數,延時tms
  28. 入口函數:無
  29. 出口頻率:無
  30. ********************************************/
  31. void delay1ms(uchar t)
  32. {
  33.               uchar tt;
  34.               while(t--)
  35.               {            
  36.                             tt= 125;
  37.                             while(tt--);
  38.               }
  39. }
  40. /*************************LED顯示函數**************************************/

  41. /*******************************************
  42. 函    數:初始化定時器0
  43. 入口函數:無
  44. 出口頻率:無
  45. ********************************************/
  46. void INIT_time0()
  47. {
  48.               TMOD |= 0x01;
  49.               TH0 = -2000 / 256;
  50.               TL0 = -2000 % 256;
  51.               EA = 1;
  52.               ET0 = 1;
  53.               TR0 = 1;
  54. }
  55. /*******************************************
  56. 函    數:LED數碼管在start位開始顯示num數據
  57. 入口函數:start是數據從第幾位顯示,num是顯示多少位
  58. 出口頻率:無
  59. ********************************************/
  60. void LED_display(uchar start, uchar num)
  61. {
  62.               static unsigned char i = 0;
  63.               uchar delay = 15;
  64.   if(AD9850_temp == 1)
  65.   {
  66.               display_data[0] = MHZ / 10;                                          //將頻率分解讓數碼管顯示
  67.               display_data[1] = MHZ % 10;
  68.               display_data[2] = KHZ / 100;
  69.               display_data[3] = KHZ % 100 / 10;
  70.               display_data[4] = KHZ % 10;
  71.               display_data[5] = HZ / 100;
  72.               display_data[6] = HZ % 100 / 10;
  73.               display_data[7] = HZ % 10;
  74.   }
  75.               LED_DATA_IO = 0xed;                                                        //顯示兩個小數點
  76.               weila = 1;                   //位碼鎖存
  77.               weila = 0;
  78.             
  79.               LED_DATA_IO = duanma[10];
  80.               duanla = 1;
  81.               duanla = 0;            
  82.               while(delay--);
  83.               LED_DATA_IO = weima[i+start];
  84.               weila = 1;
  85.               weila = 0;
  86.             
  87.               LED_DATA_IO = duanma[display_data[i]];
  88.               duanla = 1;
  89.               duanla = 0;
  90.               i++;
  91.               if(i == num)
  92.                             i = 0;               
  93. }
  94. /*******************************************
  95. 函    數:中斷函數
  96. 入口函數:無
  97. 出口頻率:無
  98. ********************************************/
  99. void INT_time0() interrupt 1
  100. {
  101.                  TH0 = -2000 / 256;
  102.               TL0 = -2000 % 256;
  103.               LED_display(0, 8);
  104. }
  105. /*************************按鍵函數*************************************/
  106. /*******************************************
  107. 函    數:按鍵初始化,確定頻率的大小
  108. 入口函數:無
  109. 出口頻率:無
  110. ********************************************/
  111. void INIT_key()              reentrant                 //可從入函數
  112. {
  113.               uchar unit = 0,decade = 0, power = 0, i;
  114.               AD9850_temp = 0;                                                                                                                //AD9850開始標志位關閉
  115.               memset(display_data, 0, 8);
  116.               while(1)
  117.               {
  118.                             if(key_unit == 0)                                                                      //個位鍵
  119.                             {
  120.                                           delay1ms(20);                                                           //延時,防抖動
  121.                                           if(key_unit == 0)
  122.                                           {
  123.                                                         while(key_unit == 0);
  124.                                                         unit++;
  125.                                                         if(unit == 10 )
  126.                                                                       unit = 0;

  127.                                                                       display_data[6] = unit;
  128.                                           }
  129.                             }

  130.                             if(key_decade == 0)                                                                                    //十位鍵
  131.                             {
  132.                                           delay1ms(20);
  133.                                           if(key_decade == 0)
  134.                                           {
  135.                                                         while(key_decade == 0);
  136.                                                         decade++;
  137.                                                         if(decade == 10)
  138.                                                                       decade = 0;

  139.                                                                       display_data[5] = decade;
  140.                                           }
  141.                             }

  142.                             if(key_power == 0)                                                                                       //10次冪鍵
  143.                             {
  144.                                           delay1ms(20);
  145.                                           if(key_power == 0)
  146.                                           {
  147.                                                         while(key_power == 0);
  148.                                                         power++;
  149.                                                         if(power == 7)
  150.                                                                       power = 0;
  151.                                                                      
  152.                                                                       display_data[7] = power;
  153.                                           }
  154.                             }

  155.                             if(key_sure == 0)                                                                                      //確定鍵
  156.                             {
  157.                                           delay1ms(20);
  158.                                           if(key_sure == 0)
  159.                                           {
  160.                                                         while(key_sure == 0);
  161.                                                         break;
  162.                                           }
  163.                             }                           
  164.               }

  165.               frequence = unit + 10*decade;                                                          //將按鍵得到的數值進行變換,得到我們需要的頻率
  166.               for(i = 1; i <= power; i++)
  167.                             frequence *= 10;
  168.                            
  169.                             if(frequence >= 20000000)                                                        //由于AD9850的頻率范圍是1——20MHZ,所以超過了就重新輸入
  170.                             {
  171.                                           frequence = 0;
  172.                                           INIT_key();
  173.                             }

  174.                             MHZ = frequence / 1000000;                                                        //將頻率分解位MHZ,KHZ,HZ,主要是為了在中斷中計算量少些,以免影響中斷效果
  175.                             KHZ = frequence % 1000000 / 1000;
  176.                             HZ = frequence %1000;
  177.             
  178.               AD9850_temp = 1;                                                                                      //AD9850開始標志位開啟
  179. }

  180. /*************************AD9850函數**************************************/
  181. /*******************************************
  182. 函    數:進行9850的DDS函數發生,寫入控制字,寫入頻率字
  183.           從高字往低字寫
  184. 入口函數:需要的頻率
  185. 出口頻率:無
  186. ********************************************/
  187. void AD9850_WRITE()
  188. {
  189.               unsigned long temp;
  190.               char i;                           
  191.               W_SLK = 0;
  192.               DQ_VD = 0;

  193.                 temp = (unsigned long)(34.359738368 * frequence);
  194.               for(i = 0; i < 4; i++)
  195.               WRITE_DATA[i] = temp >> (i * 8);

  196.               for(i = 4; i >= 0; i--)
  197.               {
  198.                             W_SLK = 0;
  199.                             WRITE_DATA_IO = WRITE_DATA[i];
  200.                             W_SLK = 1;
  201.                             _nop_();
  202.               }
  203.               DQ_VD = 1;
  204. }
  205. /*************************主函數**************************************/
  206. /*******************************************
  207. 函    數:主函數,完成對全局的操控
  208. 入口函數:無
  209. 出口頻率:無
  210. ********************************************/
  211. void main()
  212. {
  213.               INIT_time0();                                          //初始化時間中斷
  214.               while(1)
  215.               {
  216.                             if(key_sure == 0)
  217.                             {
  218.                                           delay1ms(20);
  219.                                           if(key_sure == 0)
  220.                                           {
  221.                                                         while(key_sure == 0);
  222.                                               INIT_key();
  223.                                                         AD9850_WRITE();
  224.                                           }
  225.                             }
  226.               }
  227. }
復制代碼

5波形圖
  1.9MHZ正弦波
   


1HZ方波
  

1HZ正弦波

1MHZ方波
1MHZ實物
1MHZ正弦波
  

6結束語
    本模塊學習是基于AD9850的DDS信號發生器的基礎上,通過了解AD9850的工作原理和工作要求來完成正弦波.矩形波等波形在系統時鐘125M的條件下的學習。
   本次學習得到了精度很高的正弦波和矩形波,其占空比為46.5%已經很接近預期的結果。

以上的Word格式文檔51黑下載地址:
10基于DDS的波形發生器設計 1005014107劉艷珍.doc (1.47 MB, 下載次數: 29)

1005014117-張志超.doc

595 KB, 下載次數: 18, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天操妹子 | 欧美高清一级片 | 久久国产婷婷国产香蕉 | 亚洲女人的天堂 | 成人激情视频 | 久久精品日产第一区二区三区 | 亚洲网站在线观看 | 天堂综合 | 一区二区三区中文字幕 | 国产成人精品久久二区二区91 | 国产香蕉视频 | 久久国产精品久久久久久 | 中文字幕在线一区二区三区 | 欧美一区 | 日韩美女一区二区三区在线观看 | 亚洲一区中文字幕在线观看 | 黑人巨大精品 | 午夜在线精品偷拍 | av毛片| h视频在线免费看 | 久久成人精品视频 | 久久99视频这里只有精品 | 91麻豆精品国产91久久久久久 | 九一精品 | 国产欧美在线一区 | 国产一区二区三区在线 | 国产精品久久久99 | 最新av在线播放 | 亚洲二区在线 | 九热在线 | 成人妇女免费播放久久久 | 欧美国产精品一区二区三区 | 日本在线免费观看 | 91久久精品国产 | 久久久国产一区二区三区 | 99久久婷婷国产综合精品电影 | 精品欧美一区二区三区久久久 | 欧美a区| 黄色国产视频 | 中文字幕免费在线观看 | 青青草这里只有精品 |