1. 程式人生 > 實用技巧 >AD9833波形訊號發生器(STM32F407VET6驅動,標準庫)原始碼

AD9833波形訊號發生器(STM32F407VET6驅動,標準庫)原始碼

連線自己的STM32F407開發板時,只需用修改GPIO就可直接使用,如果不是採用STM32F407開發板,則可能需要修改一下標頭檔案以及相關程式碼,但也不是很複雜

AD9833.h

 1 #ifndef _AD_9833_H
 2 #define _AD_9833_H
 3 #include <math.h>
 4 #include "sys.h"
 5 
 6 // ------------------------- Defines -------------------------
 7 #define FMCLK 25000000        // Master Clock On AD9833
8 #define AD9833PORT GPIOE // PORT OF AD9833 9 #define AD9833DATA GPIO_Pin_7 // SPI DATA PIN 10 #define AD9833SCK GPIO_Pin_8 // SPI Clock PIN 11 #define AD9833SS GPIO_Pin_9 // SPI Chip Select 12 #define ASM_NOP() 13 // Assembly NOPE (Little Delay) 14 enum WaveType{SIN, SQR, TRI}; // Wave Selection Enum
15 16 // ------------------ Functions --------------------- 17 void AD9833_SetWave(u16 Wave); // Sets Output Wave Type 18 void AD9833_SetWaveData(float Frequency,float Phase); // Sets Wave Frequency & Phase 19 void AD9833_Init(u16 Wave,float FRQ,float Phase); // Initializing AD9833
20 #endif

AD9833.c

  1 /*************************************************************************************
  2  Title    :   Analog Devices AD9833 DDS Wave Generator Library for STM32 Using HAL Libraries
  3  Author:    Bardia Alikhan Afshar <[email protected]>  
  4  Software:  IAR Embedded Workbench for ARM
  5  Hardware:  Any STM32 device
  6 *************************************************************************************/
  7 #include "AD9833.h"
  8 
  9 /*
 10   VCC   ---     3.3V
 11   SDATA ---     PC12 
 12   SCLK  ---     PC10
 13   FSYNC ---     PC11   
 14 
 15 */
 16 // ------------------- Variables ----------------
 17 u16 FRQLW = 0;    // MSB of Frequency Tuning Word
 18 u16 FRQHW = 0;    // LSB of Frequency Tuning Word
 19 u32  phaseVal=0;  // Phase Tuning Value
 20 u8 WKNOWN=0;      // Flag Variable
 21 // -------------------------------- Functions --------------------------------
 22 
 23 // ----------------- Software SPI Function
 24 void writeSPI(u16 word) {
 25     u8 i;
 26     for (i = 0; i < 16 ; i++) {
 27           if(word & 0x8000) GPIO_SetBits(AD9833PORT,AD9833DATA);   //bit=1, Set High
 28         else GPIO_ResetBits(AD9833PORT,AD9833DATA);        //bit=0, Set Low
 29         ASM_NOP();
 30         GPIO_ResetBits(AD9833PORT,AD9833SCK);             //Data is valid on falling edge
 31         ASM_NOP();
 32         GPIO_SetBits(AD9833PORT,AD9833SCK);
 33         word = word<<1; //Shift left by 1 bit
 34         }
 35     GPIO_ResetBits(AD9833PORT,AD9833DATA);                    //Idle low
 36     ASM_NOP();
 37 }
 38 
 39 // ------------------------------------------------ Sets Output Wave Type
 40 void AD9833_SetWave(u16 Wave){
 41   switch(Wave){
 42   case 0:
 43   GPIO_ResetBits(AD9833PORT,AD9833SS);
 44     writeSPI(0x2000); // Value for Sinusoidal Wave
 45     GPIO_SetBits(AD9833PORT,AD9833SS);
 46     WKNOWN=0;
 47     break;
 48   case 1:
 49     GPIO_ResetBits(AD9833PORT,AD9833SS);
 50     writeSPI(0x2028); // Value for Square Wave
 51     GPIO_SetBits(AD9833PORT,AD9833SS);
 52     WKNOWN=1;
 53     break;
 54   case 2:
 55         GPIO_ResetBits(AD9833PORT,AD9833SS);
 56     writeSPI(0x2002); // Value for Triangle Wave
 57     GPIO_SetBits(AD9833PORT,AD9833SS);
 58     WKNOWN=2;
 59     break;
 60   default:
 61     break;
 62   }
 63 }
 64 
 65 // ------------------------------------------------ Sets Wave Frequency & Phase (In Degree) In PHASE0 & FREQ0 Registers
 66 void AD9833_SetWaveData(float Frequency,float Phase){
 67     long freq=0;
 68     ASM_NOP();
 69      // ---------- Tuning Word for Phase ( 0 - 360 Degree )
 70      if(Phase<0)Phase=0; // Changing Phase Value to Positive
 71      if(Phase>360)Phase=360; // Maximum value For Phase (In Degree)
 72      phaseVal  = ((int)(Phase*(4096/360)))|0XC000;  // 4096/360 = 11.37 change per Degree for Register And using 0xC000 which is Phase 0 Register Address
 73      
 74      // ---------- Tuning word for Frequency      
 75     freq=(int)(((Frequency*pow(2,28))/FMCLK)+1); // Tuning Word
 76     FRQHW=(int)((freq & 0xFFFC000) >> 14); // FREQ MSB
 77     FRQLW=(int)(freq & 0x3FFF);  // FREQ LSB 
 78     FRQLW |= 0x4000;
 79     FRQHW |= 0x4000; 
 80      // ------------------------------------------------ Writing DATA
 81         GPIO_SetBits(AD9833PORT,AD9833DATA);
 82         GPIO_SetBits(AD9833PORT,AD9833SCK);
 83         GPIO_SetBits(AD9833PORT,AD9833SS);  
 84         GPIO_ResetBits(AD9833PORT,AD9833SS); //low = selected
 85         ASM_NOP();
 86         writeSPI(0x2100); // enable 16bit words and set reset bit
 87         writeSPI(FRQLW);
 88         writeSPI(FRQHW);
 89                     writeSPI(phaseVal);
 90         writeSPI(0x2000); // clear reset bit 
 91         ASM_NOP();
 92         GPIO_SetBits(AD9833PORT,AD9833SS); //high = deselected 
 93     AD9833_SetWave(WKNOWN);
 94     ASM_NOP();
 95     return;
 96 }
 97 
 98 // ------------------------------------------------ Initializing AD9833
 99 void AD9833_Init(u16 WaveType,float FRQ,float Phase){
100     GPIO_InitTypeDef  GPIO_InitStructure;
101     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOF時鐘
102 
103   //GPIOF9,F10初始化設定
104   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
105   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通輸出模式
106   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推輓輸出
107   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
108   GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化
109     GPIO_SetBits(GPIOE,GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9);
110     
111     
112     
113     GPIO_SetBits(AD9833PORT,AD9833DATA); // Set All SPI pings to High
114     GPIO_SetBits(AD9833PORT,AD9833SCK);  // Set All SPI pings to High
115     GPIO_SetBits(AD9833PORT,AD9833SS);   // Set All SPI pings to High
116     AD9833_SetWave(WaveType);                              // Type Of Wave 
117     AD9833_SetWaveData(FRQ,Phase);                         // Frequency & Phase Set
118     return;
119 }