AD9951

本贴最后更新于 521 天前,其中的信息可能已经时移世异

通信

image

PIN

​​image

SCLK-Serial 时钟。串行时钟引脚用于从 AD9951 和 AD9951 同步数据,并运行内部状态机。SCLK 最大频率为 25mhz。

csb -芯片选择条。CSB 是主动低输入,允许多个设备在同一串行通信线路上。当该输入高时,SDO 和 SDIO 引脚将进入高阻抗状态。如果在任何通信周期中被驱动为高电平,那么该周期将暂停,直到 CS 被重新激活为低电平。在保持 SCLK 控制的系统中,芯片选择可以很低。

串行数据输入/输出。数据总是写入该引脚上的 AD9951。然而,这个引脚可以用作双向数据线。==寄存器地址 0x00 的第 7 位控制这个引脚的配置。默认值是 Logic 0,它将 SDIO 引脚配置为双向。==

串行数据输出。数据从这个引脚读取,协议使用单独的线路发送和接收数据。在 AD9951 工作在单一双向 I/O 模式的情况下,该引脚不输出数据,并设置为高阻抗状态。

iosync——它同步 I/O 端口状态机而不影响可寻址寄存器的内容。IOSYNC 引脚上的活动高输入导致当前通信周期中止。在 IOSYNC 返回 low(逻辑 0)之后,另一个通信周期可能开始,从指令字节写入开始。

IO UPDATE

image

同步;寄存器更新(I/O 更新)

SYNC_CLK 和 I/O 更新数据到 AD9951 的功能与 SYNC_CLK 信号是同步的(在 SYNC_CLK 引脚上外部提供给用户)。==I/O UPDATE 引脚在 SYNC_CLK 的上升沿上采样==。

在内部,SYSCLK 被馈送到一个除以 4 的分频器来产生 SYNC_CLK 信号。SYNC_CLK 信号在 SYNC_CLK 引脚上提供给用户。这样可以使外部硬件与设备的内部时钟同步。

这是通过强制任何外部硬件从 SYNC_CLK 获取其时间来实现的。与 SYNC_CLK 耦合的 I/O UPDATE 信号用于将内部缓冲区内容传输到设备的控制寄存器中。SYNC_CLK 和 I/O UPDATE 引脚的组合为用户提供了相对于 SYSCLK 的恒定延迟,并且还确保了在断言一个新的调谐字或相位偏移值时模拟输出信号的相位连续性。图 19 演示了一个 I/O UPDATE 定时周期和同步。

同步逻辑注意事项:

  1. I/O UPDATE 信号边缘检测产生单个上升沿时钟信号,驱动寄存器组触发器。I/O UPDATE 信号对占空比没有限制。I/O UPDATE 的最小 low 时间是一个 SYNC_CLK 时钟周期。

  2. I/O UPDATE 引脚设置并保持在 SYNC_CLK 的上升沿周围,并且具有零保持时间和 4 ns 设置时间

SDIO 和 SDO​

SDIO 和 SDO 都是与 SPI(串行外设接口)相关的信号线。

SDIO(Serial Data Input/Output)是用于向 SPI 设备发送数据的串行数据输入/输出线。它是主控制器(如微处理器或微控制器)通过该线将数据发送给 SPI 设备。

SDO(Serial Data Output)是从 SPI 设备传输数据回主控制器的串行数据输出线。SPI 设备通过该线将数据返回给主控制器。

在 SPI 通信中,主控制器通过 SCK(时钟线)驱动数据传输,在每个时钟周期中,主控制器将数据从 SDO 线发送到 SPI 设备的 SDI 线,并从 SPI 设备的 SDO 线接收数据。

因此,SDIO 和 SDO 是 SPI 通信中用于数据的输入和输出的信号线。

clock stall

在串行通信协议中出现的一种特定时序条件,称为“时钟停滞高”(clock stall high)。在典型的同步串行通信协议(如 SPI、I2C 或 SMBus)中,数据传输与时钟信号同步。时钟信号决定何时数据有效并应该被采样。在正常操作期间,时钟信号在高电平和低电平之间转换以定义数据传输的时序。然而,==在某些情况下,例如数据传输中出现延迟或暂停,时钟信号可能会保持高电平状态一段较长时间。==这就是所谓的“时钟停滞高”条件。

“时钟停滞高”条件可能由总线仲裁、数据争用或同步问题等多种因素引起。在设计和实现依赖同步串行通信协议的系统时,考虑这种情况非常重要。

当遇到“时钟停滞高”条件时,接收设备可以等待时钟恢复其正常模式,也可以根据协议规范采取适当的行动。对“时钟停滞高”条件的确切行为和响应取决于特定的协议和实现。

image

时序

image

串口操作在 AD9951 中,指令字节指定读/写操作和寄存器地址。==AD9951 上的串行操作只发生在寄存器级,而不是字节级==。对于 AD9951,串口控制器识别指令字节寄存器地址,并自动生成相应的寄存器字节地址。此外,控制器期望该寄存器的所有字节将被访问。在串行 I/O 操作期间,需要访问寄存器的所有字节,只有一个例外。==IOSYNC 函数可用于终止 I/O 操作==,从而允许访问少于所有字节的数据。


AD9951 的通信周期有两个阶段。阶段 1 是指令周期,它是将一个指令字节写入 AD9951,与前 8 个 SCLK 上升沿一致。指令字节向 AD9951 串行端口控制器提供有关数据传输周期的信息,这是通信周期的第二阶段。

阶段 1 指令字节定义==即将到来的数据传输是读还是写,以及正在访问的寄存器的串行地址。==请注意,被访问的寄存器的串行地址与要写入的字节的地址不同。有关详细信息,请参见示例操作部分。每个通信周期的前 8 个 SCLK 上升沿用于将指令字节写入 AD9951。剩余的 SCLK 边缘用于通信周期的第 2 阶段。阶段 2 是 AD9951 和系统控制器之间的实际数据传输。在通信周期的第 2 阶段传输的字节数是被访问寄存器的函数。例如,当访问 3 字节宽的控制功能寄存器 2 号时,阶段 2 要求传输 3 字节。==如果访问四个字节宽的频率调谐字,则阶段 2 需要传输四个字节。==在每条指令传输完所有数据字节后,通信周期就完成了。

在任何通信周期完成时,AD9951 串行端口控制器期望下八个上升的 SCLK 边是下一个通信周期的指令字节。所有输入到 AD9951 的数据都注册在 SCLK 的上升沿上。所有数据都被驱动出 AD9951 在 SCLK 的下降沿上。图 21 到图 24 有助于理解 AD9951 串口的一般操作。


​​imageimage​​

寄存器

CFR1

image

image

image

image

CFR2

CFR2 寄存器是用于控制 AD9951 的各种功能、特性和模式的寄存器,主要与芯片的模拟部分相关。

下面是对 CFR2 的每个位的功能描述:

  • CFR2<23:12>:未使用的位。

  • CFR2<11>:高速同步使能位。

    • CFR2<11> = 0(默认值):关闭高速同步增强功能。
    • CFR2<11> = 1:打开高速同步增强功能。当使用超过 50 MHz 的 SYNC_CLK 输入(200 MSPS SYSCLK)时,应设置该位,以实现自动同步功能。详细信息请参阅"Synchronizing Multiple AD9951s"章节。
  • CFR2<10>:硬件手动同步使能位。

    • CFR2<10> = 0(默认值):关闭硬件手动同步功能。
    • CFR2<10> = 1:启用硬件手动同步功能。当 SYNC_IN 引脚上出现上升沿时,设备会使 SYNC_CLK 的上升沿提前一个 REFCLK 周期。与软件手动同步使能位不同,该位不会自动清零。一旦启用了硬件手动同步模式,它将一直保持启用状态,直到该位被清零。详细信息请参阅"Synchronizing Multiple AD9951s"章节。
  • CFR2<9>:CRYSTAL OUT 使能位。

    • CFR2<9> = 0(默认值):CRYSTAL OUT 引脚无效。
    • CFR2<9> = 1:CRYSTAL OUT 引脚有效。当激活时,晶体振荡器电路输出驱动 CRYSTAL OUT 引脚,可以将其连接到其他设备以产生参考频率。该振荡器对于 20 MHz 到 30 MHz 范围内的晶体具有响应能力。
  • CFR2<8>:未使用的位。

  • CFR2<7:3>:参考时钟倍频器控制位。

    • 这个 5 位字控制时钟倍频器(PLL)模块的倍频器值。有效值为 4 至 20(0x04 到 0x14)。超出此范围的值将绕过时钟倍频器。详细信息请参阅"Phase-Locked Loop (PLL)"章节。
  • CFR2<2>:VCO 范围控制位。

    • 当 CFR2<2> == 0(默认值)时,VCO 在 100 MHz 至 250 MHz 的范围内工作。
    • 当 CFR2<2> == 1 时,VCO 在 250 MHz 至 400 MHz 的范围内工作。
  • CFR2<1:0>:电荷泵电流控制位。

    • 这些位用于控制电荷泵的电流设置。默认设置 CFR2<1:0> 将电荷泵电流设置为默认值 75 µA。每增加一个位(01、10、11),电荷泵电流将增加 25 µA:100 µA、125 µA 和 150 µA。

其他寄存器

振幅比例因子(ASF)

ASF 寄存器存储在输出形键控(OSK)操作中使用的 2 位自动斜坡速率值和 14 位振幅比例因子。在自动 OSK 操作中,ASF <15:14> 告诉 OSK 块每次增加或减少需要多少幅度步长。ASF<13:0> 设置 OSK 内部乘数可达到的最大值。手动 OSK 模式下,ASF<15:14> 不起作用。ASF <13:0> 直接提供输出比例因子。如果清除 OSK 使能位,CFR1<25> = 0,则该寄存器对设备操作没有影响。

幅度斜坡率(ARR)

ARR 寄存器存储在自动 OSK 模式中使用的 8 位幅度斜坡率。这个寄存器对幅度比例因子计数器增加或减少的速率进行编程。如果将 OSK 设置为手动模式,或者清除了 OSK enable,则该寄存器对设备操作没有影响。

频率调谐字 0 (FTW0)

频率调谐字是一个 32 位寄存器,用于控制 DDS 核心的相位累加器中的累加速率。

它的具体作用取决于设备的操作方式。

相位偏移字(POW)相位偏移字是一个存储相位偏移值的 14 位寄存器。这个偏移值被添加到相位累加器的输出中,以抵消输出信号的当前相位。

其他

运行模式

image

相位控制

一个 14 位的相位偏移(θ)可以通过控制寄存器加到相位累加器的输出上。该功能为用户提供了两种不同的相位控制方法。

第一种方法是==静态相位调整==,其中将固定的相位偏移量加载到适当的相位偏移寄存器中并保持不变。结果是输出信号相对于标称信号有一个恒定的角度偏移。这允许用户相位对准 DDS 输出与一些外部信号,如果需要的话。

相位控制的第二种方法是==用户通过 I/O 端口定期更新相位偏移寄存器==。通过适当地修改作为时间函数的相位偏移,用户可以实现相位调制输出信号。然而,I/O 端口的速度和 SYSCLK 的频率都限制了可以执行相位调制的速率。

AD9951 允许相位累加器的可编程连续调零以及明确和释放或自动调零功能。每个特征都通过 CFR1 位单独控制。CFR1<13> 为自动清相累加器位。CFR1<10> 清除相位累加器并保持该值为零。

连续清除位连续清除位仅仅是一个静态控制信号,当激活高位时,相位累加器在整个比特激活期间保持为零。当钻头变低,不活动时,相位累加器允许工作。

当设置时,自动清除相位累加器在接收到 I/O UPDATE 时清除并释放相位累加器。每次后续的 I/O UPDATE 都会重复自动清除功能,直到适当的自动清除控制位被清除。

AD9951 的形状开关键控功能允许用户控制 DAC 的开关发射的上升和下降时间。该函数用于数字数据的突发传输,以减少短而突然的数据突发对频谱的不利影响。

支持自动和手动形状的开关键控模式。

自动模式以由外部引脚(OSK)控制的幅度斜坡率(ARR)寄存器决定的速率产生线性比例因子。手动模式允许用户通过将比例因子值写入幅度比例因子(ASF)寄存器来直接控制输出幅度。

通过清除 OSK 使能位(CFR1<25> = 0),可以绕过(禁用)形开关键控功能。

这些模式由位于控制函数寄存器(CFR)的最高位字节中的两个比特控制。CFR1<25> 为形通断键控使能位。当设置 CFR1<25> 时,表示开启输出缩放功能,CFR1<25> 绕过该功能。CFR1<24> 为内形通断键控有源钻头。当设置 CFR1<24> 时,内部形通断键控模式激活;CFR1<24> 清除,外部形开关键控模式激活。CFR1<24> 是一个不关心形状开关键使能位(CFR1<25>)是否被清除。上电条件为开-关键禁用(CFR1<25> = 0)。

图 18 显示了 OSK 电路的框图。

开关键控模式

AUTO 形开关键控模式操作当==CFR1<25>和 CFR1<24>设置时,自动形开关键控模式激活==。当启用自动成形开关键控模式时,内部生成一个比例因子,并将其应用于乘法器输入,用于缩放 DDS 核心块的输出(参见图 18)。比例因子是一个 14 位计数器的输出,该计数器以 8 位输出斜坡率寄存器的内容决定的速率递增/递减。当 OSK 引脚高时,比例因子增大,当 OSK 引脚低时,比例因子减小。比例因子是一个无符号值,因此所有 0 将 DDS 核心输出乘以 0(十进制),0x3FFF 将 DDS 核心输出乘以 16383(十进制)。

对于那些使用全幅度(14 位)但需要快速斜坡速率的用户,内部生成的比例因子步长通过 ASF<15:14> 位来控制。表 6 描述了每 ASF<15:14> 位内部生成的比例因子的递增/递减步长。

这种模式的一个特点是允许的最大输出幅度受幅度比例因子寄存器内容的限制。这允许用户斜坡到小于满量程的值。

PLL

锁相环(PLL)锁相环允许 REFCLK 频率的倍增。锁相环的控制是通过编程控制函数寄存器 2 位的 5 位 REFCLK 乘法器来完成的,Bits <7:3>。

当编程的值范围从 0x04 到 0x14(4 十进制到 20 十进制)时,==PLL 将 REFCLK 输入频率乘以相应的十进制值。==然而,锁相环的最大输出频率被限制在 400mhz。当 PLL 值改变时,用户应该意识到必须分配时间来允许 PLL 锁定(大约 1 毫秒)。

通过编程一个超出 4 到 20(十进制)范围的值来绕过锁相环。旁路时,锁相环关闭以节省功率。

时钟输入

时钟输入 AD9951 支持多种时钟方式。支持差分或单端输入时钟和使能片上振荡器和/或==锁相环(PLL)乘法器都通过用户可编程位控制==。AD9951 可以配置为六种工作模式之一来产生系统时钟。==使用 CLKMODESELECT 引脚、CFR1<4>和 CFR2<7:3>配置模式。==将外部引脚 CLKMODESELECT 连接到 Logic High,可以实现片上晶体振荡器电路。启用片上振荡器后,AD9951 的用户将外部晶体连接到 REFCLK 和 REFCLKB 输入端,以产生 20 MHz 至 30 MHz 范围内的低频参考时钟。由振荡器产生的信号在传送到芯片的其余部分之前被缓冲。该缓冲信号可通过 CRYSTAL OUT 引脚获得。CFR1<4> 位可用于开启或关闭缓冲区,打开或关闭系统时钟。振荡器本身没有断电,以避免长时间的启动时间与打开晶体振荡器相关。将 CFR2<9> 写入 Logic High 使能晶体振荡器输出缓冲区。逻辑低在 CFR2<9> 禁用振荡器输出缓冲区。

==将 CLKMODESELECT 连接到 Logic Low 禁用片上振荡器和振荡器输出缓冲器。==当振荡器被禁用时,外部振荡器必须提供 REFCLK 和/或 REFCLKB 信号。对于微分操作,这些引脚由互补信号驱动。对于单线操作,应在未使用引脚和模拟电源之间连接 0.1µF 电容器。电容器就位后,时钟输入引脚偏置电压为 1.35 V。此外,锁相环可用于将参考频率乘以 4 到 20 范围内的整数值。表 4 总结了操作的时钟模式。==注意,锁相环乘法器是通过 CFR2<7:3>位控制的==,与 CFR1<4> 位无关。

image

image​​image​​

原理图

image

程序

​​image

#include "config.h"
#include "AD9951.h"

#define  NUM_2_31_N 2147483648.0 
#define  NUM_2_32_N 4294967296.0 
#define AD9951_SYS 400000000.0

unsigned char AD9951_cfr1[4] = {0x02, 0x02, 0x00, 0x07};
unsigned char AD9951_cfr2[3] = {0x00, 0x00, 0x18};
unsigned char AD9951_asf[2] = {0xff, 0x3f};
unsigned char AD9951_arr = 0xff;
unsigned char AD9951_ftw[4] = {0x33, 0x00, 0x00, 0x00};
unsigned char AD9951_pow[2] = {0x00, 0x00};

//AD9959初始化
void Init_AD9951(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
    GPIO_InitStructure.Pin = GPIO_Pin_All;//初始化管脚
    GPIO_Inilize(GPIO_P2, &GPIO_InitStructure);					 //根据设定参数初始化GPIOA

    //ad9951_CS =		 0;
    ad9951_RST =     0;
	ad9951_IO_UP = 	 0;
	ad9951_OSK  = 0;
	ad9951_OSK  = 1;
	ad9951_IOSYS =   0;

	AD9951_toggleReset();
	AD9951_toggleIOSync();

	 //These are all of the registers that can be changed.
     //Set the value of each register and then call the Config method
     //See page 14 of the fancy datasheet for information on the registers
     AD9951_cfr1[0] = 0x00;
     AD9951_cfr1[1] = 0x02;
     AD9951_cfr1[2] = 0x00;
     AD9951_cfr1[3] = 0x07;
     AD9951_SendReg(cfr1_reg,write_reg);
   
	 AD9951_cfr2[0] = 0x40;		//PPL 8
     AD9951_cfr2[1] = 0x00;
     AD9951_cfr2[2] = 0x00;
     AD9951_SendReg(cfr2_reg,write_reg);
   
     AD9951_asf[0] = 0xff;
     AD9951_asf[1] = 0x3f;
     AD9951_SendReg(asf_reg,write_reg);
   
     AD9951_arr = 0xff;
     AD9951_SendReg(arr_reg,write_reg);
   
     AD9951_ftw[0] = 0x00;
     AD9951_ftw[1] = 0x00;
     AD9951_ftw[2] = 0x00;
     AD9951_ftw[3] = 0x00;
     AD9951_SendReg(ftw_reg,write_reg);
   
     AD9951_pow[0] = 0x00;
     AD9951_pow[1] = 0x00;
     AD9951_SendReg(pow_reg,write_reg);

}

u8 AD9951_ddswrite_byte(unsigned char byt)
{
    u8 i, sbt;
    sbt = 0x80;
    ad9951_SCLK = 0;

    for (i = 0; i < 8; i++)
    {
        if ((byt & sbt) == 0) ad9951_SDIO = 0;
        else ad9951_SDIO = 1;
        ad9951_SCLK = 1;
        sbt = sbt >> 1;
        ad9951_SCLK = 0;
    }
	return 0;
}

void AD9951_ddswrite_FTW(u32 freq)
{
	u32 ftw = 0;

	if( (freq >= 0 ) && (freq <= NUM_2_31_N) )
		ftw = (freq * NUM_2_32_N) / AD9951_SYS;
	else if(  (freq > NUM_2_31_N) && (freq < (NUM_2_32_N - 1) ) )
		ftw = (u32)((1 - (freq / AD9951_SYS)) * NUM_2_32_N);

    AD9951_ftw[0] = (ftw >> 0) & 0xFF;
    AD9951_ftw[1] = (ftw >> 8) & 0xFF;
    AD9951_ftw[2] = (ftw >> 16) & 0xFF;
    AD9951_ftw[3] = (ftw >> 24) & 0xFF;
	AD9951_SendReg(ftw_reg, write_reg); //This means that you'd like to send the Frequency register to the AD9951 and you want to write to the register
	AD9951_toggleIOSync();
	AD9951_toggleIOUpdate(); 

}

void AD9951_IO_Update(void)
{
    ad9951_IO_UP = 0;
    delay_us(2);
    ad9951_IO_UP = 1;
    delay_us(4);
    ad9951_IO_UP = 0;
}

void AD9951_Config() {
    AD9951_SendReg(cfr1_reg, write_reg);
    AD9951_SendReg(cfr2_reg, write_reg);
    AD9951_SendReg(asf_reg, write_reg);
    AD9951_SendReg(arr_reg, write_reg);
    AD9951_SendReg(ftw_reg, write_reg);
    AD9951_SendReg(pow_reg, write_reg);
}

void AD9951_ChangeASF(unsigned short ASF) {
    AD9951_asf[0] = ASF & 0xFF;
    AD9951_asf[1] = ASF >> 8;

    AD9951_SendReg(asf_reg, write_reg);
}

void AD9951_ChangeARR(int ARR) {
    AD9951_arr = ARR;

    AD9951_SendReg(arr_reg, write_reg);
}

void AD9951_ChangePhase(int degrees) {
    unsigned short AD9951_poww = ((degrees >= -360 && degrees <= 360 ? degrees : 0) * 16384) / 360;
    AD9951_pow[0] = AD9951_poww & 0xFF;
    AD9951_pow[1] = AD9951_poww >> 8;

    AD9951_SendReg(pow_reg, write_reg);
}

void AD9951_toggleIOUpdate() {
    // Toggle IO_UPDATE
	ad9951_IO_UP = 1;
	delay_ms(10);
	ad9951_IO_UP = 0;
}

void AD9951_toggleIOSync() {
    // Toggle IO_SYNC.
	ad9951_IOSYS = 1;
	delay_ms(10);
	ad9951_IOSYS = 0;
}

void AD9951_toggleReset() {
    // Toggle RESET
	ad9951_RST = 1;
	delay_ms(10);
	ad9951_RST = 0;
}

void AD9951_SendReg(unsigned char reg, unsigned char read_write) {
    unsigned char rw;
    unsigned char buf[4];
    int i;

    if (read_write == write_reg) {
        rw = 0x00; // It's a write instruction
    } else if (read_write == read_reg) {
        rw = 0x80; // It's a read instruction
    }

	ad9951_CS = 0; 

    switch (reg) {
        case cfr1_reg:
            reg = rw | cfr1_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
	
            for (i = 3; i >= 0; i--) {
                buf[i] = AD9951_ddswrite_byte(AD9951_cfr1[i]); // Send data byte(s)
            }

            if (read_write == read_reg) {
                AD9951_cfr1[3] = buf[3];
                AD9951_cfr1[2] = buf[2];
                AD9951_cfr1[1] = buf[1];
                AD9951_cfr1[0] = buf[0];
            }

            break;

        case cfr2_reg:
            reg = rw | cfr2_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
            for (i = 2; i >= 0; i--) {
                buf[i] = AD9951_ddswrite_byte(AD9951_cfr2[i]); // Send data byte(s)
            }

            if (read_write == read_reg) {
                AD9951_cfr2[2] = buf[2];
                AD9951_cfr2[1] = buf[1];
                AD9951_cfr2[0] = buf[0];
            }

            break;

        case asf_reg:
            reg = rw | asf_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
            for (i = 1; i >= 0; i--) {
                buf[i] = AD9951_ddswrite_byte(AD9951_asf[i]); // Send data byte(s)
            }

            if (read_write == read_reg) {
                AD9951_asf[1] = buf[1];
                AD9951_asf[0] = buf[0];
            }

            break;

        case arr_reg:
            reg = rw | arr_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
            buf[0] = AD9951_ddswrite_byte(AD9951_arr); // Send data byte

            if (read_write == read_reg) {
                AD9951_arr = buf[0];
            }

            break;

        case ftw_reg:
            reg = rw |ftw_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
            for (i = 3; i >= 0; i--) {
                buf[i] = AD9951_ddswrite_byte(AD9951_ftw[i]); // Send data byte(s)
            }

            if (read_write == read_reg) {
                AD9951_ftw[3] = buf[3];
                AD9951_ftw[2] = buf[2];
                AD9951_ftw[1] = buf[1];
                AD9951_ftw[0] = buf[0];
            }

            break;

        case pow_reg:
            reg = rw | pow_reg;
            // Send instruction byte
			AD9951_ddswrite_byte(reg);
            for (i = 1; i >= 0; i--) {
                buf[i] = AD9951_ddswrite_byte(AD9951_pow[i]); // Send data byte(s)
            }

            if (read_write == read_reg) {
                AD9951_pow[1] = buf[1];
                AD9951_pow[0] = buf[0];
            }

            break;
    }
	ad9951_CS = 1;
	AD9951_toggleIOSync();
	AD9951_toggleIOUpdate();
}

#ifndef __AD9951_H__
#define __AD9951_H__

#include 	"config.h"
#include	"STC8A_Delay.h"
#include	"STC8A_GPIO.h"

sbit ad9951_RST = 	P2^7;
sbit ad9951_IOSYS = P2^6;
sbit ad9951_SDO = 	P2^5;

sbit ad9951_CS = 	P2^4;
sbit ad9951_SCLK =	P2^3;
sbit ad9951_SDIO = 	P2^2;

sbit ad9951_OSK =	P2^1;
sbit ad9951_IO_UP = P2^0;


#define cfr1_reg 0x00
#define cfr2_reg 0x01
#define asf_reg 0x02
#define arr_reg 0x03
#define ftw_reg 0x04
#define pow_reg 0x05
#define read_reg 0x00
#define write_reg 0x01

extern unsigned char AD9951_cfr1[4];
extern unsigned char AD9951_cfr2[3];
extern unsigned char AD9951_asf[2] ;
extern unsigned char AD9951_arr;
extern unsigned char AD9951_ftw[4] ;
extern unsigned char AD9951_pow[2] ;

void Init_AD9951(void);
void AD9951_Config();
u8 AD9951_ddswrite_byte(unsigned char byt);
void AD9951_ChangeASF(unsigned short ASF);
void AD9951_ChangeARR(int ARR);
void AD9951_ChangePhase(int degrees);
void AD9951_toggleIOUpdate();
void AD9951_toggleIOSync();
void AD9951_toggleReset();
void AD9951_SendReg(unsigned char reg, unsigned char read_write);
void AD9951_ddswrite_FTW(u32 freq);
void AD9951_ddswrite_phase(unsigned int phase);
void AD9951_ddswrite_amplitude(unsigned int amplitude);
void AD9951_IO_Update(void);

#endif



参考

  1. blog.csdn.net/acb989898/...
  2. www.laserlance.com/proje...

注意事项

  1. AD9951 要设置八倍频。AD9958 设置十倍频。

相关帖子

回帖

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...