AD9833介绍与应用(C语言实现)

article/2025/10/19 1:04:25

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;elseAD9833_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最大支持25MHzfrequence_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_LSBfrequence_LSB=frequence_LSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14位frequence_MSB=frequence_hex>>14; //frequence_hex高16位送给frequence_HSBfrequence_MSB=frequence_MSB&0x3fff;//去除最高两位,16位数换去掉高位后变成了14位frequence_LSB=frequence_LSB|reg;frequence_MSB=frequence_MSB|reg;AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1AD9833_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位为1AD9833_WriteData(0x2100); //选择数据一次写入,B28位和RESET位为1AD9833_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);   //串口初始化为9600AD9833_Init();//输出三角波AD9833_Setup(AD9833_REG_FREQ0,10000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_TRIANGLE);while(1){printf("t:%d\n",t);delay_ms(500);t++;}}

http://chatgpt.dhexx.cn/article/EETFgWDH.shtml

相关文章

2021电赛预测—手把手带你玩转DDS模块AD9833

1、电赛预测 摘要&#xff1a;原定于7月28日才发布的器件清单&#xff0c;提前2天在26号就发布。感觉大家现在应该猜题预测&#xff0c;与其猜题&#xff0c;还不如静下心来做题。盲目猜题是没有必要的&#xff0c;熟悉相关器件倒尤为重要。不要到处去水群聊天&#xff0c;听风…

幻方....

c语言上机。。。。 c写的幻方。 1 /*************************************************************************2 > File Name: code/class/7.c3 > Author: 111qqz4 > Email: rkz2013126.com 5 > Created Time: 2015年11月11日 星期三 19时31分5…

Unity脚本生命周期流程图

转载自【无幻】&#xff1a;http://blog.csdn.net/akof1314/article/details/39323081 渲染 OnPreCull: 在相机剔除场景之前调用此函数。相机可见的对象取决于剔除。OnPreCull 函数调用发生在剔除之前。 OnBecameVisible/OnBecameInvisible: 在对象对于相机可见/不可见时调用此…

SonicUI在MFC中的使用

SonicUI是一个GUI引擎&#xff0c;提供了一些简单的UI组件实现高效率的UI效果&#xff0c;例如&#xff1a;自绘按钮、异形窗体、动画、超链接和图像操作方法。此项目作者开源到CodeProject&#xff0c;地址为&#xff1a;http://www.codeproject.com/KB/GDI/SonicUI.aspx。下载…

将ribbon主题应用到对话框中去(转载)

原帖地址&#xff1a;这里 找了N久&#xff0c;终于在无幻大神这里找到了将ribbon sdi主题应用到对话框程序中的方法&#xff0c;好像这是一个开源的项目&#xff0c;google code里有,地址在 这里。记录下&#xff1a; 1、下载网页里的资源KofPack0.1&#xff0c;vs里打开工程…

如何制作一个横版格斗过关游戏 Cocos2d-x 2.0.4

本文原创版权归 csdn 无幻 所有&#xff0c;转载请详细标明原创作者及出处&#xff0c;以示尊重&#xff01; 作者&#xff1a;无幻 原文&#xff1a;http://blog.csdn.net/akof1314/article/details/8549150 本文实践自 Allen Tan 的文章《How To Make A Side-Scrolling Bea…

VC复制HTML格式到剪贴板 HTML Clipboard Format

本文作者&#xff1a;无幻 测试环境&#xff1a;Windows 7 开发环境&#xff1a;Visual Studio 2008 SP1 参照MSDN和帮助&#xff0c;在VC下测试代码如下&#xff1a; C语言: BOOL CBaseDialogDlg::CopyHtmlToClip( const CString &strHtml ) { // 1)转换成UTF-8 CW2A p…

如何制作一个横版格斗过关游戏(2) Cocos2d-x 2.0.4 .

本文原创版权归 csdn 无幻 所有&#xff0c;转载请详细标明原创作者及出处&#xff0c;以示尊重&#xff01; 作者&#xff1a;无幻 原文&#xff1a;http://blog.csdn.net/akof1314/article/details/8572546 在第一篇《如何制作一个横版格斗过关游戏》基础上&#xff0c;增加…

Cocos2d-x 2.0.1 学习tests示例(二)ActionsTest

作者&#xff1a;无幻 博客&#xff1a; http://blog.csdn.net/akof1314 初学Cocos2d-x&#xff0c;如文章有错误之处&#xff0c;欢迎指出 自上篇《 Cocos2d-x 2.0.1 学习tests示例&#xff08;一&#xff09;Manual Transformation》继续学习tests示例。 1 2 3 4 5 6 7 8 9…

改变CMFCRibbonBar高度

本文作者&#xff1a;无幻 测试环境&#xff1a;Windows XP 开发环境&#xff1a;Visual Studio 2010 要改变CMFCRibbonBar的高度&#xff0c;需要重载CalcFixedLayout函数&#xff0c;例如如下&#xff1a; 头文件&#xff1a; #pragma once// // CKofMFCRibbonQuickAccessTo…

Cocos2d-x 2.0.1 学习tests示例(一)Manual Transformation

作者&#xff1a;无幻 博客&#xff1a; http://blog.csdn.net/akof1314 初学Cocos2d-x&#xff0c;如文章有错误之处&#xff0c;欢迎指出 从上次《Cocos2d-x 2.0 从HelloWorld入手》&#xff0c;继续学习tests示例。 1.右键点击“Solution ‘cocos2d-win32.vc2008’"&…

Unity3d好东西应该被看见_分享一个Assetbundle分析工具

关于Assetbundle分析 很多年前获得过搜狐畅玩的代码 不确定是不是腾讯流出版本&#xff0c;反正经历了深圳畅玩&#xff0c;到北京畅玩。 整个中国地图&#xff0c;从南到北&#xff0c;成熟的Unity手游团队&#xff0c;手上几乎都是那一份ASSETBUNDLE处理代码 功能太多&am…

Visual C++ 2008 Feature Pack 示例截图

Visual C 2008 Feature Pack 示例截图 by 无幻 百度文库&#xff1a;http://wenku.baidu.com/view/f09e5575a417866fb84a8eb6.html 豆丁文档&#xff1a;http://www.docin.com/p-55873972.html CSDN下载&#xff1a;http://download.csdn.net/source/2380293 动态图片显示…

CRichEditCtrlEx支持静态表情聊天类的使用

本文作者&#xff1a;无幻 博客地址&#xff1a;http://blog.csdn.net/akof1314 平时我们在做IM聊天之类的软件的时候&#xff0c;一般都会使用Rich Edit控件来作为聊天编辑框和聊天记录框的控件&#xff0c;在之前的VC知识库看过《类似 MSN 信息发送框的制作(上)》、《类似 MS…

方舟服务器文件夹,方舟生存进化文件夹里哪个才是打开游戏 | 手游网游页游攻略大全...

发布时间&#xff1a;2016-04-07 有许多玩家反映在方舟生存进化当中自己在洞穴里只能挖到石头,挖不到水晶,这是怎么回事呢?接下来小编就为大家带来方舟生存进化在洞穴里怎么才能采集到水晶的详细攻略. 答:用铁镐挖才能采集到水晶,用石镐就只能采到石头,希望能帮到 ... 标签&am…

【VC学习】VC2010 Windows Media Player控件的使用技巧

声明&#xff1a;以下博客基于无幻 VC2008 Windows Media Player控件的使用技巧&#xff0c;自行学习整理 附上原地址&#xff1a;http://blog.csdn.net/akof1314/article/details/4900040 本是跟着老师选修课学习&#xff0c;编程都是基于MFC&#xff0c;手动在toolbox里面修…

真Unity3d_分享一个编辑器扩展模型预览视图Mesh Preview Inspector窗口

预览窗口 在 Unity 编辑器界面上可以看到除了 Game 视图、Scene 视图,其他的视图也会出现绘制三维物体的地方,比如检视器的预览窗口,当选中网格时,会对网格进行预览,如下所示: 预览窗口是UnityEditor的底层框架 UnityEditor框架图 可看我之前的博客: https://blog.c…

lookup

这里注意数组 1.{ sum((E3:E11)*(F3*F11) )} 代表数组运算ctrlentershift&#xff0c;因为(E3:E11)*(F3*F11)返回的是数组 2. sum(E3:E11)其中E3:E11也是数组但是直接enter就可以‘ 为什么&#xff1a;因为(E3:E11)是本来就存在的列&#xff0c;(E3:E11)*(F3*F11)是运算出来…

access Dlookup的值写入表

目的 写入供应商名称&#xff0c;自动弹出供应商代码&#xff0c;然后将该条记录增加到表中 方法 在供应商名称的属性表写&#xff0c;不是供应商代码的属性表 在事件过程中写入- Private Sub 供应商名称_AfterUpdate() Me.供应商代码.Value DLookup(“供应商代码”, “Q_…

access-vba之用户登录窗口

界面截图如下: 创建一个窗体设计,然后在设计中找到控件 因为科室更新,带来了用户的更新,所有用户的行来源不指定,但科室的行来源要指定 最后,我们通过VBA实现用户的行来源,这样可以保证在科室变化的情况下,用户实时显示每个科室的人员 Private Sub keshi_AfterUpdate(…