欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

双路低频信号发生分析仪(部分)

程序员文章站 2022-07-12 10:28:39
...

花两天时间做了一下,主要也是想了解一下DFT及FFT的使用,这里写个备忘录以防忘记。

本题要求是程控产生范围为1000hz到2000hz的正弦波矩形波三角波和锯齿波,且步进值为10hz,这里使用stm32的两路DAC来产生波形,大概想法为调用DMA,DAC来构建交互,用TIM来控制频率,从数据手册来看的话DAC上升时间暨相邻两个点的上升时间为1us,用示波器看也确实如此,其他不赘述

一,基础部分

void DAC_Channel1Init(void)
{
	DAC_InitTypeDef DAC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 

	DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO; 
	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; 
	DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
	DAC_Init(DAC_Channel_1, &DAC_InitStructure); 

	DAC_SetChannel1Data( DAC_Align_12b_R , 0 );
	DAC_Cmd( DAC_Channel_1 , ENABLE ); 
	DAC_DMACmd( DAC_Channel_1 , ENABLE ); 
}
/******************************************
DAC通道2使能
PA.5输出

*******************************************/
void DAC_Channel2Init(void)
{
      
    DAC_InitTypeDef DAC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE); 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 

	DAC_InitStructure.DAC_Trigger = DAC_Trigger_T4_TRGO; 
	DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; 
	DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;
	DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
	DAC_Init(DAC_Channel_2, &DAC_InitStructure); 
    DAC_SetChannel2Data( DAC_Align_12b_R , 0x00 );
	DAC_Cmd( DAC_Channel_2 , ENABLE ); 
	//DAC_DMACmd( DAC_Channel_2 , ENABLE ); 
}

再配置完DMA

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM4, ENABLE);

	TIM_TimeBaseStructure.TIM_Period = 0; 
	TIM_TimeBaseStructure.TIM_Prescaler = 0; 
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update); 

配置时钟,改变频率仅需通过改变重装载值即可

双路低频信号发生分析仪(部分)

正弦波产生

双路低频信号发生分析仪(部分)

矩形波产生

双路低频信号发生分析仪(部分)

锯齿波产生

/************************
锯齿波产生
vpp:  赋值

***************************/

void  Saw_wave(float vpp)
{
   u16 i=0;
	 u16 Temp=0;
	 float k=0.0;
	 Temp = (u16)( (vpp/3.3)*4096);
	//printf("%d\r\n",Temp);
	 k=Temp/1024.0;
	//printf("%f\r\n",k);
  for(i=0;i<1023;i++)
	{
	   DAC_outData[i]=k*i+80;
		//printf("%d\r\n",DAC_outData[i]);
	}
   DAC_outData[1023]=0;
}

接下来只需要初始化即可自动产生波形,步进值通过按键改变封装函数的值即可。

移相只需要在两个dac准备产生波形的时间之中延时你所需的相位时间即可双路低频信号发生分析仪(部分)

两路DAC所产生的相移波形

二  、 FFT变换

两路正弦信号使用加法电路进行叠加,这里使用官方dsp库进行分析

双路低频信号发生分析仪(部分)这里用的是DFT采集1024个点的方式,根据采样定律,需要大于最大频率两倍的采样频率才可以正确采样,因此这里调用定时器使用5KHz的频率采样。即每点4.8hz的速率采集

void GetPowerMag(void)
{
    signed short lX,lY;
    float X,Y,Mag;
    unsigned short i;
    for(i=0; i<NPT/2; i++)
    {
        lX  = (lBufOutArray[i] << 16) >> 16;
        lY  = (lBufOutArray[i] >> 16);
        X = NPT * ((float)lX) / 32768;
        Y = NPT * ((float)lY) / 32768;
        Mag = sqrt(X * X + Y * Y) / NPT;
        if(i == 0)
            lBufMagArray[i] = (unsigned long)(Mag * 32768);
        else
            lBufMagArray[i] = (unsigned long)(Mag * 65536);
    }
}

 

相关标签: 波形产生