AD9834是一款75 MHz、低功耗DDS器件,能够产生高性能正弦波和三角波输出。其片内还集成一个比较器,支持产生方波以用于时钟发生。当供电电压为3 V时,其功耗仅为20 mW,非常适合对功耗敏感的应用。
AD9834提供相位调制和频率调制功能。频率寄存器为28位;时钟速率为75 MHz,可以实现0.28 Hz的分辨率。同样,时钟速率为1 MHz时,AD9834可以实现0.004 Hz的分辨率。影响频率和相位调制的方法是通过串行接口加载寄存器,然后通过软件或FSELECT/PSELECT引脚切换寄存器。
AD9834通过一个三线式串行接口写入数据。该串行接口能够以最高40 MHz的时钟速率工作,并且与DSP和微控制器标准兼容。
该器件采用2.3 V至5.5 V电源供电。模拟和数字部分彼此独立,可以采用不同的电源供电;例如,AVDD可以是5 V,而DVDD可以是3 V。
AD9834具有掉电引脚(SLEEP),支持从外部控制掉电模式。器件中不用的部分可以掉电,以将功耗降至低点。例如,在产生时钟输出时,可以关断DAC。
该器件采用20引脚TSSOP封装。
应用
频率刺激/波形产生
频率相位调谐和调制
低功耗RF/通信系统
液体和气流测量
传感器应用:接近度、运动和缺陷检测
测试与医疗设备
使用开发板驱动,GPIO模拟SPI
代码
AD9834.h
#ifndef __AD9834_H #define __AD9834_H #include <stdint.h> #include "stm32wbaxx_hal.h" //这里根据芯片的具体信号选择自己的头文件 #include "main.h" #include "usart.h" #include "stdio.h" /*--------------------- AD9834控制信号 16Bit ---------------------*/ /** * @brief 在这部分当中,包括了AD9834大部分控制信号的定义,包括了控制信号的宏定义 * @useage 使用函数AD9834_Write_16Bits()来写入控制信号, * 或者也可以使用AD9834_Select_Wave()来写入(后者通常用于直接使用某种波形) */ //设置基本的波形,默认使用频率寄存器0 #define Triangle_Wave 0x2002 #define Sine_Wave 0x2008 #define Square_Wave 0x2028 //设置使用频率寄存器1 #define Sine_Wave_Reg1 0x2808 #define Square_Wave_Reg1 0x2828 #define Triangle_Wave_Reg1 0x2802 //设置通过引脚选择发生波形 #define SelectByPin 0x2208 //设置PIN_SW 位,选择通过引脚选择频率寄存器、相位和是否不发生波 //在如上的Pin中,包括FS,PS,RESET,SLEEP四根引脚,根据自己的情况写入 //重新复位AD9834 #define RESET_AD9834 0x2100 //停止AD9834的DAC输出 #define STOP_DAC 0x2040 //进阶操作部分 //如果部署需数据手册,不要贸然使用这一部分 //如果使用这部分,请对各个宏进行 | 的运算操作赋予或者使用~进行清除,否则容易出现问题。 #define AD9834_B28 0x2000 //设置为28位模式 #define AD9834_HLB 0x0100 //设置为高速模式,不要轻易使用 #define AD9834_RESET 0x0100 //复位AD9834 #define AD9834_SLEEP1 0x0080 //设置为睡眠模式1 #define AD9834_SLEEP12 0x0040 //设置为睡眠模式2 #define AD9834_OPBITEN 0x0020 //设置为输出使能 #define AD9834_DIV2 0x0010 //设置为分频模式 #define AD9834_MODE 0x0002 //设置为三角波模式 #define AD9834_SIGN_PIBIT 0x0001 //设置为正弦波模式 #define AD9834_PHASE 0xC000 //设置相位寄存器0 #define AD98er_PHASE1 0xE000 //设置相位寄存器1 //------------------AD9834控制和器件特性------------------// /** * @brief 在这部分中,包括了AD9834的一些特性,包括了AD9834的一些控制引脚和所用时钟 * @notice 在使用AD9834时,需要根据自己的情况修改这部分的内容 */ /* AD9834晶振频率 */ #define AD9834_SYSTEM_COLCK 75000000UL /* AD9834 控制引脚 */ #define AD9834_FSYNC AD9834_FSYNC_Pin #define AD9834_SCLK AD9834_SCLK_Pin #define AD9834_SDATA AD9834_SDATA_Pin #define AD9834_RESET AD9834_RESET_Pin #define AD9834_FS AD9834_FS_Pin #define AD9834_PS AD9834_PS_Pin //为兼容标准库,提供如下宏 #define GPIO_SetBits(x,y) HAL_GPIO_WritePin((x),(y),GPIO_PIN_SET) #define GPIO_ResetBits(x,y) HAL_GPIO_WritePin((x),(y),GPIO_PIN_RESET) //为了便于操作数据引脚,提供如下宏 #define AD9834_FSYNC_SET GPIO_SetBits(AD9834_FSYNC_GPIO_Port ,AD9834_FSYNC) #define AD9834_FSYNC_CLR GPIO_ResetBits(AD9834_FSYNC_GPIO_Port ,AD9834_FSYNC) #define AD9834_SCLK_SET GPIO_SetBits(AD9834_SCLK_GPIO_Port ,AD9834_SCLK) #define AD9834_SCLK_CLR GPIO_ResetBits(AD9834_SCLK_GPIO_Port ,AD9834_SCLK) #define AD9834_SDATA_SET GPIO_SetBits(AD9834_SDATA_GPIO_Port ,AD9834_SDATA) #define AD9834_SDATA_CLR GPIO_ResetBits(AD9834_SDATA_GPIO_Port ,AD9834_SDATA) #define AD9834_RESET_SET GPIO_SetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) #define AD9834_RESET_CLR GPIO_ResetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) //为了便于操作频率等控制引脚,提供如下宏 #define AD9834_FS_SET GPIO_SetBits(AD9834_FS_GPIO_Port ,AD9834_FS) #define AD9834_FS_CLR GPIO_ResetBits(AD9834_FS_GPIO_Port ,AD9834_FS) #define AD9834_PS_SET GPIO_SetBits(AD9834_PS_GPIO_Port ,AD9834_PS) #define AD9834_PS_CLR GPIO_ResetBits(AD9834_PS_GPIO_Port ,AD9834_PS) #define AD9834_RST_SET GPIO_SetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) #define AD9834_RST_CLR GPIO_ResetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) /*--------------------- AD9834操作位声明 ---------------------*/ /** * @brief 这部分包括了AD9834的一些操作位的声明,包括了AD9834的一些操作位的宏定义 * @useage 使用函数AD9834_Write_16Bits()来写入控制信号。 * @notice 如果有不明便的地方,查阅数据手册进行更改 */ //频率寄存器的控制位 #define FREQ_0 0 #define FREQ_1 1 #define PHASE_0 0 #define PHASE_1 1 //各个位的定义,留空为0 //如果需要使用其他位,请自行添加相关的变量/宏的定义 #define DB15 0 #define DB14 0 #define DB13 B28 #define DB12 HLB #define DB11 FSEL #define DB10 PSEL #define DB9 PIN_SW #define DB8 RESET #define DB7 SLEEP1 #define DB6 SLEEP12 #define DB5 OPBITEN #define DB4 SIGN_PIB #define DB3 DIV2 #define DB2 0 #define DB1 MODE #define DB0 0 //通过操作位的宏定义,可以得到控制信号的值 //可以通过AD9834_Write_16Bits()函数来直接写入控制信号 #define CONTROL_REGISTER (DB15<<15)|(DB14<<14)|(DB13<<13)|(DB12<<12)|(DB11<<11)|(DB10<<10)|(DB9<<9)|(DB8<<8)|(DB7<<7)|(DB6<<6)|(DB5<<5)|(DB4<<4)|(DB3<<3)|(DB2<<2)|(DB1<<1)|(DB0<<0) /*--------------------- AD9834函数声明 ---------------------*/ void AD9834_Write_16Bits(unsigned int data); //写一个字到AD9834 void AD9834_Select_Wave(unsigned int initdata); //选择输出波形 void AD9834_Init(void); //初始化配置 void AD9834_Set_Freq(unsigned char freq_number, unsigned long freq);//选择输出寄存器和输出频率值 #endif /* AD9834_H */
AD9834.c
/********************************************************** 功能:75MHz时钟, AD9834正弦波点频输出,范围0-30M(可编辑0-100M), 方波:50k-5M,三角波:0-10M,扫频默认正弦波 。 接口:控制接口请参照AD9834.h 时间:2022/10/08 版本:0.9 作者:康威电子(原作者) **********************************************************/ #include "AD9834.h" /**************************************************************** 函数名称: AD9834_Write_16Bits 功 能: 向AD9834写入16为数据 参 数: data -- 要写入的16位数据 返回值 : 无 *****************************************************************/ void AD9834_Write_16Bits(unsigned int data) { unsigned char i = 0; AD9834_SCLK_SET; AD9834_FSYNC_CLR; for (i = 0;i < 16;i++) { if (data & 0x8000) AD9834_SDATA_SET; else AD9834_SDATA_CLR; AD9834_SCLK_CLR; data <<= 1; AD9834_SCLK_SET; } AD9834_SDATA_SET; AD9834_FSYNC_SET; } /*********************************************************************************** 函数名称:AD9834_Select_Wave 功 能:写控制位控制, -------------------------------------------------- IOUT正弦波 ,SIGNBITOUT方波 ,写FREQREG0 ,写PHASE0 ad9834_write_16bit(0x2028) 一次性写FREQREG0 ad9834_write_16bit(0x0038) 单独改写FREQREG0的LSB ad9834_write_16bit(0x1038) 单独改写FREQREG0的MSB -------------------------------------------------- IOUT三角波 ,写PHASE0 ad9834_write_16bit(0x2002) 一次性写FREQREG0 ad9834_write_16bit(0x0002) 单独改写FREQREG0的LSB ad9834_write_16bit(0x1008) 单独改写FREQREG0的MSB 参 数:initdata -- 要输入的命令 返回值 :无 注 意: 大部分情况下,只需要写入一次,除非要改变波形类型。 同样可以通过改变控制位来改变波形类型,但是这样会导致频率和相位的改变。 ************************************************************************************/ void AD9834_Select_Wave(unsigned int initdata) { AD9834_FSYNC_SET; AD9834_SCLK_SET; AD9834_RESET_SET; AD9834_RESET_SET; AD9834_RESET_CLR; AD9834_Write_16Bits(initdata); } /**************************************************************** 函数名称: Init_AD9834 功 能: 初始化后将FS和PS引脚设置为低。 参 数: 无 返回值 : 无 *****************************************************************/ // B6 FS B5 PS B7 FSY B8 SCK B9 SDA B10 RST void AD9834_Init() { GPIO_ResetBits(AD9834_FS_GPIO_Port, AD9834_FS); GPIO_ResetBits(AD9834_PS_GPIO_Port, AD9834_PS); } /**************************************************************** 函数名称: AD9834_Set_Freq 功 能: 设置频率值 参 数: freq_number -- 要写入的平率寄存器(FREQ_0或FREQ_1) freq -- 频率值,直接填写赫兹,换算公式为: (Freq_value(value)=Freq_data(data)*FCLK/2^28) //此时FCLK=75MHz,所以Freq_value=Freq_data*75/2^28 返回值 : 无 *****************************************************************/ void AD9834_Set_Freq(unsigned char freq_number, unsigned long freq) { unsigned long FREQREG = (unsigned long)(268435456.0 / AD9834_SYSTEM_COLCK * freq); unsigned int FREQREG_LSB_14BIT = (unsigned int)FREQREG; unsigned int FREQREG_MSB_14BIT = (unsigned int)(FREQREG >> 14); if (freq_number == FREQ_0) { FREQREG_LSB_14BIT &= ~(1U << 15); FREQREG_LSB_14BIT |= 1 << 14; FREQREG_MSB_14BIT &= ~(1U << 15); FREQREG_MSB_14BIT |= 1 << 14; } else { FREQREG_LSB_14BIT &= ~(1 << 14); FREQREG_LSB_14BIT |= 1U << 15; FREQREG_MSB_14BIT &= ~(1 << 14); FREQREG_MSB_14BIT |= 1U << 15; } AD9834_Write_16Bits(FREQREG_LSB_14BIT); AD9834_Write_16Bits(FREQREG_MSB_14BIT); } //============================================================// /* 注:使用时先调用初始化函数初始化IO配置,然后调用AD9834_Select_Wave()选择(基本的三种波形为频率寄存器0) 波形,最后选择频率值即可输出。 */
主函数调用
AD9834_Init(); AD9834_Select_Wave(Sine_Wave);//Sine_Wave Square_Wave Triangle_Wave AD9834_Set_Freq(FREQ_0, 1000);
效果