手上有个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
- /*************************************************************************************
- 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
复制代码 驱动源文件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
- *************************************************************************************/
- #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
|
学习学习,可以做个小的波形发生器了啊
这个可编程波形发生器不错啊