首页 > 编程知识 正文

stm32f103rct6单片机,stm32f103rct6

时间:2023-05-05 11:44:21 阅读:273059 作者:4932

基于STM32F103RCT6的AD9833驱动开发(代码可以免费发邮箱) AD9833手册分析


管脚定义:






手册就先讲到这里,不明白的欢迎评论区留言,另外我会把代码还有手册一并发送给感兴趣的朋友。

AD9833典型应用电路(亲测有效,可以直接拿走)


注意晶振是有源晶振。

软件部分 SPI驱动部分(建议用库函数版本调用STM32SPI功能,尽量不要IO模拟,测过时序之后你可能会明白,IO时序乱的yipi)

spi时序图:

SPI初始化 void SPI2_Init(void){GPIO_InitTypeDef GPIO_InitStructure; /*******************/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE ); RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE );GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);/*******这里很关键*************/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //SPI_NSS GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_12); GPIO_SetBits(GPIOB,GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//选择了串行时钟的稳态:时钟悬空高SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//数据捕获于第二个时钟沿SPI_InitStructure.SPI_NSS = SPI_NSS_Soft/*Hard Soft*/;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;//定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值计算的多项式SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器 SPI_Cmd(SPI2, ENABLE); //使能SPI外设//SPI2_ReadWriteByte(0xff);//启动传输 }

我用的是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读写功能 u8 SPI2_ReadWriteByte(u8 TxData){u8 retry=0; while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位{retry++;if(retry>200)return 0;} SPI_I2S_SendData(SPI2, TxData); //通过外设SPIx发送一个数据retry=0;while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)//检查指定的SPI标志位设置与否:接受缓存非空标志位{retry++;if(retry>200)return 0;} return SPI_I2S_ReceiveData(SPI2); //返回通过SPIx最近接收的数据 }

一定一定要用这个函数,小遍在这吃过亏,一定要一读一写,否则可能出现写不进去的情况。反正强调一点,不管用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*/

大体就介绍到这,有问题的朋友可以评论区留言,或者微信都可以,欢迎交流。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。