管脚定义:
手册就先讲到这里,不明白的欢迎评论区留言,另外我会把代码还有手册一并发送给感兴趣的朋友。
AD9833典型应用电路(亲测有效,可以直接拿走)
注意晶振是有源晶振。
spi时序图:
我用的是SPI2,假如你打算用SPI1的话,只需要配置一下IO,然后最重要的是SPI时钟千万别挂载错了,RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );改为RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI2, ENABLE );
而且一定要明白NSS管脚含义,AD9833要求写之前有一个拉低的过程,弄明白NSS信号软硬件管理到底什么含义,这里我推荐用软件管理模式,有内部信号接管,(这时候你就不用管主机的NSS了),这时候STM32的NSS管脚可以当普通IO使用,不过要手动拉高拉低NSS管脚(可以参考AD9833写操作时序)小遍在这里给大家安利一篇博客,这一部分说的比较详细。
https://blog.csdn.net/otto1230/article/details/100122559
一定一定要用这个函数,小遍在这吃过亏,一定要一读一写,否则可能出现写不进去的情况。反正强调一点,不管用SPI做什么,相信我老铁,没毛病。用这个读写函数一点问题都没有。
AD9833驱动代码(重点来了)下面是头文件标注
ad9833.h#ifndef _AD9833_H_#define _AD9833_H_/******************************************************************************//* Include Files *//******************************************************************************/#include "sys.h"#define AD9833_FSYNC PBout(12)//这个是NSS管脚/******************************************************************************//* AD9833 *//******************************************************************************//* 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_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)#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))/******************************************************************************//* Functions Prototypes *//******************************************************************************//* Initializes the SPI communication peripheral and resets the part. */unsigned char AD9833_Init(void);/* Sets the Reset bit of the AD9833. */void AD9833_Reset(void);/* Clears the Reset bit of the AD9833. */void AD9833_ClearReset(void);/* Writes the value to a register. */void AD9833_SetRegisterValue(unsigned short regValue);/* Writes to the frequency registers. */void AD9833_SetFrequency(unsigned short reg, float fout);/* Writes to the phase registers. */void AD9833_SetPhase(unsigned short reg, unsigned short val);/* Selects the Frequency,Phase and Waveform type. */void AD9833_Setup(unsigned short freq, unsigned short phase, unsigned short type);void AD9833_SetFrequencyQuick(float fout,unsigned short type);unsigned char AD9833_SPI_Write(unsigned char* data, unsigned char bytesNumber);#endif // _AD9833_H ad9833.c#define FCLK 30000000//设置晶振频率//#define RealFreDat 268435456.0/FCLK//总的公式为 Fout=(Fclk/2的28次方)*28位寄存器的值double RealFreDat = 268435456.0/FCLK;/********往ad9833写******************************/unsigned char AD9833_SPI_Write(unsigned char* data, unsigned char bytesNumber){unsigned char i =0,j = 0;unsigned char writeData[5]= {0,0, 0, 0, 0};AD9833_FSYNC =0;for(i = 0;i < bytesNumber;i ++){writeData[i] = data[i + 1];}for(i=0 ;i<bytesNumber ;i++) { //while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET); //检查指定的SPI标志位设置与否:发送缓存空标志位SPI2_ReadWriteByte(writeData[i]);}AD9833_FSYNC = 1;delay_us(5);return i;}void AD9833_SetRegisterValue(unsigned short regValue){unsigned char data[5] = {0x03, 0x00, 0x00};data[1] = (unsigned char)((regValue & 0xFF00) >> 8);data[2] = (unsigned char)((regValue & 0x00FF) >> 0); AD9833_SPI_Write(data,2);}void AD9833_SetFrequency(unsigned short reg, float fout){unsigned short freqHi = reg;unsigned short freqLo = reg;unsigned long val=RealFreDat*fout;//F寄存器的值freqHi |= (val & 0xFFFC000) >> 14 ;freqLo |= (val & 0x3FFF);AD9833_SetRegisterValue(AD9833_B28);AD9833_SetRegisterValue(freqLo);AD9833_SetRegisterValue(freqHi);}void AD9833_SetFrequencyQuick(float fout,unsigned short type){AD9833_SetFrequency(AD9833_REG_FREQ0, fout*1000);// 400 kHzAD9833_Setup(AD9833_FSEL0, AD9833_PSEL0, type);}unsigned char AD9833_Init(void){ SPI2_Init(); AD9833_SetRegisterValue(AD9833_REG_CMD | AD9833_RESET); return (1);}void AD9833_Setup(unsigned short freq, unsigned short phase, unsigned short type){unsigned short val = 0;val = freq | phase | type;AD9833_SetRegisterValue(val);} main.cAD9833_Init();AD9833_SetFrequencyQuick(0,AD9833_OUT_SINUS );//输出频率 HZ 波形类型 /* SINUS TRIANGLE*/大体就介绍到这,有问题的朋友可以评论区留言,或者微信都可以,欢迎交流。