【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);

照片记录

在这里插入图片描述

测试版

在这里插入图片描述
在这里插入图片描述

AD9959是一款高性能直接数字频率合成器(DDS),支持多通道信号生成,广泛应用于需要高精度波形控制的场景,如通信、雷达、测试仪器等。尽管AD9959的默认输出为正弦波,但通过合理配置其内部寄存器和利用外部控制逻辑,可以实现任意波形输出(AWG)功能。 AD9959通过其内置的相位累加器和频率调谐字(FTW)机制,可以灵活地调整输出信号的频率和相位[^1]。在任意波形生成中,相位信息被用作查找表(LUT)的索引,该查找表存储了用户自定义的波形数据。这些波形数据可以通过外部控制器(如FPGA)加载到AD9959的寄存器中,或者通过其内部的波形存储器进行管理。 AD9959支持多通道独立控制,每个通道可以配置不同的频率、相位和幅度参数,这为实现复杂的波形调制提供了基础[^1]。例如,可以通过编程使不同通道输出不同波形,或在单个通道上切换多个波形,从而实现任意波形序列的生成。 在实现任意波形输出时,通常需要借助外部控制器(如FPGA)来管理波形数据的加载和更新。FPGA可以用于生成波形查找表、控制相位增量、动态切换频率和相位参数,以及处理AD9959的寄存器配置。此外,AD9959的串行I/O接口可用于加载频率控制字和相位偏移值,实现波形的动态变化。 以下是一个使用FPGA控制AD9959配置频率控制字的Verilog代码示例: ```verilog reg [31:0] freq_word = 32'h12345678; // 示例频率控制字 always @(posedge clk) begin if (start_config) begin wr_data <= freq_word[31:24]; wr_addr <= 8'h00; wr_en <= 1'b1; #10 wr_en <= 1'b0; // 依次写入剩余字节 end end ``` 该代码展示了如何通过FPGA向AD9959写入频率控制字,为任意波形生成提供基础。通过扩展该逻辑,可以实现波形数据的动态加载和切换,从而生成任意波形。 此外,AD9959的幅度控制功能也可以用于实现波形的形状调整,进一步增强其作为任意波形发生器的能力。结合高速DAC和适当的滤波电路,可以提升输出波形的质量和精度。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值