AD9833直接输出任意波形 数字可调
AD9833是一款低功耗直接数字频率合成(DDS)设备,支持高达25 MHz的时钟速率。
这款低功耗DDS器件是一款数控振荡器,采用了相位累加器、正弦ROM和10位D/A转换器,并集成在单个CMOS芯片上。支持最高25 MHz的时钟频率,电源电压范围为+2.3 V至+5.5 V。 具备相位调制和频率调制能力。频率精度可控制在0.25亿分之一。调制通过串行接口加载寄存器实现。 AD9833通过VOUT引脚提供多种输出波形。可以绕过正弦ROM,使DAC输出线性升降斜坡信号。若不绕过正弦ROM,则可输出正弦波。此外,若需要时钟输出,可输出DAC数据的最高有效位。 无论VDD值是多少,当VDD超过+2.5 V时,片上稳压器会将VDD降压至+2.5 V,使数字部分内部以+2.5 V运行。 AD9833具备掉电功能(SLEEP)。这允许关闭未使用的器件部分,从而使该器件的电流消耗最小化。例如,在生成时钟输出时可关闭DAC。 AD9833采用10引脚μsoIC封装。
封装 MSOP-10
AD9833BRMZ-REEL7
时钟频率(fc) 25MHz
特性
+2.3 V至±5.5 V电源
25 MHz速度
微型10引脚μs0|0封装
串行加载
正弦/三角DAC输出
掉电选项
窄带无杂散动态范围(SFDR)> 72 dB
3 V电压下功耗20 mW
驱动程序
// -------------------------- 1. 引脚定义(需根据硬件接线修改)--------------------------
// 规格书10. PIN DESCRIPTION:3线串行接口(SCLK/SDATA/FSYNC为数字输入)
#define AD9833_SCLK_PIN GPIO_PIN_3
#define AD9833_SCLK_PORT GPIOA
#define AD9833_SDATA_PIN GPIO_PIN_4
#define AD9833_SDATA_PORT GPIOA
#define AD9833_FSYNC_PIN GPIO_PIN_2
#define AD9833_FSYNC_PORT GPIOA
// -------------------------- 2. 寄存器地址与控制位(源自规格书Table 1-Table 8)--------------------------
// 控制寄存器(D15=0,D14=0)
#define AD9833_REG_CTRL 0x0000
// 频率寄存器(D15,D14标识地址)
#define AD9833_REG_FREQ0 0x4000 // FREQ0:D15=0,D14=1
#define AD9833_REG_FREQ1 0x8000 // FREQ1:D15=1,D14=0
// 相位寄存器(D15=1,D14=1;D13标识寄存器)
#define AD9833_REG_PHASE0 0xC000 // PHASE0:D13=0
#define AD9833_REG_PHASE1 0xE000 // PHASE1:D13=1
// 控制寄存器位定义(规格书Table 2)
#define AD9833_CTRL_B28 0x2000 // 28位频率字模式(1=分两次写28位,0=14位独立写)
#define AD9833_CTRL_HLB 0x1000 // 14位频率字选择(1=MSB,0=LSB;仅B28=0时有效)
#define AD9833_CTRL_FSELECT 0x0800 // 频率寄存器选择(1=FREQ1,0=FREQ0)
#define AD9833_CTRL_PSELECT 0x0400 // 相位寄存器选择(1=PHASE1,0=PHASE0)
#define AD9833_CTRL_RESET 0x0100 // 复位(1=复位,0=正常;规格书11. RESET Function)
#define AD9833_CTRL_SLEEP1 0x0080 // 内部时钟断电(1=禁用,0=启用;规格书12. Sleep Function)
#define AD9833_CTRL_SLEEP12 0x0040 // DAC断电(1=断电,0=启用;规格书12. Sleep Function)
#define AD9833_CTRL_OPBITEN 0x0020 // 输出模式选择(1=数字输出,0=DAC输出;规格书13. VOUT Pin)
#define AD9833_CTRL_DIV2 0x0008 // 数字输出分频(1=MSB,0=MSB/2;仅OPBITEN=1时有效)
#define AD9833_CTRL_MODE 0x0002 // DAC输出波形(1=三角波,0=正弦波;规格书13. VOUT Pin)
// 补充:MODE=0(启用SIN ROM,输出正弦波),与AD9833_CTRL_MODE(MODE=1)对应
#define AD9833_CTRL_MODE_0 0x0000 // 规格书Table 11:MODE=0时启用SIN ROM
//#define AD9833_CTRL_MODE 0x0002 // 原定义保留:MODE=1时bypass SIN ROM(三角波)
// -------------------------- 3. 宏定义(基于规格书关键参数)--------------------------
#define AD9833_MCLK 25000000UL // 主时钟频率(最高25MHz,规格书FEATURES)
#define AD9833_PHASE_MAX 4096UL // 相位寄存器最大值(12位,规格书Table 3)
#define AD9833_FREQ_MAX 0xFFFFFFFUL// 频率寄存器最大值(28位,规格书Table 3)
// -------------------------- 1. 引脚操作宏(简化GPIO控制)--------------------------
#define AD9833_SCLK_HIGH() std_gpio_set_pin(AD9833_SCLK_PORT, AD9833_SCLK_PIN)
#define AD9833_SCLK_LOW() std_gpio_reset_pin(AD9833_SCLK_PORT, AD9833_SCLK_PIN)
#define AD9833_SDATA_HIGH() std_gpio_set_pin(AD9833_SDATA_PORT, AD9833_SDATA_PIN)
#define AD9833_SDATA_LOW() std_gpio_reset_pin(AD9833_SDATA_PORT, AD9833_SDATA_PIN)
#define AD9833_FSYNC_HIGH() std_gpio_set_pin(AD9833_FSYNC_PORT, AD9833_FSYNC_PIN)
#define AD9833_FSYNC_LOW() std_gpio_reset_pin(AD9833_FSYNC_PORT, AD9833_FSYNC_PIN)
// -------------------------- 4. 函数声明 --------------------------
/**
* @brief AD9833引脚初始化(SCLK/SDATA推挽输出,FSYNC推挽输出)
* @note 规格书10. PIN DESCRIPTION:数字引脚支持CMOS电平(VINH=VDD-0.9~VDD,VINL=0~0.9V)
*/
void AD9833_Init(void);
/**
* @brief 向AD9833写入16位数据(规格书9. Serial Interface时序)
* @param data: 16位数据(寄存器地址+数据/控制位)
*/
void AD9833_WriteData(uint16_t data);
/**
* @brief 配置AD9833输出频率(规格书8. CIRCUIT DESCRIPTION:f_OUT = FREQ_REG × f_MCLK / 2^28)
* @param freq_reg: 频率寄存器(AD9833_REG_FREQ0/AD9833_REG_FREQ1)
* @param freq_hz: 目标输出频率(单位:Hz,最大≤AD9833_MCLK/2)
*/
void AD9833_SetFrequency(uint16_t freq_reg, uint32_t freq_hz);
/**
* @brief 配置AD9833输出相位(规格书8. CIRCUIT DESCRIPTION:相位偏移=PHASE_REG × 2π / 4096)
* @param phase_reg: 相位寄存器(AD9833_REG_PHASE0/AD9833_REG_PHASE1)
* @param phase_deg: 目标相位偏移(单位:°,范围0~360)
*/
void AD9833_SetPhase(uint16_t phase_reg, float phase_deg);
/**
* @brief 配置AD9833输出波形(规格书13. VOUT Pin:正弦波/三角波/方波)
* @param wave_type: 波形类型(0=正弦波,1=三角波,2=方波(MSB),3=方波(MSB/2))
*/
void AD9833_SetWaveform(uint8_t wave_type);
/**
* @brief 控制AD9833休眠模式(规格书12. Sleep Function)
* @param sleep_mode: 休眠模式(0=无休眠,1=DAC休眠,2=时钟休眠,3=深度休眠)
*/
void AD9833_SetSleepMode(uint8_t sleep_mode);
void AD9833_Init(void)
{
std_gpio_init_t AD9833_gpio_config = {0};
// SCLK/SDATA/FSYNC配置为推挽输出(频率≤40MHz,规格书TIMING CHARACTERISTICS)
AD9833_gpio_config.pin = AD9833_SCLK_PIN | AD9833_SDATA_PIN | AD9833_FSYNC_PIN;
AD9833_gpio_config.mode = GPIO_MODE_OUTPUT;
AD9833_gpio_config.pull = GPIO_NOPULL;
AD9833_gpio_config.output_type = GPIO_OUTPUT_PUSHPULL;
std_gpio_init(GPIOA, &AD9833_gpio_config);
// 初始化引脚电平(FSYNC默认高电平,SCLK默认高电平;规格书Figure 3. Serial Timing)
AD9833_FSYNC_HIGH();
AD9833_SCLK_HIGH();
AD9833_SDATA_LOW();
// 复位AD9833(规格书11. RESET Function:上电后需复位,避免DAC输出异常)
AD9833_WriteData(AD9833_REG_CTRL | AD9833_CTRL_RESET);
std_delayms(20); // 等待复位完成(规格书唤醒时间典型1ms,此处留足余量)
AD9833_WriteData(AD9833_REG_CTRL & ~AD9833_CTRL_RESET); // 退出复位
}
// -------------------------- 3. 串行数据写入(严格遵循规格书时序)--------------------------
void AD9833_WriteData(uint16_t data) {
uint8_t i;
// 步骤1:拉低FSYNC,开始数据传输(规格书Figure 3:FSYNC低电平有效)
AD9833_FSYNC_LOW();
std_delayus(10); // 满足FSYNC建立时间t7≥5ns(规格书TIMING CHARACTERISTICS)
// 步骤2:16位数据逐位写入(MSB先传,SCLK下降沿锁存;规格书9. Serial Interface)
for (i = 0; i < 16; i++) {
AD9833_SCLK_HIGH(); // SCLK先置高,准备下降沿
std_delayus(10);
// 输出当前位(从最高位D15开始)
if (data & (0x8000 >> i)) {
AD9833_SDATA_HIGH();
} else {
AD9833_SDATA_LOW();
}
std_delayus(10); // 满足数据建立时间t9≥5ns
// SCLK下降沿锁存数据(规格书Figure 3:数据在SCLK下降沿被采样)
AD9833_SCLK_LOW();
std_delayus(10);
}
// 步骤3:拉高FSYNC,结束数据传输(满足SCLK下降沿到FSYNC上升沿时间t8≥10ns)
AD9833_SCLK_HIGH();
std_delayus(10);
AD9833_FSYNC_HIGH();
}
// -------------------------- 4. 频率配置(基于规格书频率计算公式)--------------------------
void AD9833_SetFrequency(uint16_t freq_reg, uint32_t freq_hz) {
uint64_t freq_word;
uint16_t ctrl_word;
// 1. 计算频率字(规格书8. CIRCUIT DESCRIPTION:FREQ_REG = f_OUT × 2^28 / f_MCLK)
if (freq_hz > AD9833_MCLK / 2) {
freq_hz = AD9833_MCLK / 2; // 输出频率最大为MCLK/2(奈奎斯特准则)
}
freq_word = (uint64_t)freq_hz * AD9833_FREQ_MAX / AD9833_MCLK;
// 2. 配置28位频率字模式(B28=1,分两次写入14位LSB和14位MSB;规格书Table 5)
ctrl_word = AD9833_REG_CTRL | AD9833_CTRL_B28;
AD9833_WriteData(ctrl_word);
// 3. 写入14位LSB(freq_reg地址 + 低14位数据)
AD9833_WriteData(freq_reg | (uint16_t)(freq_word & 0x3FFF));
// 4. 写入14位MSB(freq_reg地址 + 高14位数据)
AD9833_WriteData(freq_reg | (uint16_t)((freq_word >> 14) & 0x3FFF));
// 5. 恢复B28=0(可选,不影响后续操作)
ctrl_word = AD9833_REG_CTRL & ~AD9833_CTRL_B28;
AD9833_WriteData(ctrl_word);
}
// -------------------------- 5. 相位配置(基于规格书相位计算公式)--------------------------
void AD9833_SetPhase(uint16_t phase_reg, float phase_deg) {
uint16_t phase_word;
// 1. 相位范围限制(0~360°)
if (phase_deg < 0) phase_deg = 0;
if (phase_deg > 360) phase_deg = 360;
// 2. 计算相位字(规格书8. CIRCUIT DESCRIPTION:PHASE_REG = 相位(°) × 4096 / 360)
phase_word = (uint16_t)(phase_deg * AD9833_PHASE_MAX / 360.0f);
// 3. 写入相位寄存器(相位寄存器地址 + 12位相位数据;规格书Table 8)
AD9833_WriteData(phase_reg | (phase_word & 0x0FFF));
}
// -------------------------- 6. 波形配置(基于规格书VOUT输出规则)--------------------------
void AD9833_SetWaveform(uint8_t wave_type) {
uint16_t ctrl_word = AD9833_REG_CTRL;
// 关键:先将SLEEP12置0(启用DAC),避免DAC断电导致无输出(规格书Table 10)
ctrl_word &= ~AD9833_CTRL_SLEEP12;
switch (wave_type) {
case 0: // 正弦波:OPBITEN=0(DAC输出),MODE=0(启用SIN ROM)(规格书Table 11)
ctrl_word &= ~AD9833_CTRL_OPBITEN; // OPBITEN=0:启用DAC输出
ctrl_word &= ~AD9833_CTRL_MODE; // MODE=0:启用SIN ROM(替代原无效的AD9833_CTRL_MODE_0)
break;
case 1: // 三角波:OPBITEN=0,MODE=1(bypass SIN ROM)(规格书Table 11)
ctrl_word &= ~AD9833_CTRL_OPBITEN;
ctrl_word |= AD9833_CTRL_MODE;
break;
case 2: // 方波(MSB):OPBITEN=1,DIV2=1(规格书Table 11)
ctrl_word |= AD9833_CTRL_OPBITEN | AD9833_CTRL_DIV2;
ctrl_word |= AD9833_CTRL_SLEEP12; // 数字输出时可断电DAC(降低功耗,规格书Table 10)
break;
case 3: // 方波(MSB/2):OPBITEN=1,DIV2=0(规格书Table 11)
ctrl_word |= AD9833_CTRL_OPBITEN;
ctrl_word &= ~AD9833_CTRL_DIV2;
ctrl_word |= AD9833_CTRL_SLEEP12; // 数字输出时断电DAC
break;
default: // 默认正弦波(规格书推荐初始输出)
ctrl_word &= ~AD9833_CTRL_OPBITEN;
ctrl_word &= ~AD9833_CTRL_MODE;
break;
}
AD9833_WriteData(ctrl_word); // 写入控制寄存器,使配置生效(规格书第9章串行接口)
}
void AD9833_SetSleepMode(uint8_t sleep_mode) {
uint16_t ctrl_word = AD9833_REG_CTRL;
switch (sleep_mode) {
case 0: // 无休眠(SLEEP1=0,SLEEP12=0)
ctrl_word &= ~(AD9833_CTRL_SLEEP1 | AD9833_CTRL_SLEEP12);
break;
case 1: // DAC休眠(SLEEP1=0,SLEEP12=1)
ctrl_word &= ~AD9833_CTRL_SLEEP1;
ctrl_word |= AD9833_CTRL_SLEEP12;
break;
case 2: // 时钟休眠(SLEEP1=1,SLEEP12=0)
ctrl_word |= AD9833_CTRL_SLEEP1;
ctrl_word &= ~AD9833_CTRL_SLEEP12;
break;
case 3: // 深度休眠(SLEEP1=1,SLEEP12=1)
ctrl_word |= AD9833_CTRL_SLEEP1 | AD9833_CTRL_SLEEP12;
break;
}
}
调用方法
AD9833_Init();
// 配置FREQ0寄存器,输出520Hz频率
AD9833_SetFrequency(AD9833_REG_FREQ0, 520UL);
AD9833_SetSleepMode(0);
AD9833_SetWaveform(0);
照片记录





3896

被折叠的 条评论
为什么被折叠?



