这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32WBA55CG开发板】过程帖:软件GPIO模拟spi驱动DDS芯片A

共1条 1/1 1 跳转至

【STM32WBA55CG开发板】过程帖:软件GPIO模拟spi驱动DDS芯片AD9834

菜鸟
2025-01-10 23:08:24     打赏

AD9834是一款75 MHz、低功耗DDS器件,能够产生高性能正弦波和三角波输出。其片内还集成一个比较器,支持产生方波以用于时钟发生。当供电电压为3 V时,其功耗仅为20 mW,非常适合对功耗敏感的应用。

AD9834提供相位调制和频率调制功能。频率寄存器为28位;时钟速率为75 MHz,可以实现0.28 Hz的分辨率。同样,时钟速率为1 MHz时,AD9834可以实现0.004 Hz的分辨率。影响频率和相位调制的方法是通过串行接口加载寄存器,然后通过软件或FSELECT/PSELECT引脚切换寄存器。

AD9834通过一个三线式串行接口写入数据。该串行接口能够以最高40 MHz的时钟速率工作,并且与DSP和微控制器标准兼容。

该器件采用2.3 V至5.5 V电源供电。模拟和数字部分彼此独立,可以采用不同的电源供电;例如,AVDD可以是5 V,而DVDD可以是3 V。

AD9834具有掉电引脚(SLEEP),支持从外部控制掉电模式。器件中不用的部分可以掉电,以将功耗降至低点。例如,在产生时钟输出时,可以关断DAC。

该器件采用20引脚TSSOP封装。

应用

  • 频率刺激/波形产生

  • 频率相位调谐和调制

  • 低功耗RF/通信系统

  • 液体和气流测量

  • 传感器应用:接近度、运动和缺陷检测

  • 测试与医疗设备

使用开发板驱动,GPIO模拟SPI

屏幕截图 2025-01-10 230520.png代码

AD9834.h

#ifndef __AD9834_H 
#define __AD9834_H

#include <stdint.h>
#include "stm32wbaxx_hal.h"  //这里根据芯片的具体信号选择自己的头文件
#include "main.h"
#include "usart.h"
#include "stdio.h"

 /*--------------------- AD9834控制信号 16Bit ---------------------*/
/**
 * @brief 在这部分当中,包括了AD9834大部分控制信号的定义,包括了控制信号的宏定义
 * @useage 使用函数AD9834_Write_16Bits()来写入控制信号,
 *         或者也可以使用AD9834_Select_Wave()来写入(后者通常用于直接使用某种波形)
 */
 //设置基本的波形,默认使用频率寄存器0
#define Triangle_Wave    0x2002 
#define Sine_Wave  0x2008 
#define Square_Wave 0x2028

//设置使用频率寄存器1
#define Sine_Wave_Reg1 0x2808  
#define Square_Wave_Reg1 0x2828 
#define Triangle_Wave_Reg1 0x2802

//设置通过引脚选择发生波形
#define SelectByPin 0x2208  //设置PIN_SW 位,选择通过引脚选择频率寄存器、相位和是否不发生波
//在如上的Pin中,包括FS,PS,RESET,SLEEP四根引脚,根据自己的情况写入

//重新复位AD9834
#define RESET_AD9834 0x2100

//停止AD9834的DAC输出
#define STOP_DAC 0x2040

//进阶操作部分
//如果部署需数据手册,不要贸然使用这一部分
//如果使用这部分,请对各个宏进行 | 的运算操作赋予或者使用~进行清除,否则容易出现问题。
#define AD9834_B28  0x2000  //设置为28位模式
#define AD9834_HLB  0x0100  //设置为高速模式,不要轻易使用
#define AD9834_RESET 0x0100  //复位AD9834
#define AD9834_SLEEP1 0x0080  //设置为睡眠模式1
#define AD9834_SLEEP12 0x0040  //设置为睡眠模式2
#define AD9834_OPBITEN 0x0020  //设置为输出使能
#define AD9834_DIV2 0x0010  //设置为分频模式
#define AD9834_MODE 0x0002  //设置为三角波模式
#define AD9834_SIGN_PIBIT 0x0001  //设置为正弦波模式
#define AD9834_PHASE 0xC000  //设置相位寄存器0
#define AD98er_PHASE1 0xE000  //设置相位寄存器1


//------------------AD9834控制和器件特性------------------//
/**
 * @brief 在这部分中,包括了AD9834的一些特性,包括了AD9834的一些控制引脚和所用时钟
 * @notice 在使用AD9834时,需要根据自己的情况修改这部分的内容
 */

 /* AD9834晶振频率 */
#define AD9834_SYSTEM_COLCK     75000000UL 


/* AD9834 控制引脚 */
#define AD9834_FSYNC  AD9834_FSYNC_Pin    
#define AD9834_SCLK   AD9834_SCLK_Pin			
#define AD9834_SDATA  AD9834_SDATA_Pin 		
#define AD9834_RESET  AD9834_RESET_Pin		
#define AD9834_FS  		AD9834_FS_Pin		
#define AD9834_PS  		AD9834_PS_Pin		

//为兼容标准库,提供如下宏
#define GPIO_SetBits(x,y) HAL_GPIO_WritePin((x),(y),GPIO_PIN_SET)
#define GPIO_ResetBits(x,y) HAL_GPIO_WritePin((x),(y),GPIO_PIN_RESET)

//为了便于操作数据引脚,提供如下宏
#define AD9834_FSYNC_SET   GPIO_SetBits(AD9834_FSYNC_GPIO_Port ,AD9834_FSYNC) 
#define AD9834_FSYNC_CLR   GPIO_ResetBits(AD9834_FSYNC_GPIO_Port ,AD9834_FSYNC) 

#define AD9834_SCLK_SET   GPIO_SetBits(AD9834_SCLK_GPIO_Port ,AD9834_SCLK) 
#define AD9834_SCLK_CLR   GPIO_ResetBits(AD9834_SCLK_GPIO_Port ,AD9834_SCLK) 

#define AD9834_SDATA_SET   GPIO_SetBits(AD9834_SDATA_GPIO_Port ,AD9834_SDATA) 
#define AD9834_SDATA_CLR   GPIO_ResetBits(AD9834_SDATA_GPIO_Port ,AD9834_SDATA) 

#define AD9834_RESET_SET   GPIO_SetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) 
#define AD9834_RESET_CLR   GPIO_ResetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET) 

//为了便于操作频率等控制引脚,提供如下宏
#define AD9834_FS_SET   GPIO_SetBits(AD9834_FS_GPIO_Port ,AD9834_FS)
#define AD9834_FS_CLR   GPIO_ResetBits(AD9834_FS_GPIO_Port ,AD9834_FS)

#define AD9834_PS_SET   GPIO_SetBits(AD9834_PS_GPIO_Port ,AD9834_PS)
#define AD9834_PS_CLR   GPIO_ResetBits(AD9834_PS_GPIO_Port ,AD9834_PS)

#define AD9834_RST_SET   GPIO_SetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET)
#define AD9834_RST_CLR   GPIO_ResetBits(AD9834_RESET_GPIO_Port ,AD9834_RESET)

/*--------------------- AD9834操作位声明 ---------------------*/
/**
 * @brief 这部分包括了AD9834的一些操作位的声明,包括了AD9834的一些操作位的宏定义
 * @useage 使用函数AD9834_Write_16Bits()来写入控制信号。
 * @notice 如果有不明便的地方,查阅数据手册进行更改
 */

 //频率寄存器的控制位
#define FREQ_0      0 
#define FREQ_1      1 
#define PHASE_0     0
#define PHASE_1     1

//各个位的定义,留空为0
//如果需要使用其他位,请自行添加相关的变量/宏的定义
#define DB15        0 
#define DB14        0 
#define DB13        B28 
#define DB12        HLB 
#define DB11        FSEL 
#define DB10        PSEL 
#define DB9         PIN_SW 
#define DB8         RESET
#define DB7         SLEEP1 
#define DB6         SLEEP12 
#define DB5         OPBITEN 
#define DB4         SIGN_PIB 
#define DB3         DIV2 
#define DB2         0 
#define DB1         MODE 
#define DB0         0 

//通过操作位的宏定义,可以得到控制信号的值
//可以通过AD9834_Write_16Bits()函数来直接写入控制信号
#define CONTROL_REGISTER    (DB15<<15)|(DB14<<14)|(DB13<<13)|(DB12<<12)|(DB11<<11)|(DB10<<10)|(DB9<<9)|(DB8<<8)|(DB7<<7)|(DB6<<6)|(DB5<<5)|(DB4<<4)|(DB3<<3)|(DB2<<2)|(DB1<<1)|(DB0<<0) 

 /*--------------------- AD9834函数声明 ---------------------*/
void AD9834_Write_16Bits(unsigned int data);  //写一个字到AD9834 
void AD9834_Select_Wave(unsigned int initdata); //选择输出波形 
void AD9834_Init(void);  					//初始化配置 
void AD9834_Set_Freq(unsigned char freq_number, unsigned long freq);//选择输出寄存器和输出频率值 

#endif /* AD9834_H */

AD9834.c

/**********************************************************
 功能:75MHz时钟, AD9834正弦波点频输出,范围0-30M(可编辑0-100M),
            方波:50k-5M,三角波:0-10M,扫频默认正弦波 。
 接口:控制接口请参照AD9834.h
 时间:2022/10/08
 版本:0.9
 作者:康威电子(原作者)

 **********************************************************/
#include "AD9834.h" 

 /****************************************************************
 函数名称: AD9834_Write_16Bits
 功    能: 向AD9834写入16为数据
 参    数: data --  要写入的16位数据
 返回值  : 无
 *****************************************************************/

void AD9834_Write_16Bits(unsigned int data)
{
    unsigned char i = 0;

    AD9834_SCLK_SET;
    AD9834_FSYNC_CLR;

    for (i = 0;i < 16;i++)
    {
        if (data & 0x8000)
            AD9834_SDATA_SET;
        else
            AD9834_SDATA_CLR;

        AD9834_SCLK_CLR;
        data <<= 1;
        AD9834_SCLK_SET;
    }
    AD9834_SDATA_SET;
    AD9834_FSYNC_SET;
}

/***********************************************************************************
函数名称:AD9834_Select_Wave
功    能:写控制位控制,
    --------------------------------------------------
    IOUT正弦波 ,SIGNBITOUT方波 ,写FREQREG0 ,写PHASE0
    ad9834_write_16bit(0x2028)   一次性写FREQREG0
    ad9834_write_16bit(0x0038)   单独改写FREQREG0的LSB
    ad9834_write_16bit(0x1038)   单独改写FREQREG0的MSB
    --------------------------------------------------
    IOUT三角波 ,写PHASE0
    ad9834_write_16bit(0x2002)   一次性写FREQREG0
    ad9834_write_16bit(0x0002)   单独改写FREQREG0的LSB
    ad9834_write_16bit(0x1008)   单独改写FREQREG0的MSB
参    数:initdata -- 要输入的命令
返回值  :无
注    意: 大部分情况下,只需要写入一次,除非要改变波形类型。
          同样可以通过改变控制位来改变波形类型,但是这样会导致频率和相位的改变。
************************************************************************************/
void AD9834_Select_Wave(unsigned int initdata)

{

    AD9834_FSYNC_SET;
    AD9834_SCLK_SET;
    AD9834_RESET_SET;
    AD9834_RESET_SET;
    AD9834_RESET_CLR;

    AD9834_Write_16Bits(initdata);

}

/****************************************************************

函数名称: Init_AD9834

功    能: 初始化后将FS和PS引脚设置为低。
参    数: 无

返回值  : 无

*****************************************************************/
// B6 FS  B5 PS    B7 FSY   B8 SCK   B9 SDA B10 RST 

void AD9834_Init()
{
    GPIO_ResetBits(AD9834_FS_GPIO_Port, AD9834_FS);
    GPIO_ResetBits(AD9834_PS_GPIO_Port, AD9834_PS);
}

/****************************************************************

函数名称: AD9834_Set_Freq

功    能: 设置频率值

参    数: freq_number -- 要写入的平率寄存器(FREQ_0或FREQ_1)
          freq -- 频率值,直接填写赫兹,换算公式为: (Freq_value(value)=Freq_data(data)*FCLK/2^28)
                                                //此时FCLK=75MHz,所以Freq_value=Freq_data*75/2^28

返回值  : 无

*****************************************************************/
void AD9834_Set_Freq(unsigned char freq_number, unsigned long freq)
{
    unsigned long FREQREG = (unsigned long)(268435456.0 / AD9834_SYSTEM_COLCK * freq);
    unsigned int FREQREG_LSB_14BIT = (unsigned int)FREQREG;
    unsigned int FREQREG_MSB_14BIT = (unsigned int)(FREQREG >> 14);

    if (freq_number == FREQ_0)
    {
        FREQREG_LSB_14BIT &= ~(1U << 15);
        FREQREG_LSB_14BIT |= 1 << 14;
        FREQREG_MSB_14BIT &= ~(1U << 15);
        FREQREG_MSB_14BIT |= 1 << 14;
    }
    else
    {
        FREQREG_LSB_14BIT &= ~(1 << 14);
        FREQREG_LSB_14BIT |= 1U << 15;
        FREQREG_MSB_14BIT &= ~(1 << 14);
        FREQREG_MSB_14BIT |= 1U << 15;
    }
    AD9834_Write_16Bits(FREQREG_LSB_14BIT);
    AD9834_Write_16Bits(FREQREG_MSB_14BIT);
}
//============================================================// 
/*   注:使用时先调用初始化函数初始化IO配置,然后调用AD9834_Select_Wave()选择(基本的三种波形为频率寄存器0)
波形,最后选择频率值即可输出。 */

主函数调用

	AD9834_Init();
	AD9834_Select_Wave(Sine_Wave);//Sine_Wave Square_Wave Triangle_Wave
	AD9834_Set_Freq(FREQ_0, 1000);

效果



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]