电赛总结(四)——波形发生芯片总结之AD9834
一、特性参数
1、2.3V~5.5V供电
2、输出频率高达37.5MHz
3、正弦波、三角波输出
4、提供相位调制和频率调制功能
5、除非另有说明,VDD = 2.3 V至5.5 V,AGND = DGND = 0 V,TA = TMIN至TMAX,RSET = 6.8 k,RLOAD = 200 (对于IOUT和IOUTB)。
二、芯片管脚图
三、管脚功能说明
管脚名称 | 功能 |
FS ADJUST | 此引脚和AGND之间连接一个电阻(RSET),从而决定满量程DAC电流的幅度。RSET与满量程电流之间的关系如下: IOUT FULL SCALE = 18 × FSADJUST/RSET |
REFOUT | 基准电压输出。AD9834通过此引脚提供1.20 V内部基准电压源。 |
COMP | DAC偏置引脚。此引脚用于对DAC偏置电压进行去耦。 |
VIN | 比较器输入。可利用比较器从正弦DAC输出产生方波。DAC输出应经过适当滤波,然后再施加于比较器,以改善抖动性能。当控制寄存器中的Bit OPBITEN和Bit SIGN/PIB置1时,比较器输入端连接到VIN。 |
IOUT, | 电流输出。这是高阻抗电流源。应在IOUT和AGND之间连接一个标称值为200 的负载电阻。IOUTB最好应通过一个大小为200 的外部负载电阻连接到AGND,但也可直接与AGND相连。此外还建议通过一个20 pF电容连接到AGND,以防止出现时钟馈通。 |
AVDD | 模拟部分的正电源。AVDD的值范围为2.3 V至5.5 V。应在AVDD和AGND之间连接一个0.1uF去耦电容。 |
DVDD | 数字部分的正电源。DVDD的值范围为2.3 V至5.5 V。应在DVDD和DGND之间连接一个0.1uF去耦电容。 |
CAP/2.5V | 数字电路采用2.5 V电源供电。当DVDD超过2.7 V时,此2.5 V利用片内调节器从DVDD产生。该调节器需要在CAP/2.5 V至DGND之间连接一个典型值为100 nF的去耦电容。如果DVDD小于或等于2.7 V,则CAP/2.5 V应与DVDD直接相连。 |
DGND | 数字地。 |
AGND | 模拟地。 |
MCLK | 数字时钟输入。DDS输出频率是MCLK频率的一个分数,分数的分子是二进制数。输出频率精度和相位噪声均由此时钟决定。 |
FSELECT | 频率选择输入。FSELECT控制相位累加器中使用的具体频率寄存器(FREQ0或FREQ1)。可使用引脚FSELECT或BitFSEL来选择要使用的频率寄存器。使用Bit FSEL来选择频率寄存器时,FSELECT引脚应与CMOS高电平或低电平相连。 |
PSELECT | 相位选择输入。PSELECT控制将增加到相位累加器输出的具体相位寄存器(PHASE0或PHASE1)。可使用引脚PSELECT或Bit PSEL来选择要使用的相位寄存器。当相位寄存器由Bit PSEL控制时,PSELECT引脚应与CMOS高电平或低电平相连 |
RESET | 高电平有效数字输入。RESET可使相应的内部寄存器复位至0,以提供中间电平的模拟输出。RESET不影响任何可寻址寄存器。 |
SLEEP | 高电平有效数字输入。当此引脚处于高电平时,DAC关断。此引脚功能与控制位SLEEP12相同。 |
SDATA | 串行数据输入。16位串行数据字施加于此输入。 |
SCLK | 串行时钟输入。数据在每个SCLK下降沿逐个输入AD9834。 |
FSYNC | 低电平有效控制输入。这是输入数据的帧同步信号。当FSYNC变为低电平时,即告知内部逻辑,正在向器件 |
SIGN BIT | 逻辑输出。比较器输出通过此引脚提供,或者可通过此引脚输出NCO的MSB。通过将控制寄存器中的Bit |
四、寄存器
一个16位的控制寄存器。设置好之后即可产生对应的波形
五、STM32F103驱动代码
#ifndef __AD9834_H #define __AD9834_H #include "stm32f10x.h" #include "pbdata.h" #include "gpio.h" #define FSYNC Pin9 #define SDATA Pin10 #define SCLK Pin11 #define RESET Pin12 #define FCLK 50 enum Phase { Sine, Triangle, Square }; void Ad9834_init(enum Phase ph,u32 freq); void Send_Phase(void); void Ad9834_Send_Freq(u16 Freq_word); void Ad9834_Send_Con(u16 Con_word); #endif /* __DAC_H */
#include "ad9834.h" #include "math.h" void Ad9834_init(enum Phase ph,u32 freq) { u32 fre= (u32)freq / 20000.0 * pow(2,28) - 1; u16 fre_high = fre / 0x4000 + 0x4000; u16 fre_low = fre % 0x4000 + 0x4000; set_out(GPIOG, FSYNC | SDATA | SCLK | RESET); set_outH(GPIOG,FSYNC); set_outH(GPIOG,SCLK); set_outH(GPIOG,RESET); delay_us(10); set_outH(GPIOG,RESET); delay_us(10); set_outL(GPIOG,RESET); delay_ms(10); if(ph==Sine) { Ad9834_Send_Con(0x2038); } else if(ph==Triangle) { Ad9834_Send_Con(0x2002); } else { Ad9834_Send_Con(0x2020); } delay_us(10); Ad9834_Send_Freq(fre_low); delay_us(10); Ad9834_Send_Freq(fre_high); // Send_Phase(); } void Ad9834_Send_Con(u16 Con_word) { u8 i; set_outL(GPIOG,FSYNC); set_outH(GPIOG,SCLK); for(i=0;i<16;i++) { if(Con_word & 0x8000) { set_outH(GPIOG,SDATA); } else { set_outL(GPIOG,SDATA); } Con_word<<=1; set_outL(GPIOG,SCLK); delay_us(10); set_outH(GPIOG,SCLK); } set_outH(GPIOG,FSYNC); } void Ad9834_Send_Freq(u16 Freq_word) { u8 i; set_outL(GPIOG,FSYNC); set_outH(GPIOG,SCLK); for(i=0;i<16;i++) { if((Freq_word & 0x8000) == 0x8000) { set_outH(GPIOG,SDATA); } else { set_outL(GPIOG,SDATA); } Freq_word<<=1; set_outL(GPIOG,SCLK); delay_us(10); set_outH(GPIOG,SCLK); } set_outH(GPIOG,FSYNC); } void Send_Phase(void) { Ad9834_Send_Con(0xC000); }