一、开发环境
硬件:STM32F407 核心开发板
单片机:STM32F407ZGT6
Keil版本:5.24.2.0
STM32CubeMX版本:6.12.0
二、配置CubeMX
1. 选择时钟源
2. 配置时钟
3. 使能Debug功能:Serial Wire
4. HAL库时基选择:SysTick
5. GPIO配置:如图(只用到了PC0、PC1、PC2,其他的不用管)。
6. 配置工程参数:在Project标签页中,配置项目名称和位置,选择工具链MDK-ARM。
7. 生成代码:在Code Generator标签页中,配置工程外设文件与HAL库,勾选头文件.c和.h文件分开,然后点击Project > Generate Code生成代码。
三、代码实现与部署
1. 添加 AD9833.c 和 AD9833.h 文件
AD9833.c
/*************************************************************************************
Title : Analog Devices AD9833 DDS Wave Generator Library for STM32 Using HAL Libraries
Author: Bardia Alikhan Afshar <bardia.a.afshar@gmail.com>
Software: IAR Embedded Workbench for ARM
Hardware: Any STM32 device
*************************************************************************************/
#include "AD9833.h"
// ------------------- Variables ----------------
uint16_t FRQLW = 0; // MSB of Frequency Tuning Word
uint16_t FRQHW = 0; // LSB of Frequency Tuning Word
uint32_t phaseVal=0; // Phase Tuning Value
uint8_t WKNOWN=0; // Flag Variable
// -------------------------------- Functions --------------------------------
// ------------------------------------------------ Software SPI Function
void writeSPI(uint16_t word,AD9833_Typedef AD9833) {
for (uint8_t i = 0; i < 16 ; i++) {
if(word & 0x8000) HAL_GPIO_WritePin(AD9833.PORT,AD9833.DATA,GPIO_PIN_SET); //bit=1, Set High
else HAL_GPIO_WritePin(AD9833.PORT,AD9833.DATA,GPIO_PIN_RESET); //bit=0, Set Low
ASM_NOP();
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SCK,GPIO_PIN_RESET); //Data is valid on falling edge
ASM_NOP();
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SCK,GPIO_PIN_SET);
word = word<<1; //Shift left by 1 bit
}
HAL_GPIO_WritePin(AD9833.PORT,AD9833.DATA,GPIO_PIN_RESET); //Idle low
ASM_NOP();
}
// ------------------------------------------------ Sets Output Wave Type
void AD9833_SetWave(uint16_t Wave,AD9833_Typedef AD9833){
switch(Wave){
case 0:
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_RESET);
writeSPI(0x2000,AD9833); // Value for Sinusoidal Wave
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_SET);
WKNOWN=0;
break;
case 1:
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_RESET);
writeSPI(0x2028,AD9833); // Value for Square Wave
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_SET);
WKNOWN=1;
break;
case 2:
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_RESET);
writeSPI(0x2002,AD9833); // Value for Triangle Wave
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_SET);
WKNOWN=2;
break;
default:
break;
}
}
// ------------------------------------------------ Sets Wave Frequency & Phase (In Degree) In PHASE0 & FREQ0 Registers
void AD9833_SetWaveData(float Frequency,float Phase,AD9833_Typedef AD9833){
ASM_NOP();
// ---------- Tuning Word for Phase ( 0 - 360 Degree )
if(Phase<0)Phase=0; // Changing Phase Value to Positive
if(Phase>360)Phase=360; // Maximum value For Phase (In Degree)
phaseVal = ((int)(Phase*(4096/360)))|0XC000; // 4096/360 = 11.37 change per Degree for Register And using 0xC000 which is Phase 0 Register Address
// ---------- Tuning word for Frequency
long freq=0;
freq=(int)(((Frequency*pow(2,28))/FMCLK)+1); // Tuning Word
FRQHW=(int)((freq & 0xFFFC000) >> 14); // FREQ MSB
FRQLW=(int)(freq & 0x3FFF); // FREQ LSB
FRQLW |= 0x4000;
FRQHW |= 0x4000;
// ------------------------------------------------ Writing DATA
HAL_GPIO_WritePin(AD9833.PORT,AD9833.DATA,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SCK,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_RESET); //low = selected
ASM_NOP();
writeSPI(0x2100,AD9833); // enable 16bit words and set reset bit
writeSPI(FRQLW,AD9833);
writeSPI(FRQHW,AD9833);
writeSPI(phaseVal,AD9833);
writeSPI(0x2000,AD9833); // clear reset bit
ASM_NOP();
HAL_GPIO_WritePin(AD9833.PORT,AD9833.SS,GPIO_PIN_SET); //high = deselected
AD9833_SetWave(WKNOWN,AD9833);
ASM_NOP();
return;
}
AD9833.h
/*************************************************************************************
Title : Analog Devices AD9833 DDS Wave Generator Library for STM32 Using HAL Libraries
Author: Bardia Alikhan Afshar <bardia.a.afshar@gmail.com>
Software: IAR Embedded Workbench for ARM
Hardware: Any STM32 device
*************************************************************************************/
#ifndef _AD_9833_H
#define _AD_9833_H
#include <math.h>
#include "stm32f4xx_hal.h"
// ------------------------- Defines -------------------------
#define FMCLK 25000000 // Master Clock On AD9833
#define ASM_NOP() HAL_Delay(1) // Assembly NOPE (Little Delay)
typedef struct
{
GPIO_TypeDef * PORT;
uint16_t DATA;
uint16_t SCK;
uint16_t SS;
}AD9833_Typedef;
enum WaveType{SIN, SQR, TRI}; // Wave Selection Enum
// ------------------ Functions ---------------------
void AD9833_SetWave(uint16_t Wave,AD9833_Typedef AD9833); // Sets Output Wave Type
void AD9833_SetWaveData(float Frequency,float Phase,AD9833_Typedef AD9833); // Sets Wave Frequency & Phase
#endif
2. 添加 AD9833_Setup.c 和 AD9833_Setup.h 文件
AD9833_Setup.c
#include "AD9833_Setup.h"
void AD9833_Init(AD9833_Typedef AD9833)
{
// AD9833 Pin configuration
AD9833.PORT = GPIOC;
AD9833.DATA = GPIO_PIN_0;
AD9833.SCK = GPIO_PIN_1;
AD9833.SS = GPIO_PIN_2;
// Set all AD9833 pin to High
HAL_GPIO_WritePin(AD9833.PORT, AD9833.DATA, GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833.PORT, AD9833.SCK, GPIO_PIN_SET);
HAL_GPIO_WritePin(AD9833.PORT, AD9833.SS, GPIO_PIN_SET);
// Set default frequecy which is employeed by AD9833
AD9833_SetWave(SIN, AD9833); // Type Of Wave
AD9833_SetWaveData(11000, 2, AD9833); // Frequency & Phase Set
return;
}
AD9833_Setup.h
#ifndef __AD9833_Setup_H__
#define __AD9833_Setup_H__
#include "AD9833.h"
// Initialing AD9833
void AD9833_Init(AD9833_Typedef AD9833);
#endif
3. main.c增加代码:添加头文件 #include "AD9833.h" #include "AD9833_Setup.h",然后就可以调用函数输出波形啦。
#include "AD9833.h"
#include "AD9833_Setup.h"
/* USER CODE BEGIN 2 */
AD9833_Typedef AD9833_1;
AD9833_Init(AD9833_1);
/* USER CODE END 2 */
/* USER CODE BEGIN WHILE */
AD9833_SetWave(SIN, AD9833_1);
AD9833_SetWaveData(20000, 2, AD9833_1);
HAL_Delay(5000);
/* USER CODE END WHILE */