任意波形发生器芯片AD9102的应用
前言
本文主要介绍Analog Device公司的任意波形合成器AD9102的应用
一、任意波形合成器AD9102简介
AD9102是Analog Device公司生产的任意波形合成器集成芯片,内部集成了高速DAC,高速波形储存器,DDS直接数字频率合成器,电压基准源等,可以产生任意波形。具有低功耗,高集成度等特点。最高系统时钟频率为180MHz,可产生最高频率为90MHz的正弦波信号和10MHz的任意波形信号。功能框图如下:
二、硬件设计
1.AD9102最小系统
AD9102芯片最小系统十分简单,仅需少量电阻电容即可。电阻R5,R6为DAC输出电流电压转换电阻,将电流输出转化为电压输出。R7,R8为校准电阻。电容均为电源滤波和退耦电容。为了提高电磁兼容性,降低干扰,将模拟地和数字地分开布线,并用铁氧体磁珠单点连接。
2.时钟电路
AD9102支持单端和差分时钟输入,数据手册上推荐使用差分时钟,故使用德州仪器公司的LMH7220高速LVDS驱动器产生LVDS电平差分时钟。由于AD9102内部无时钟管理系统,波形生成器时钟即为输入时钟,故外部提供两路时钟信号,分别为10MHz和180MHz,分别为产生高频信号和低频信号时的参考时钟。
3.输出信号处理电路
AD9102输出为电流信号,经电阻转换为电压信号后,由可变增益放大器放大后输出。可变增益放大器采用德州仪器公司生产的VCA824集成芯片,增益由电压控制,输出带载能力强,图中电路接法最高电压放大倍数为10倍,最低为0倍,与控制电压成线性关系。具体可参阅VCA824的数据手册。控制电压由双极性DAC:AD5761R产生。
4.控制电路
AD9102芯片使用SPI接口控制,增益控制DAC也为SPI控制,控制器采用意法半导体公司STM32L552CEU6。控制电路如下图所示。
5.电源电路
整个系统需要3.3V数字电源,3.3V模拟电源,±5V模拟电源,分别由不同的电源芯片产生,如下图。
三、软件设计
提示:本设计使用STM32单片机HAL库方式编程,使用开发环境Keil uVision5。
1.单片机外设配置
本设计用到了SPI,定时器,内置运算放大器,I2C,GPIO,UART(可选)等外设。
2.AD9102初始化和基本交互
uint8_t AD9102_Init(void)//上电初始化
{
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);//CS拉高
HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_SET);//RESET拉高
HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);//TRIG拉低
AD9102_Reset();
return 1;
}
uint8_t AD9102_Reset(void)//重置器件
{
HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_RESET);//RESET拉低
HAL_Delay(10);
HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_SET);//RESET拉高
return 1;
}
uint8_t AD9102_WriteReg(uint16_t addr,uint16_t data)//写入寄存器
{
uint8_t Txd[4];
Txd[0]=((addr>>8)&0x7F);
Txd[1]=addr&0xFF;
Txd[2]=(data>>8)&0xFF;
Txd[3]=data&0xFF;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);//CS拉低,启动传输
HAL_SPI_Transmit(&hspi3,Txd,4,1000);//SPI发送数据
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);//CS拉高,结束传输
return 1;
}
uint16_t AD9102_ReadReg(uint16_t addr)//读取寄存器
{
uint8_t Txd[2];
uint8_t Rxd[2];
uint16_t Rdata;
Txd[0]=((addr>>8)&0x7F)|0x80;
Txd[1]=addr&0xFF;
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);//CS拉低,启动传输
HAL_SPI_Transmit(&hspi3,Txd,2,1000);//SPI发送指令
HAL_SPI_Receive(&hspi3,Rxd,2,1000);//接收数据
HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);//CS拉高,结束传输
Rdata=(Rxd[0]<<8)+(Rxd[1]);
return Rdata;
}
3.AD9102芯片操作
根据数据手册,我编写了对AD9102芯片进行操作的库函数,列表如下:
//AD9102.h
#include "stm32l5xx_hal.h"
#define RESET_Pin GPIO_PIN_12
#define RESET_GPIO_Port GPIOA
#define CS_Pin GPIO_PIN_15
#define CS_GPIO_Port GPIOA
#define TRIG_Pin GPIO_PIN_8
#define TRIG_GPIO_Port GPIOB
#define CLKMODE2_Pin GPIO_PIN_8
#define CLKMODE2_GPIO_Port GPIOA
#define CLKMODE1_Pin GPIO_PIN_11
#define CLKMODE1_GPIO_Port GPIOA
uint8_t AD9102_Init(void);//上电初始化
uint8_t AD9102_Reset(void);//重置器件
uint8_t AD9102_Trig(void);//触发
uint8_t AD9102_DisTrig(void);//终止触发
uint8_t AD9102_WriteReg(uint16_t addr,uint16_t data);//写入寄存器
uint16_t AD9102_ReadReg(uint16_t addr);//读取寄存器
uint8_t AD9102_Duplex(uint8_t value);//双工设置,0为全双工,1为半双工
uint8_t AD9102_DataSequence(uint8_t value);//数据顺序设置,1为LSB优先,0为MSB优先
uint8_t AD9102_SoftReset(void);//软件重置
uint8_t AD9102_DoubleSPI(uint8_t value);//双重SPI设置,0为标准SPI,1为双SPI
uint8_t AD9102_SPIDRV(uint8_t value);//SPI_DRV设置
uint8_t AD9102_DOUT_EN(uint8_t value);//DOUT设置
uint8_t AD9102_GetLDOStatus(uint8_t LDO);//获取LDO状态,1为开启,0为关闭,参数1:CLDO,2:DLDO1,3:DLDO2
uint8_t AD9102_LDO_EN(uint8_t LDO,uint8_t value);//内置LDO开关,参数1:1:CLDO,2:DLDO1,3:DLDO2。参数2:0为开启,1为关闭
uint8_t AD9102_RefRes_EN(uint8_t value);//参考电压电阻开关,0为开启,1为关闭
uint8_t AD9102_BandGap_EN(uint8_t value);//内置参考电压开关,0为开启,1为关闭
uint8_t AD9102_DACOutput_EN(uint8_t value);//DAC输出开关,0为开启,1为关闭
uint8_t AD9102_CLK_EN(uint8_t Clock,uint8_t value);//系统时钟开关,参数1为时钟源:1:DAC1,2:DDS核心,3:低功耗模式,4:全部时钟。参数2:0为开启,1为关闭
uint8_t AD9102_PowerSave(uint8_t value);//低功耗模式,0为关闭,1为开启
uint8_t AD9102_DACCLK_Inv(uint8_t value);//DAC时钟反相,1为反相,0为正常
uint8_t AD9102_REFADJ(uint8_t value);//参考电压调节
int8_t AD9102_GetDACGainCal(void);//读取DAC增益校准值
uint8_t AD9102_SetDACGain(int8_t value);//设置DAC增益值
uint8_t AD9102_DACGainRange(uint8_t value);//DAC增益范围设置
uint8_t AD9102_DACRset_EN(uint8_t value);//内部RSET开关,1为开启,0为关闭
uint8_t AD9102_GetRset(void);//校准后RSET值读取
uint8_t AD9102_Rset(uint8_t value);//设置RSET值
uint16_t AD9102_GetCalStatus(void);//读取校准状态
uint8_t AD9102_Cal_Reset(void);//重置校准
uint8_t AD9102_CalibrationMode(uint8_t value);//校准模式,1为进入校准模式,0为退出校准模式
uint8_t AD9102_Cal_Offset(uint8_t value);//校准偏置设置
uint8_t AD9102_CalClk_EN(uint8_t value);//启动校准时钟,1为开启,0为关闭
uint8_t AD9102_CalClk_Div(uint8_t value);//校准时钟分频
uint8_t AD9102_GetCompCalResult(void);//获取比较器校准结果
uint8_t AD9102_GetCalComp(void);//读取校准是否完成
uint8_t AD9102_StartCal(uint8_t value);//开始校准,1为开启校准,0为关闭
uint8_t AD9102_Pattern_Update(void);//更新图案寄存器
uint8_t AD9102_ReadBackMode(uint8_t value);//读回模式
uint8_t AD9102_MemoryAccess(uint8_t value);//内存接入模式
uint8_t AD9102_RunMode(uint8_t value);//软件启动和终止图案,0为启动,1为停止
uint8_t AD9102_GetPatternStatus(void);//获取图案生成状态
uint8_t AD9102_PatternMode(uint8_t mode);//波形输出模式,0为连续输出,1为有限次数输出
uint8_t AD9102_PatternDelay(uint16_t value);//波形延迟
uint8_t AD9102_DigitalOffset(uint16_t value);//数字偏置设置
uint8_t AD9102_WavePrestoreSel(uint8_t value);//预储存配置选择,0:恒定值,1:锯齿波,2:伪随机序列,3:DDS输出
uint8_t AD9102_WaveSel(uint8_t value);//波形选择,0:RAM值,1:预储存波形,2:使用延迟和周期的预储存波形,3:RAM调制的预储存波形
uint8_t AD9102_DACHoldCycle(uint8_t value);//DAC保持时间,0至15周期
uint8_t AD9102_PatternPeriodBASE(uint8_t value);//DAC周期和波形周期关系
uint8_t AD9102_DACDelay(uint8_t value);//DAC延迟
uint8_t AD9102_PatternPeriod(uint16_t value);//波形周期设置
uint8_t AD9102_PatternRepeat(uint8_t value);//波形重复输出次数
uint8_t AD9102_DOUT_Delay(uint16_t value);//触发后DOUT拉高延迟
uint8_t AD9102_DOUT_ManualSet(uint8_t value);//手动设置DOUT值
uint8_t AD9102_DOUT_Function(uint8_t value);//DOUT输出模式,0为手动设置,1为波形生成和停止标志
uint8_t AD9102_DOUT_Time(uint8_t value);//DOUT持续时间
uint8_t AD9102_DAC_ConstValue(uint16_t value);//DAC恒定值设置,0至0xFFF
uint8_t AD9102_DigitalGain(uint16_t value);//数字增益设置
uint8_t AD9102_SawtoothSamp(uint8_t value);//锯齿波每个阶梯采样次数,1至64
uint8_t AD9102_SawtoothType(uint8_t value);//锯齿波类型,0为上升锯齿波,1为下降锯齿波,2为对称锯齿波,3为零输出
uint8_t AD9102_DDS_SetFreq(uint32_t freqcode);//设置DDS频率,代码0至0xFFFFFF
uint8_t AD9102_DDS_SetFreq_Hz(double freq);//设置DDS频率,单位Hz,主频180MHz分辨率最小10.728836Hz
uint8_t AD9102_DDS_PhaseSet(uint16_t phasecode);//DDS相位设置,0至0xFFFF
uint8_t AD9102_DDS_PhaseSet_Deg(double phase);//设置DDS相位,单位度
uint8_t AD9102_DDS_PhaseSet_Rad(double phase);//设置DDS相位,单位弧度
uint8_t AD9102_DelayMode(uint8_t value);//触发延迟模式,0:每个波形都延迟,1:只延迟第一个波形
uint8_t AD9102_DDS_CosineWave(uint8_t value);//DDS输出正弦波或余弦波,1为余弦,0为正弦
uint8_t AD9102_RAM_ClockSource(uint8_t channel);//RAM时钟来源,0:MCLK,1:DDS(MSB)
uint8_t AD9102_Phase_RAM_EN(uint8_t value);//DDS相位偏移从RAM读取数据,0为从寄存器读取,1为RAM读取
uint8_t AD9102_DDSTuningRAM_EN(uint8_t value);//DDS频率控制字来源,0为寄存器,1为RAM
uint8_t AD9102_DDS_RAMTuning_Config(uint8_t value);//DDSRAM调频设置
uint8_t AD9102_StartDelay(uint16_t value);//DAC延迟,0至0xFFFF
uint8_t AD9102_StartAddress(uint16_t value);//DAC输出波形数据起始地址
uint8_t AD9102_StopAddress(uint16_t value);//DAC输出波形结束地址
uint8_t AD9102_DDSCycle(uint16_t value);//DDS周期设置
uint16_t AD9102_GetError(void);//获取错误信息
uint16_t AD9102_ReadRAM(uint16_t addr);//读取RAM,16位位宽,地址0x6000至0x6FFF
uint8_t AD9102_WriteRAM(uint16_t addr,int16_t data);//写入寄存器,12位位宽,地址0x6000至0x6FFF
uint8_t AD9102_ExtGain(double value);//设置外部增益
uint8_t AD9102_SetRAMWaveAddr(uint16_t start,uint16_t stop);//设置RAM波形起始地址和结束地址
uint8_t AD9102_OutputSineWave(double freq,double amplitude,double phase);//输出正弦波
uint8_t AD9102_OutputRectangularWave(double freq,double amplitude,double Duty);//输出方波
uint8_t AD9102_OutputTriangle(double freq,double amplitude,double peak);//输出三角波
uint8_t AD9102_OutputLOWFREQRect(double freq,double amplitude,double duty);//输出低频方波
uint8_t AD9102_OutputLOWFREQRTriangle(double freq,double amplitude,double peak);//输出低频三角波
uint8_t AD9102_OutputConstValue(int16_t value);//输出恒定值
uint8_t AD9102_OutputAnyWave(int *wavedata,uint16_t length);//输出任意波
uint8_t AD9102_MainClk(uint8_t level);//设置主频挡位,0为168MHz,1为8MHz
double AD9102_FixGain(double value);//增益校准
四、结果测试
1.实物图
2.正弦波输出测试
测试代码如下:
AD9102_Init();//上电初始化
AD9102_DisTrig();//终止触发
AD9102_ExtGain_Init();//外部增益初始化
AD9102_DigitalGain(0x400);
AD9102_MainClk(1);
AD9102_OutputSineWave(1000000,2000,0);//输出正弦波,(频率,振幅,相位)
AD9102_Trig();//触发
输出结果:
输出频率为1MHz,振幅为2Vpp,相位为0度的正弦波
3.三角波输出测试
测试代码如下:
AD9102_Init();//上电初始化
AD9102_DisTrig();//终止触发
AD9102_ExtGain_Init();//外部增益初始化
AD9102_DigitalGain(0x400);
AD9102_MainClk(1);
AD9102_OutputTriangle(1000000,3000,50);//输出三角波(频率,振幅,对称度)
AD9102_Trig();//触发
输出结果:
输出频率为1MHz,振幅为3Vpp,对称度为75%的三角波
4.方波输出测试
测试代码如下:
AD9102_Init();//上电初始化
AD9102_DisTrig();//终止触发
AD9102_ExtGain_Init();//外部增益初始化
AD9102_DigitalGain(0x400);
AD9102_MainClk(1);
AD9102_OutputRectangularWave(1000000,5000,30);//输出方波(频率,振幅,占空比)
AD9102_Trig();//触发
输出结果:
输出频率为1MHz,振幅为5Vpp,对称度为30%的方波(负载电阻50欧姆)
5.任意波输出测试
测试代码如下:
AD9102_Init();//上电初始化
AD9102_DisTrig();//终止触发
AD9102_ExtGain_Init();//外部增益初始化
AD9102_DigitalGain(0x400);
AD9102_MainClk(1);
AD9102_OutputAnyWave(wavedata2,3000);//输出任意波(波形数组,波形长度)
AD9102_Trig();//触发
其中wavedata2为任意波形数据,是一个正弦波,三角波,方波交替出现的波形,部分如下:
输出结果: