【GD32】AD9833模块 DDS模块 提供测试程序 正弦波/方波/三角波信号发生器

news2024/12/23 22:56:24

2.45 AD9833 DDS模块

2.45.1 模块来源

采购链接:
AD9833模块 DDS模块 提供测试程序 正弦波/方波/三角波信号发生器
资料下载:
https://pan.baidu.com/s/1JZ0ga4uTyXUq5u-Or9BVlg?pwd=GOOD
提取码:GOOD

2.45.2 规格参数
工作电压:2.3 V至5.5 V电源供电
工作电流:12.65 mW(3 V时)
通信方式:3线SPI接口
芯片引脚数量:10引脚MSOP封装
2.45.3 移植过程
我们的目标是在梁山派GD32F470上能够通过模块输出波形的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.45.3.1 查看资料
模块作用:
可编程波形发生器,能够产生正弦 波、三角波和方波输出。各种类型的检测、信号激励和时 域反射(TDR)应用都需要波形发生器。输出频率和相位可 通过软件进行编程,调整简单。无需外部元件。频率寄存 器为28位:时钟速率为25 MHz时,可以实现0.1 Hz的分辨 率;而时钟速率为1 MHz时,则可以实现0.004 Hz的分辨率。
模块驱动:
AD9833通过一个三线式串行接口写入数据。该串行接口能 够以最高40 MHz的时钟速率工作,并且与DSP和微控制器 标准兼容。该器件采用2.3 V至5.5 V电源供电。注意:在生成方波时会过冲(可以在加入电源滤波电路缓解但不能彻底解决!!!)
2.45.3.2 引脚选择
在这里插入图片描述
2.45.3.3 移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为AD9833.c与ccd.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件AD9833.c中,编写如下代码。

 /********************************************************************************
   * 测试硬件:立创·梁山派开发板GD32F470ZGT6    使用主频200Mhz    晶振25Mhz
   * 版 本 号: V1.0
   * 修改作者: LCKFB
   * 修改日期: 2023年06月12日
   * 功能介绍:      
   ******************************************************************************
 
 *********************************************************************************/

#include "AD9833.h"
#include "gd32f4xx.h"


/******************************************************************
 * 函 数 名 称:Ad9833GpioConfig
 * 函 数 说 明:Ad9833的初始化
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:软件SPI的配置
******************************************************************/
void AD9833_GpioConfig(void)
{
        rcu_periph_clock_enable(RCU_SDATA);     //使能SDATA引脚时钟
    rcu_periph_clock_enable(RCU_SCLK);      //使能SCLK引脚时钟
    rcu_periph_clock_enable(RCU_FSNYC);     //使能FSNYC引脚时钟
    
    //配置SDATA为上拉推挽输出
    gpio_mode_set(PORT_SDATA, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_SDATA);        
    gpio_output_options_set(PORT_SDATA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_SDATA);
    //输出高电平
    gpio_bit_set(PORT_SDATA, GPIO_SDATA); 

    //配置SCLK为上拉推挽输出
        gpio_mode_set(PORT_SCLK, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP,  GPIO_SCLK);        
    gpio_output_options_set(PORT_SCLK, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,  GPIO_SCLK); 
    //输出高电平
    gpio_bit_set(PORT_SCLK,  GPIO_SCLK); 

    //配置FSNYC为上拉推挽输出
        gpio_mode_set(PORT_FSNYC, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_FSNYC);       
    gpio_output_options_set(PORT_FSNYC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_FSNYC); 
    //输出高电平
    gpio_bit_set(PORT_FSNYC, GPIO_FSNYC);         
}
     


/******************************************************************
 * 函 数 名 称:AD9833_WriteData
 * 函 数 说 明:向AD9833写入16位数据
 * 函 数 形 参:txdata=写入的16位数据
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:FSNYC低电平有效,数据在时钟的下降沿被采集数据,在时钟的上升沿更新数据
******************************************************************/
void AD9833_WriteData(uint16_t txdata)
{
    int i;
    ADI_FSNYC_OUT(1);
    
    ADI_SCLK_OUT(0);
    ADI_SCLK_OUT(1);
    
    ADI_FSNYC_OUT(0);
    //写16位数据
    for(i=0;i<16;i++)
    {  
        if (txdata & 0x8000)
        {
           ADI_SDATA_OUT(1);
        }
        else
        {
            ADI_SDATA_OUT(0);
        }
        ADI_SCLK_OUT(0);
        txdata<<=1;
        ADI_SCLK_OUT(1);
        
    }
    ADI_FSNYC_OUT(1);
}
/******************************************************************
 * 函 数 名 称:AD9833_SetFrequency
 * 函 数 说 明:ad9833设置频率寄存器
 * 函 数 形 参:reg=待写入的频率寄存器  fout=频率值
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void AD9833_SetFrequency(unsigned short reg, double fout)
{
    int frequence_LSB=0, frequence_MSB=0;
    double   frequence_mid=0, frequence_DATA=0;
    long int frequence_hex=0;
    /*********************************计算频率的16进制值***********************************/
    //如果时钟频率不为25MHZ,修改该处的频率值,单位MHz ,AD9833最大支持25MHz
    frequence_mid = 268435456/25;//适合25M晶振
    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_SetPhase
 * 函 数 说 明:ad9833设置相位寄存器
 * 函 数 形 参:reg=待写入的相位寄存器    fout=相位值  
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
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=输出的相位寄存器类型
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
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 =  波形类型
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
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);
}

在文件AD9833.h中,编写如下代码。

 /********************************************************************************
    * 测试硬件:立创·梁山派开发板GD32F470ZGT6    使用主频200Mhz    晶振25Mhz
    * 版 本 号: V1.0
    * 修改作者: LCKFB
    * 修改日期: 2023年06月12日
    * 功能介绍:      
    ******************************************************************************

  *********************************************************************************/
#ifndef _AD9833_H__
#define _AD9833_H__

#include "GD32F4XX.h"


//引脚定义
#define RCU_SDATA   RCU_GPIOD
#define PORT_SDATA  GPIOD
#define GPIO_SDATA  GPIO_PIN_5

#define RCU_SCLK    RCU_GPIOD
#define PORT_SCLK   GPIOD
#define GPIO_SCLK   GPIO_PIN_4

#define RCU_FSNYC   RCU_GPIOD
#define PORT_FSNYC  GPIOD
#define GPIO_FSNYC  GPIO_PIN_1


//端口输出
#define  ADI_SDATA_OUT(X)       gpio_bit_write(PORT_SDATA, GPIO_SDATA, (X)?SET:RESET) 
#define  ADI_SCLK_OUT(X)        gpio_bit_write(PORT_SCLK, GPIO_SCLK, (X)?SET:RESET) 
#define  ADI_FSNYC_OUT(X)       gpio_bit_write(PORT_FSNYC, GPIO_FSNYC, (X)?SET:RESET) 

//输出波形
#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))    //方波

//相关寄存器
#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)

//命令控制位
#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_GpioConfig(void);
void AD9833_WriteData(uint16_t 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

2.45.4 移植验证

在自己工程中的main主函数中,编写如下。

 /********************************************************************************
   * 测试硬件:立创·梁山派开发板GD32F470ZGT6    使用主频200Mhz    晶振25Mhz
   * 版 本 号: V1.0
   * 修改作者: LCKFB
   * 修改日期: 2023年06月12日
   * 功能介绍:      
   ******************************************************************************
 *********************************************************************************/
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "sys.h"
#include "bsp_usart.h"
#include "AD9833.h"

int main(void)
{       
    systick_config();        
    usart_gpio_config(115200U);    
    AD9833_GpioConfig();
    while(1) 
    {
        //输出 2K 三角波
        AD9833_Setup(AD9833_REG_FREQ0,2000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_TRIANGLE);
        delay_1ms(2000);
        delay_1ms(2000);
        delay_1ms(2000);     
        delay_1ms(2000);     

        //输出 50K 正弦波
        AD9833_Setup(AD9833_REG_FREQ0,50000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_SINUS);
        delay_1ms(2000);
        delay_1ms(2000);     
        delay_1ms(2000);     
        delay_1ms(2000);     

        //输出 1M 方波
        AD9833_Setup(AD9833_REG_FREQ0,1000000.0,AD9833_REG_PHASE1,1024,AD9833_OUT_MSB);
        delay_1ms(2000);
        delay_1ms(2000);     
        delay_1ms(2000);     
        delay_1ms(2000);               
    }
}

移植现象:该实例是产生一个2KHZ的三角波,8秒后产生50K正弦波,8秒后再产生1M方波,将探头连接到示波器上观察!!注意:生成方波有过冲是正常现象。
在这里插入图片描述
在这里插入图片描述
移植成功示例,见文件2.45.4-1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1595130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(七)PostgreSQL的用户管理

PostgreSQL的用户管理 1 创建用户&#xff08;角色&#xff09; CREATE USER现在是CREATE ROLE的别名。唯一的区别是&#xff0c;当命令的拼写为CREATE USER时&#xff0c;默认情况下会使用LOGIN&#xff0c;而当命令拼写为CREATE ROLE时会使用NOLOGIN。 官方文档&#xff1a…

MyBatis-Spring整合

引入Spring之前需要了解mybatis-spring包中的一些重要类&#xff1b; http://www.mybatis.org/spring/zh/index.html 什么是 MyBatis-Spring&#xff1f; MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。 知识基础 在开始使用 MyBatis-Spring 之前&#x…

如何编写易于访问的技术文档 - 最佳实践与示例

当你为项目或工具编写技术文档时&#xff0c;你会希望它易于访问。这意味着它将为全球网络上的多样化受众提供服务并可用。 网络无障碍旨在使任何人都能访问网络内容。设计师、开发人员和撰写人员有共同的无障碍最佳实践。本文将涵盖一些创建技术内容的最佳实践。 &#xff0…

编曲知识19:自动化处理 发送原理 混响 延迟

自动化处理 发送原理 混响 延迟小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_661a68eae4b023c0a96a8b36?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 自动化处理 自动化 鼠标挪动到轨道左下角打开自动化轨道 或右键轨道-左键单击…

力扣 | 24. 两两交换链表中的节点

两两交换链表中的节点 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 你不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 输入&#xff1a;head 1->2->3->4->5->NULL 输出&#xff1a;2->1-&g…

信号反射的几个重要体现及电路设计

本文要点&#xff1a; 1&#xff0c;介绍信号分列反射的具体表现&#xff1b; 2&#xff0c;结合具体电路分析。 信号沿传输线向前传播时&#xff0c;每时每刻都会感受到一个瞬态阻抗&#xff0c;这个阻抗可能是传输线本身的&#xff0c;也可能是中途或末端其他元件的。对于信…

HashMap扩容原理(带源码分析)

HashMap的扩容原理 1.扩容流程图 注&#xff1a;拆分链表的规则 这里拆分链表时的一个比较&#xff1a;e.hash & oldCap 0 意思是&#xff1a;某一个节点的hash值和老数组容量求&运算。如果等于0&#xff0c;当前元素在老数组中的位置就是在新数组中的位置。如果不等…

numpy学习笔记(3),数组连接

6. 连接数组 6.1. 连接数组&#xff0c; 6.2. 分割数组&#xff0c; 6.3. 算术运算&#xff0c; 6.4. 广播&#xff08;重点&#xff09; 6.1 连接数组 concatenatehstackvstack 6.1.1 使用concatenate函数 沿指定轴连接多个数组&#xff0c;语法格式如下&#xff1a; num…

最新版守约者二级域名分发系统

主要功能 二级域名管理&#xff1a; 我们的系统提供全面的二级域名管理服务&#xff0c;让您轻松管理和配置二级域名。 域名分发&#xff1a;利用我们先进的域名分发技术&#xff0c;您可以自动化地分配和管理域名&#xff0c;确保每个用户或客户都能及时获得所需的域名资源。…

串口RS485

1.原理 全双工&#xff1a;在同一时刻可以同时进行数据的接收和数据的发送&#xff0c;两者互不影响 半双工&#xff1a;在同一时刻只能进行数据的接收或者数据的发送&#xff0c;两者不能同时进行 差分信号幅值相同&#xff0c;相位相反&#xff0c;有更强的抗干扰能力。 干…

Java实现二叉树(下)

1.前言 http://t.csdnimg.cn/lO4S7 在前文我们已经简单的讲解了二叉树的基本概念&#xff0c;本文将讲解具体的实现 2.基本功能的实现 2.1获取树中节点个数 public int size(TreeNode root){if(rootnull){return 0;}int retsize(root.left)size(root.right)1;return ret;}p…

基于深度学习的花卉检测系统(含PyQt界面)

基于深度学习的花卉检测系统&#xff08;含PyQt界面&#xff09; 前言一、数据集1.1 数据集介绍1.2 数据预处理 二、模型搭建三、训练与测试3.1 模型训练3.2 模型测试 四、PyQt界面实现参考资料 前言 本项目是基于swin_transformer深度学习网络模型的花卉检测系统&#xff0c;…

正确使用@RequestMapping(包含属性详解)

目录 一、基本认知二、RequestMapping的基本使用三、深入学习RequestMapping1、RequestMapping的源码2、RequestMapping的属性2.1 path2.2 method2.3 params2.4 headers2.5 consumes2.6 produces2.7 name 一、基本认知 客户端发起Http请求&#xff0c;会提供一个URL [协议://域…

Unity 2D让相机跟随角色移动

相机跟随移动 最简单的方式通过插件Cinemachine 在窗口/包管理器选择全部找到Cinemachine&#xff0c;导入。然后在游戏对象/Cinemachine创建2D Camera。此时层级中创建一个2D相机。选中人物拖入检查器Follow。此时相机跟随人物移动。 修改相机视口距离 在检查器中Lens下调正…

单细胞RNA测序(scRNA-seq)构建人类参考基因组注释

细胞定量是scRNA-seq重要的分析步骤,主要是进行细胞与基因的定量, cell ranger将比对、质控、定量都封装了起来,使用起来也相当便捷。 单细胞RNA测序(scRNA-seq)基础知识可查看以下文章: 单细胞RNA测序(scRNA-seq)工作流程入门 单细胞RNA测序(scRNA-seq)细胞分离与…

logistic分叉图

MATLAB代码 % 初始化 r_min 2.5; % 参数r的起始值 r_max 4.0; % 参数r的结束值 r_step 0.001; % 参数r的步长 r_values r_min:r_step:r_max; % 参数r的范围% 分岔图数据初始化 num_iterations 1000; % 总迭代次数 num_last_points 100; % 用于绘图的最后的这些…

MySQL Innodb 中的排它锁、共享锁、意向锁、记录锁、间隙锁、临键锁、死锁讲解

一、MySQL 锁机制 MySQL作为流行的关系型数据库管理系统之一&#xff0c;在处理并发访问时&#xff0c;锁起着至关重要的作用。锁的使用可以确保数据的完整性&#xff0c;同时也是实现并发操作的必备工具。在MySQL Innodb 引擎中锁可以理解为两个方向的东西&#xff0c;一个是…

stm32移植嵌入式数据库FlashDB

本次实验的程序链接stm32f103FlashDB嵌入式数据库程序资源-CSDN文库 一、介绍 FlashDB 是一款超轻量级的嵌入式数据库&#xff0c;专注于提供嵌入式产品的数据存储方案。与传统的基于文件系统的数据库不同&#xff0c;FlashDB 结合了 Flash 的特性&#xff0c;具有较强的性能…

白话微机:10.民风淳朴的MCS-51小镇(小镇方言:汇编)

1. 基本结构与周期 MCS-51系列单片机属于8位单片机用 8051单片机构成最小应用系统时&#xff0c;只要将单片机接上时钟电路和复位电路即可MCS-51单片机由CPU、存储器和I/O三部分组成CPU是指&#xff1a;运算器和控制器 “PC CPU 3BUS RAM I/O” 在执行指令过程中&#xff…