| 手上有个DDS模块,本帖就用NUCLEO-U545RE来驱动它。 AD9833是ADI公司生产的一款低功耗,可编程波形发生器,能够产生正弦波、三角波、方波输出。波形发生器广泛应用于各种测量、激励和时域响应领域,AD9833无需外接元件,输出频率和相位都可通过软件编程,易于调节,频率寄存器是28位的,主频时钟为25MHz时,精度为0.1Hz,主频时钟为1MHz时,精度可以达到0.004Hz。
 
 可以通过3个串行接口将数据写入AD983,这3个串口的最高工作频率可以达到40MHz,易于与DSP和各种主流微控制器兼容。AD9833的工作电压范围为2.3V-5.5V。
 
 AD9833还具有休眠功能,可使没被使用的部分休眠,减少该部分的电流损耗,例如,若利用AD9833输岀作为时钟源,就可以让DAC休眠,以减小功耗,该电路采用10引脚MSOP型表面贴片封装,体积很小。
 
 AD9833特点
 频率和相位可数字编程
 工作电压为3V时,功耗仅为20mW
 输出频率范围为OHz-12.5MHz
 频率寄存器为28位(在25Mz的参考时钟下,精度为0.1Hz)
 可选择正弦波、三角波、方波输出
 无需外界元件
 3线SPI接口
 温度范围为-40℃-+105℃
 总结:模块与单片机之间是通过SPI通信的方式,通过对芯片内部寄存器的操作可以调节模块的数据频率和相位。可输出的频率范围是0—13.5MHZ。可以输出正弦波、三角波和方波。
 根据原理图确定管脚:
 
   
 配置如下
 
   
 驱动头文件ad9833.h
 
 驱动源文件ad9833.c复制代码/*************************************************************************************
 Title        :   Analog Devices AD9833 DDS Wave Generator Library for STM32 Using HAL Libraries
 Author:    Bardia Alikhan Afshar <bardia.a.afshar@gmail.com>  
 Software:  IAR Embedded Workbench for ARM
 Hardware:  Any STM32 device
*************************************************************************************/
#ifndef _AD_9833_H
#define _AD_9833_H
#include <math.h>
#include "stm32u5xx_hal.h"
#include "main.h"
// ------------------------- Defines -------------------------
#define FMCLK 25000000        // Master Clock On AD9833
#define AD9833SSPORT ad9833_cs_GPIO_Port      // PORT OF AD9833
#define AD9833DATAPORT ad9833_dat_GPIO_Port      // PORT OF AD9833
#define AD9833SCKPORT ad9833_sck_GPIO_Port      // PORT OF AD9833
#define AD9833DATA ad9833_dat_Pin // SPI DATA PIN
#define AD9833SCK ad9833_sck_Pin  // SPI Clock PIN
#define AD9833SS ad9833_cs_Pin   // SPI Chip Select
#define ASM_NOP() asm("NOP")  // Assembly NOPE (Little Delay)
enum WaveType{SIN, SQR, TRI}; // Wave Selection Enum
// ------------------ Functions  ---------------------
void AD9833_SetWave(uint16_t Wave);                      // Sets Output Wave Type
void AD9833_SetWaveData(float Frequency,float Phase);    // Sets Wave Frequency & Phase
void AD9833_Init(uint16_t Wave,float FRQ,float Phase);   // Initializing AD9833
#endif
 复制代码/*************************************************************************************
 Title        :   Analog Devices AD9833 DDS Wave Generator Library for STM32 Using HAL Libraries
 Author:    Bardia Alikhan Afshar <bardia.a.afshar@gmail.com>  
 Software:  IAR Embedded Workbench for ARM
 Hardware:  Any STM32 device
*************************************************************************************/
#include "AD9833.h"
// ------------------- Variables ----------------
uint16_t FRQLW = 0;    // MSB of Frequency Tuning Word
uint16_t FRQHW = 0;    // LSB of Frequency Tuning Word
uint32_t  phaseVal=0;  // Phase Tuning Value
uint8_t WKNOWN=0;      // Flag Variable
// -------------------------------- Functions --------------------------------
// ------------------------------------------------ Software SPI Function
void writeSPI(uint16_t word) {
        for (uint8_t i = 0; i < 16 ; i++) {
          if(word & 0x8000) HAL_GPIO_WritePin(AD9833DATAPORT,AD9833DATA,GPIO_PIN_SET);   //bit=1, Set High
                else HAL_GPIO_WritePin(AD9833DATAPORT,AD9833DATA,GPIO_PIN_RESET);        //bit=0, Set Low
                __NOP();
                HAL_GPIO_WritePin(ad9833_sck_GPIO_Port,AD9833SCK,GPIO_PIN_RESET);             //Data is valid on falling edge
                __NOP();
                HAL_GPIO_WritePin(ad9833_sck_GPIO_Port,AD9833SCK,GPIO_PIN_SET);
                word = word<<1; //Shift left by 1 bit
        }
        HAL_GPIO_WritePin(AD9833DATAPORT,AD9833DATA,GPIO_PIN_RESET);                    //Idle low
        __NOP();
}
// ------------------------------------------------ Sets Output Wave Type
void AD9833_SetWave(uint16_t Wave){
  switch(Wave){
  case 0:
  HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_RESET);
    writeSPI(0x2000); // Value for Sinusoidal Wave
    HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET);
    WKNOWN=0;
    break;
  case 1:
     HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_RESET);
    writeSPI(0x2028); // Value for Square Wave
    HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET);
    WKNOWN=1;
    break;
  case 2:
        HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_RESET);
    writeSPI(0x2002); // Value for Triangle Wave
    HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET);
    WKNOWN=2;
    break;
  default:
    break;
  }
}
// ------------------------------------------------ Sets Wave Frequency & Phase (In Degree) In PHASE0 & FREQ0 Registers
void AD9833_SetWaveData(float Frequency,float Phase){
__NOP();
 // ---------- Tuning Word for Phase ( 0 - 360 Degree )
 if(Phase<0)Phase=0; // Changing Phase Value to Positive
 if(Phase>360)Phase=360; // Maximum value For Phase (In Degree)
 phaseVal  = ((int)(Phase*(4096/360)))|0XC000;  // 4096/360 = 11.37 change per Degree for Register And using 0xC000 which is Phase 0 Register Address
 
 // ---------- Tuning word for Frequency      
long freq=0;
freq=(int)(((Frequency*pow(2,28))/FMCLK)+1); // Tuning Word
FRQHW=(int)((freq & 0xFFFC000) >> 14); // FREQ MSB
FRQLW=(int)(freq & 0x3FFF);  // FREQ LSB 
FRQLW |= 0x4000;
FRQHW |= 0x4000; 
 // ------------------------------------------------ Writing DATA
 HAL_GPIO_WritePin(AD9833DATAPORT,AD9833DATA,GPIO_PIN_SET);
HAL_GPIO_WritePin(ad9833_sck_GPIO_Port,AD9833SCK,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET);  
 HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_RESET); //low = selected
        __NOP();
        writeSPI(0x2100); // enable 16bit words and set reset bit
        writeSPI(FRQLW);
        writeSPI(FRQHW);
        writeSPI(phaseVal);
        writeSPI(0x2000); // clear reset bit 
        __NOP();
        HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET); //high = deselected 
AD9833_SetWave(WKNOWN);
__NOP();
return;
}
// ------------------------------------------------ Initializing AD9833
void AD9833_Init(uint16_t WaveType,float FRQ,float Phase){
HAL_GPIO_WritePin(AD9833DATAPORT,AD9833DATA,GPIO_PIN_SET); // Set All SPI pings to High
HAL_GPIO_WritePin(ad9833_sck_GPIO_Port,AD9833SCK,GPIO_PIN_SET);  // Set All SPI pings to High
HAL_GPIO_WritePin(AD9833SSPORT,AD9833SS,GPIO_PIN_SET);   // Set All SPI pings to High
AD9833_SetWave(WaveType);                              // Type Of Wave 
AD9833_SetWaveData(FRQ,Phase);                         // Frequency & Phase Set
return;
}
初始化调用接口
 
 
   
 dds模块在扩展板上
 
   
 10KHz正弦波产生效果
 
 
   里面含有直流成分,峰峰值约600mV
 
 
 | 
学习学习,可以做个小的波形发生器了啊
这个可编程波形发生器不错啊