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

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

相关推荐

  1. Python绘制正弦三角

    2024-04-15 07:26:02       42 阅读
  2. 提升变换的程序演示

    2024-04-15 07:26:02       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-15 07:26:02       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-15 07:26:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-15 07:26:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-15 07:26:02       20 阅读

热门阅读

  1. C#去掉字符串中所有匹配的字符String.Replace方法

    2024-04-15 07:26:02       16 阅读
  2. 最短路计数

    2024-04-15 07:26:02       54 阅读
  3. MATLAB初学者入门(1)—— 基础知识和功能介绍

    2024-04-15 07:26:02       21 阅读
  4. MATLAB结合C+混编循环计算多孔结构的孔径分布

    2024-04-15 07:26:02       20 阅读
  5. 迁移强化学习论文笔记(一)(Successor Features)

    2024-04-15 07:26:02       48 阅读
  6. Promise实现

    2024-04-15 07:26:02       19 阅读
  7. 第十二章:掌握kubectl常用命令

    2024-04-15 07:26:02       17 阅读
  8. list

    list

    2024-04-15 07:26:02      33 阅读