使用STM32 DAC DMA和AD9850构建的高性能波形发生器

基于STM32+DAC+DMA和AD9850的波形发生器

试验目的

一、通过STM32单片机DAC+DMA产生频率可调正弦波、三角波、锯齿波、方波。
二、使用STM32驱动AD9850波形发生模块产生正弦波和方波。

一、AD9850/AD9851的简介
AD9850/AD9851 模块是采用 ADI 应用最广泛的 DDS(AD9850 和 AD9851)制作的模块。
AD9850模块接线图
主要功能特点:
模块能够输出正弦波和方波,2 个正弦波和 2 个方波输出。
 AD9850: 0-40MHz
 AD9851: 0-70MHz
 频率在 20-30MHz 后谐波越来越大,波形会越来越不干净。
 方波: 0-1MHz
采用 70MHz 的低通滤波器,使波形的 SN 比更好
比较器的基准输入端电压由可变电阻产生,调节该电阻可以得到不同的占空比方波
AD9850 模块采用 125MHz 的有源晶振,AD9851 模块采用 30MHZ 的有源晶振
AD9850模块原理图
二、AD9850驱动程序
1、模块初始化

/********************************************
函数名称:Init_AD9834(主要是初始化GPIO)
功    能:初始化AD9834
参    数:无
返回值  :无
*********************************************/
void Init_AD9850(void)
{
#ifdef MODE_SEIAL   //串行模式
    GPIO_InitTypeDef GPIO_InitStructure ;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
    GPIO_InitStructure.GPIO_Pin = AD9850_WCLK | AD9850_FQUD | AD9850_RST | AD9850_DATA ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(AD9850_CONTROL_PORT ,&GPIO_InitStructure) ;
    
    AD9850_Reset_Sreial() ;
#endif
    
#ifdef MODE_PARALLEL //并行模式
	
    GPIO_InitTypeDef GPIO_InitStructure ;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO , ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);//?
    GPIO_InitStructure.GPIO_Pin = AD9850_WCLK | AD9850_FQUD | AD9850_RST ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    GPIO_Init(AD9850_CONTROL_PORT ,&GPIO_InitStructure) ;
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All ;//可以
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(AD9850_DATA_PORT ,&GPIO_InitStructure);
    
    AD9850_Reset_Parallel() ;//并行模式下复位AD9850
#endif
    
}
/********************************************
函数名称:AD9850_Reset_Sreial
功    能:在串行模式下复位AD9850
参    数:无
返回值  :无
*********************************************/
void AD9850_Reset_Sreial(void)
{
    AD9850_WCLK_CLR ;
    AD9850_FQUD_CLR ;
    //RST信号
    AD9850_RST_CLR ;
    AD9850_RST_SET ;
//    AD9850_Delay(0xFFFF) ;
	delay_ms(3);
    AD9850_RST_CLR ;
    //WCLK信号
    AD9850_WCLK_CLR ;
    AD9850_WCLK_SET ;
//    AD9850_Delay(0xFFFF) ;
	delay_ms(3);
    AD9850_WCLK_CLR ;
    //FQUD信号
    AD9850_FQUD_CLR ;
    AD9850_FQUD_SET ;
//    AD9850_Delay(0xFFFF) ;
	delay_ms(3);
    AD9850_FQUD_CLR ;
}

2、串行模式数据写入

/********************************************
函数名称:AD9850_Write_Serial
功    能:在串行模式下写AD9850寄存器
参    数:W0 - W0寄存器的值
          freq - 频率值
返回值  :无
*********************************************/
void AD9850_Write_Serial(unsigned char W0,unsigned long freq)
{
    unsigned char i,wdata ;
     unsigned long  y ;
	y=4294967296.0/125;
	y*=(((float)freq)/1000000);
	    
    wdata = y>>0 ;   //写w4
    for(i=0 ;i<8 ;i++)
    {
        if(wdata & 0x01)
          AD9850_DATA_Write_1 ;
        else
          AD9850_DATA_Write_0 ;
        AD9850_WCLK_SET ;
        wdata >>= 1 ;
        AD9850_WCLK_CLR ;
    }
    wdata = y>>8 ;  //写w3
     for(i=0 ;i<8 ;i++)
    {
        if(wdata & 0x01)
          AD9850_DATA_Write_1 ;
        else
          AD9850_DATA_Write_0 ;
        AD9850_WCLK_SET ;
        wdata >>= 1 ;
        AD9850_WCLK_CLR ;
    }
    wdata = y>>16 ;  //写w2
     for(i=0 ;i<8 ;i++)
    {
        if(wdata & 0x01)
          AD9850_DATA_Write_1 ;
        else
          AD9850_DATA_Write_0 ;
        AD9850_WCLK_SET ;
        wdata >>= 1 ;
        AD9850_WCLK_CLR ;
    }
    wdata = y>>24 ;  //写w1
     for(i=0 ;i<8 ;i++)
    {
        if(wdata & 0x01)
          AD9850_DATA_Write_1 ;
        else
          AD9850_DATA_Write_0 ;
        AD9850_WCLK_SET ;
        wdata >>= 1 ;
        AD9850_WCLK_CLR ;
    }
    wdata = W0 ;  //写w0
     for(i=0 ;i<8 ;i++)
    {
        if(wdata & 0x01)
          AD9850_DATA_Write_1 ;
        else
          AD9850_DATA_Write_0 ;
        AD9850_WCLK_SET ;
        wdata >>= 1 ;
        AD9850_WCLK_CLR ;
    }
    
    AD9850_FQUD_SET ;  //移入使能
//    AD9850_Delay(0xFFFF) ;
    AD9850_FQUD_CLR ;
}

三、基于STM32+DAC+DMA 的波形发生器
1、DAC DMA 初始化

void Wave_Init(u16 Wave1_Fre,float Um_H,float Um_l)
{
	u32 Freq;
	Freq=(u32)(72000000/sizeof(SineWave_Value)*2/Wave1_Fre);//计算频率
	
//	SquareWave_Data(256,SineWave_Value,Um_H,Um_l);//产生方波
//	SineWave_Data(256,SineWave_Value,Um_H);//产生正弦波
	TriangleWave_Data(256,SineWave_Value,Um_H);//产生三角波
//	SawTooth_Data(256,SineWave_Value,Um_H);//产生锯齿波
	
	SineWave_GPIO_Config();             //初始化io
	SineWave_TIM_Config(Freq);          //初始化定时器
	SineWave_DAC_Config();              //配置DAC
	SineWave_DMA_Config();              //配置DMA
	TIM_Cmd(TIM2, ENABLE); 
}

2、生成波形数据表

/********生成正弦波输出表***********/
//cycle	:波形表的位数	(0~256)
//Um		:输出电压的峰值(0~1.5)
/*******************************/
void SineWave_Data( u16 cycle ,u16 *D,float Um)
{
    u16 i;
    for( i=0;i<cycle;i++)
    {
        D[i]=(u16)((Um*sin(( 1.0*i/(cycle-1))*2*PI)+Um)*4095/3.3);
    }
}
/********生成方波输出表***********/
//cycle	:波形表的位数	(0~256)
//Um		:输出电压
/*******************************/
void SquareWave_Data( u16 cycle ,u16 *D,float Um_H,float Um_L)
{
	u16 i;
	float daH=0,daL=0;
	daH=4095*Um_H/3.3f;
	daL=4095*Um_L/3.3f;
	for(i=0;i<256/2;i++)
	{
		D[i]= (u16)(daL);
	}
	for( i=256/2;i<256;i++)
	{
		D[i]=(u16)(daH);
	}
}
/********生成三角波输出表***********/
//cycle	:波形表的位数	(0~256)
//Um		:输出电压的峰值(0~1.5)
/*******************************/
void TriangleWave_Data( u16 cycle ,u16 *D,float Um)
{
    u16 i;
	int n=1;
	for( i=0;i<cycle;i++)
	{
		if(i<cycle/2)
		{
			D[i]= (u16)(1.0*i/255*4095);
		}
		else
		{
			D[i]= (u16)(1.0*(i-2*n)/255*4095);
			n++;
		}
		
	}
}
/********生成锯齿波形输出表***********/
//cycle	:波形表的位数	(0~256)
//Um		:输出电压
/*******************************/
void SawTooth_Data( u16 cycle ,u16 *D,float Um)
{
    u16 i;
	for( i=0;i<cycle;i++)
	{		
			D[i]= (u16)(1.0*i/255*4095);
		
	}
}

3、主函数

int main(void)
{  
	uint32_t FREQ=10000;
	u8 p[250];
	delay_init();	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	uart_init(115200);
	Init_AD9850();
	LED_Init();
	LCD_Init();
	LCD_Clear(BLACK);
	BACK_COLOR = BLACK;
	POINT_COLOR = WHITE;
	LCD_ShowString(50,40,200,24,24,(u8*)"AD9850 TEST");

	AD9850_Write_Serial(0x00,FREQ);
	
	sprintf((char*)p,"Freq : %d KHz",FREQ/1000);
	if(FREQ>=1000000) sprintf((char*)p,"Freq : %d MHz",FREQ/1000000);
	LCD_ShowString(30,100,200,24,24,p);
	
	Wave_Init(SquareFreq,SquareV_H,SquareV_L);	
	
	while(1)
	{	
		LED0=!LED0;					 
		delay_ms(250);
	}
}

四、调试波形




物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32 DAC DMA和AD9850构建的高性能波形发生器

发表评论