1.特性
-
低功耗、可编程波形发生器,能产生正弦波、三角波和方波的输出;
-
主频时钟为25MHz时,可实现0.1Hz的分辨率;主频时钟为1MHz时,可实现0.004Hz的分辨率;
-
三线式串行接口(SDATA、SCLK、FSYNC)写入数据,最高能以40MHz的时钟速率工作,支持SPI通信,一个输出信号接口(VOUT),输出信号没有负电压,输出最大电压值为650mv,输出最小电压值为38mv,不是为0;
-
输出频率范围在0MHz至12.5MHz;
注意:方波输出的最大的电压值为供电电压值3.3V,并非650mv,其是作为时钟源使用。
2.引脚配置与功能描述
注意:MCLK是数字时钟输入,可接一个有源晶振,若直接连接到MCU上,可用PWM波或定时器去拉高拉低控制,但最好外接一个晶振,输出频率会受此时钟引脚的控制。
3.功能框图说明
由功能框图可看出:
输入:AD9833的输入由FSYNC引脚、SCLK引脚、SDATA引脚来控制。
寄存器:AD9833有1个控制寄存器、两个频率寄存器、两个相位寄存器、1个相位累加器。
输出:VOUT输出波形主要根据10位DAC输出正弦波和三角波,或MSB直接输出以及MSB/2输出方波。
工作流程:通过FSYNC引脚、SCLK引脚、SDATA引脚对控制寄存器、频率寄存器、相位寄存器进行写入,频率寄存器中的值输入到相位累加器中,再与相位寄存器中的值来进行相位偏移,但输出会被截断至12位,并在SIN ROM中寻找相对应相位的DAC的值经过10DAC输出或MSB直接输出或MSB/2输出到VOUT上。
注意:MSB输出的是方波,是用作时钟源使用的,输出的是供电电压3.3V,MSB输出的时钟频率是MSB/2的两倍。
4.时序特性
由时序图可看到:
-
MCLK的一个周期时间最小值为40ns,即时钟频率最大为25MHZ;
-
进行串行数据传输是,先拉低FSYNC引脚,串行数据会在16个时钟脉冲的SCLK下降沿移入器件的输入移位寄存器中。注意FSYNC拉低后至SCLK拉低之间的建立时间为5ns。
-
在FSYNC变为低电平时,SCLK必须为处于高电平。
5.寄存器及功能描述
5.1 频率和相位寄存器
AD9833包含两个28位的频率寄存器和两个12位的相位寄存器:
5.2 控制寄存器
AD9833包含一个16位的控制寄存器,可实现配置AD9833的操作,mode位之外的所有控制位均在MCLK的内部下降沿采样。
5.1.1 写入频率寄存器
需将BIT D15和BIT D14设置为频率寄存器的地址,BIT D15和BIT D14设置为01,写入到频率寄存器0,BIT D15和BIT D14设置为10,写入到频率寄存器1。
28位频率寄存器第一次写入包含14个LSB,第二次写入包含14个MSB。
当更改频率寄存器全部内容时,需对同一个频率寄存器地址连续写入两次数据,此时需要将B28(D13)控制位置1.
当只需更新频率寄存器的14个MSB或14个LSB时,将B28(D13)控制位置0,此时可单独更新频率寄存器的14个MSB或14个LSB,同时要将HLD(D12)这个位中确定要更新的具体14个位,HLD(D12)置0,即更新14个LSB,HLD(D12)置1,则更新14个MSB。
5.1.2 写入相位寄存器
需将BIT D15和BIT D14设置为相位寄存器的地址,即将BIT D15和BIT D14设置为11,BIT D13确定将载入的相位寄存器,BIT D13置0时,写入到相位寄存器0,BIT D13置1时,写入到相位寄存器1,
5.1.3 复位功能(D8控制)
复位操作不会使相位、频率或控制寄存器复位,会使相应的内部寄存器复位为0。
在AD9833上电时,器件应该复位一次。
reset置0后的8个MCLK周期内,DAC输出端会出现信号。
5.1.4 SLEEP功能
可降低功耗。
5.1.5 VOUT输出
VOUT输出包括DAC数据的MSB、正弦波输出或三角波输出。由OPBINTEN(D5)和mode(D1)bit控制。
6.C语言实现
6.1 ad9833.h文件
#ifndef _AD9833_H #define _AD9833_H #include 'sys.h' //AD9833 GPIO #define AD9833_SDATA PAout(7) //SDATA #define AD9833_SCLK PAout(5) //SCLK #define AD9833_FSYNC PAout(4) //FSYNC /* WaveMode */ #define AD9833_OUT_SINUS ((0 << 5) | (0 << 1) | (0 << 3)) #define AD9833_OUT_TRIANGLE ((0 << 5) | (1 << 1) | (0 << 3)) #define AD9833_OUT_MSB ((1 << 5) | (0 << 1) | (1 << 3)) #define AD9833_OUT_MSB2 ((1 << 5) | (0 << 1) | (0 << 3)) /* Registers */ #define AD9833_REG_CMD (0 << 14) #define AD9833_REG_FREQ0 (1 << 14) #define AD9833_REG_FREQ1 (2 << 14) #define AD9833_REG_PHASE0 (6 << 13) #define AD9833_REG_PHASE1 (7 << 13) /* Command Control Bits */ #define AD9833_B28 (1 << 13) #define AD9833_HLB (1 << 12) #define AD9833_FSEL0 (0 << 11) #define AD9833_FSEL1 (1 << 11) #define AD9833_PSEL0 (0 << 10) #define AD9833_PSEL1 (1 << 10) #define AD9833_PIN_SW (1 << 9) #define AD9833_RESET (1 << 8) #define AD9833_CLEAR_RESET (0 << 8) #define AD9833_SLEEP1 (1 << 7) #define AD9833_SLEEP12 (1 << 6) #define AD9833_OPBITEN (1 << 5) #define AD9833_SIGN_PIB (1 << 4) #define AD9833_DIV2 (1 << 3) #define AD9833_MODE (1 << 1) void AD9833_Init(void); static void AD9833_Delay(void); void AD9833_WriteData(u16 txdata); void AD9833_SetFrequency(unsigned short reg, double fout); void AD9833_SetPhase(unsigned short reg, unsigned short val); void AD9833_SetWave(unsigned int WaveMode,unsigned int Freq_SFR,unsigned int Phase_SFR); void AD9833_Setup(unsigned int Freq_SFR,double Freq,unsigned int Phase_SFR,unsigned int Phase,unsigned int WaveMode); #endif
6.2 ad9833.c文件
#include 'ad9833.h' /************************************** * 函 数 名: ad9833_init * 功能说明: ad9833初始化 * 形 参: 无 * 返 回 值: 无 *************************************/ void AD9833_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA,ENABLE );; GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //通用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7); } /************************************** * 函 数 名: AD9833_Delay * 功能说明: ad9833延迟 * 形 参: 无 * 返 回 值: 无 *************************************/ static void AD9833_Delay(void) { uint16_t i; for (i = 0; i < 1; i ); } /************************************** * 函 数 名: ad9833_write_data * 功能说明: ad9833写入16位数据 * 形 参: txdata:待写入的16位数据 * 返 回 值: 无 *************************************/ void AD9833_WriteData(u16 txdata) { int i; AD9833_SCLK=1; AD9833_FSYNC=1; AD9833_FSYNC=0; //写16位数据 for(i=0;i<16;i ) { if (txdata & 0x8000) AD9833_SDATA=1; else AD9833_SDATA=0; AD9833_Delay(); AD9833_SCLK=0; AD9833_Delay(); AD9833_SCLK=1; txdata<<=1; } AD9833_FSYNC=1; } /************************************** * 函 数 名: AD9833_SetFrequency * 功能说明: ad9833设置频率寄存器 * 形 参: reg:待写入的频率寄存器 fout:频率值 * 返 回 值: 无 *************************************/ void AD9833_SetFrequency(unsigned short reg, double fout) { int frequence_LSB,frequence_MSB; double frequence_mid,frequence_DATA; long int frequence_hex; /*********************************计算频率的16进制值***********************************/ frequence_mid=268435456/25;//适合25M晶振 //如果时钟频率不为25MHZ,修改该处的频率值,单位MHz ,AD9833最大支持25MHz frequence_DATA=fout; frequence_DATA=frequence_DATA/1000000; frequence_DATA=frequence_DATA*frequence_mid; frequence_hex=frequence_DATA; //这个frequence_hex的值是32位的一个很大的数字,需要拆分成两个14位进行处理; frequence_LSB=frequence_hex; //frequence_hex低16位送给frequence_LSB frequence_LSB=frequence_LSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14位 frequence_MSB=frequence_hex>>14; //frequence_hex高16位送给frequence_HSB frequence_MSB=frequence_MSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14位 frequence_LSB=frequence_LSB|reg; frequence_MSB=frequence_MSB|reg; AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1 AD9833_WriteData(frequence_LSB); AD9833_WriteData(frequence_MSB); } /************************************** * 函 数 名: ad9833_write_data * 功能说明: ad9833设置相位寄存器 * 形 参: reg:待写入的相位寄存器 fout:相位值 * 返 回 值: 无 *************************************/ void AD9833_SetPhase(unsigned short reg, unsigned short val) { unsigned short phase = reg; phase |= val; AD9833_WriteData(phase); } /************************************** * 函 数 名: AD9833_SetWave * 功能说明: ad9833设置波形 * 形 参: WaveMode:输出波形类型 Freq_SFR:输出的频率寄存器类型 Phase_SFR:输出的相位寄存器类型 * 返 回 值: 无 *************************************/ void AD9833_SetWave(unsigned int WaveMode,unsigned int Freq_SFR,unsigned int Phase_SFR) { unsigned int val = 0; val = (val | WaveMode | Freq_SFR | Phase_SFR); AD9833_WriteData(val); } /************************************** * 函 数 名: AD9833_Setup * 功能说明: ad9833设置输出 * 形 参: Freq_SFR:频率寄存器类型 Freq :频率值 Phase_SFR:相位寄存器类型 Phase:相位值 WaveMode:波形类型 * 返 回 值: 无 *************************************/ void AD9833_Setup(unsigned int Freq_SFR,double Freq,unsigned int Phase_SFR,unsigned int Phase,unsigned int WaveMode) { unsigned int Fsel,Psel; AD9833_WriteData(0x0100); //复位AD9833,即RESET位为1 AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1 AD9833_SetFrequency(Freq_SFR,Freq); AD9833_SetPhase(Phase_SFR,Phase); if(Freq_SFR == AD9833_REG_FREQ0) { Fsel = AD9833_FSEL0; } else { Fsel = AD9833_FSEL1; } if(Phase_SFR == AD9833_REG_PHASE0) { Psel = AD9833_PSEL0; } else { Psel = AD9833_PSEL1; } AD9833_SetWave(WaveMode,Fsel,Psel); }
6.3 main.c文件
#include 'sys.h' #include 'delay.h' #include 'usart.h' #include 'ad9833.h' int main(void) { u8 t=0; delay_init(); //延时函数初始化 uart_init(115200); //串口初始化为9600 AD9833_Init(); //输出三角波 AD9833_Setup(AD9833_REG_FREQ0,10000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_TRIANGLE); while(1) { printf('t:%dn',t); delay_ms(500); t ; } }
