AD9912驱动程序及说明1.AD9912写操作指令规范说明MCU通过向AD9912指定寄存器写入相关指令字控制AD9912实现指定功能。写操作过程中,MCU首先向AD9912写入16位指令字。指令字的第一位(I15)指明AD9912是处于读状态还是写状态;指令字的14、13位指明写入AD9912的控制字的字节数(如图2),分别可选择一字节、两字节、三字节和流模式;指令字的后13位是向AD9912写目标寄存器的地址。图1,AD991216BIT指令字图2,I14、I13位写字节选择2.头文件及其说明(AD9912.h)#includestm32l1xx_conf.h//包含所有头文件包快类型变量定义#includestm32l1xx_it.h#includestdio.h#ifndef__AD9912_H#define__AD9912_H/*宏定义部分----------------------------------------------------------------------------------------------*///定义MCUPB1引脚实现AD9912的IO_UPDATE()#defineSet_IO_UPDATE()GPIO_SetBits(GPIOB,GPIO_Pin_1)//定义MCUPA15引脚拉高AD9912的CSB#defineSet_CSB_AD()GPIO_SetBits(GPIOA,GPIO_Pin_15)//拉低AD9912的CSB#defineClear_CSB_AD()GPIO_ResetBits(GPIOA,GPIO_Pin_15)//定义MCUPB6引脚实现AD9912的Power_down#defineAD9912_Power_down()GPIO_SetBits(GPIOB,GPIO_Pin_6)#defineAD9912_Power_up()GPIO_ResetBits(GPIOB,GPIO_Pin_6)//per1KHZ=2^48/1000000上位机发送的频率以KHZ为单位#definePer_KHz281474976.7//PER1DEGREE=2^14/36014_bitregister上位机发送的相位以(°)为单位#definePer_1Degree45.5//////////////////////////////////////////////////////////////////////////////////tousetheconfigurationwizard//UseConfigurationWizardinContextMenu//hDDSOutputFrequencyConfiguration//oFrequencyofDDS(KHz)0-400000:1staticuint32_tAD9912_fre=150000;//thefrequencyoftheDACoutputofeachchannel;UnitisMHz;///h//hDDSOutputPhaseConfiguration//oPhaseofDDS0-360:1staticuint32_tAD9912_pha=0;//thePhaseoftheDACoutputofeachchannel;///h//endofconfigurationsectionexternuint8_tdata_con[4][3];staticuint8_tAD9912_Freq[6]={0x00,0x00,0x00,0x00,0x00,0x00};staticuint8_tAD9912_Phase[2]={0x00,0x00};voidAD9912_IO_update(void);voidAD9912_UPDATE(void);voidAD9912_CLEAR_UPDATE(void);voidAD9912_RESET(void);voidAD9912_conf(void);voidAD9912_FTW_conf(void);voidAD9912_Freq_Convert(uint8_t*SPI_Buffer,uint32_tFout_D);voidAD9912_Phase_Convert(uint8_t*SPI_Buffer,uint32_tPhase_Offset_D);voidAD9912_SetFreq(uint32_tFREQ_BxCx);voidAD9912_SetPhase(uint32_tPHASE_BxCx);voidAD9912_SetFreq_byfile(void);voidAD9912_SetPhase_byfile(void);#endif3.源文件及其说明(AD9912.c)1)定义的变量、常量以及函数说明uint8_tdata_con[4][3];AD9912配置信息存储数组,用于存储AD9912初始配置信息uint8_tAD9912_Freq[6]={0x00,0x00,0x00,0x00,0x00,0x00};AD9912频率控制字(FTW)存储数组uint8_tAD9912_Phase[2]={0x00,0x00};AD9912相位控制字存储数组voidAD9912_IO_update(void);AD9912IO_update函数(硬件IO_update两者选一即可)用于更新部分寄存器信息voidAD9912_UPDATE(void);AD9912IO_update函数(软件实现,上文中定义了硬件IO_update两者选一即可)用于更新部分寄存器信息voidAD9912_CLEAR_UPDATE(void);清除IO_uopdate标志位voidAD9912_RESET(void);AD9912Reset函数voidAD9912_conf(void);AD9912初始化配置函数,初始化AD9912voidAD9912_FTW_conf(void);初始化AD9912频率控制字voidAD9912_Freq_Convert(uint8_t*SPI_Buffer,uint32_tFout_D);频率控制字转换程序,将上位机发送的控制频率转换为AD9912能读懂的格式voidAD9912_Phase_Convert(uint8_t*SPI_Buffer,uint32_tPhase_Offset_D);相位控制字转换程序,将上位机发送的控制相位转换为AD9912能读懂的格式voidAD9912_SetFreq(uint32_tFREQ_BxCx);设置AD9912输出频率voidAD9912_SetPhase(uint32_tPHASE_BxCx);设置AD9912输出相位voidAD9912_SetFreq_byfile(void);voidAD9912_SetPhase_byfile(void);这两个函数主要于前期测试使用2)程序清单#includestm32l1xx_conf.h#includestm32l1xx_it.h#includesys_config.h#includeAD9912.h#includestdio.h/*前两位为指令字,后两位为写入的数据。即为配置0x0000,0x0010,0x040B,0x040C寄存器写入0x18,0x50,0xF9,0x01控制字。其中0x18控制字写入0x0000寄存器,设置AD9912SPI通信为三线模式指令读写位顺序为MSB.其中0x50控制字写入0x0010寄存器,关闭CMOSdriver、PDHSTLdriver、PDSYSCLKPLL.其中0xF9控制字写入0x040B寄存器、0x01控制字写入0x040C寄存器控制AD9912DAC模块的输出电流.*/uint8_tdata_con[4][3]={0x00,0x00,0x18,0x00,0x10,0x50,0x04,0x0B,0xF9,0x04,0x0C,0x01};////////////////////////////////////////////////////////////////////////////////////////////////////////resetAD9912voidAD9912_RESET(void){Clear_CSB_AD();while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x24);//resetbitdelay_ms(10);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);//delay_ms(10);//GPIO_ResetBits(GPIOA,GPIO_Pin_15);//SPI2_NSS;configedbysoftware;//Write_Data(0x10);//Write_Data(0xff);Set_CSB_AD();}//////////////////////////////////////////////////////////////////////////////////////////////////////voidAD9912_UPDATE(void){//I/O_UPDATESOFTClear_CSB_AD();delay_ms(5);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x05);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x01);delay_ms(5);Set_CSB_AD();}//////////////////////////////////////////////////////////////////////////////////////////////////////voidAD9912_CLEAR_UPDATE(void){//clearthebitofupdateClear_CSB_AD();delay_ms(5);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1,0x00);while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);SPI_I2S_SendData(SPI1