求助ADC+DMA+FFT

2019-07-20 02:16发布

主要程序如下:adc.c中的程序:

#include "adc.h"
#include "delay.h"
ADC_HandleTypeDef ADC1_Handler;
void MY_ADC_Init(void)
{
    ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4;   //4分频,adc时钟为27MHz
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B;           
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT;            
    ADC1_Handler.Init.ScanConvMode=DISABLE;                     
    ADC1_Handler.Init.EOCSelection=DISABLE;                     
    ADC1_Handler.Init.ContinuousConvMode=ENABLE;            
    ADC1_Handler.Init.NbrOfConversion=1;                        
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE;            
    ADC1_Handler.Init.NbrOfDiscConversion=0;                    
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START;      
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;
    ADC1_Handler.Init.DMAContinuousRequests=ENABLE;            //使用DMA传输数据
    HAL_ADC_Init(&ADC1_Handler);                                 
}

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC1_CLK_ENABLE();         
    __HAL_RCC_GPIOA_CLK_ENABLE();       
    GPIO_Initure.Pin=GPIO_PIN_5;            //PA5
    GPIO_Initure.Mode=GPIO_MODE_ANALOG;     
    GPIO_Initure.Pull=GPIO_NOPULL;         
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}

dma.c中的函数:
#include "dma.h"
#include "adc.h"
DMA_HandleTypeDef  ADC1DMA_Handler;      
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,u32 chx)
{
   __HAL_RCC_DMA2_CLK_ENABLE();
    __HAL_DMA_SET_COUNTER(&ADC1DMA_Handler,1024);
    __HAL_LINKDMA(&ADC1_Handler,DMA_Handle,ADC1DMA_Handler);    //连接dma和adc
    ADC1DMA_Handler.Instance=DMA_Streamx;                        
    ADC1DMA_Handler.Init.Channel=chx;                              
    ADC1DMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器       
    ADC1DMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;               
    ADC1DMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     
    ADC1DMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;   
    ADC1DMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;     
    ADC1DMA_Handler.Init.Mode=DMA_NORMAL;                           
    ADC1DMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               
    ADC1DMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
    ADC1DMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
    ADC1DMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;               
    ADC1DMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;            
    HAL_DMA_DeInit(&ADC1DMA_Handler);   
    HAL_DMA_Init(&ADC1DMA_Handler);
}

main.c中的函数:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "tpad.h"
#include "key.h"
#include "sdram.h"
#include "malloc.h"
#include "lcd.h"
#include "adc.h"
#include "dma.h"
#include "includes.h"
#include "dsp.h"
#include "usmart.h"
#include "math.h"
#include "arm_math.h"
#include "adc.h"
#include "mpu.h"  
#define FFT_LENGTH                1024          //FFT1024点
#define AUDIO_DATA_LENGTH 1024;
u32  audio_data_buffer[1024];
float maxvalue;         //fft后得到的最大值
void MY_DSP(void)      //dsp中进行fft的函数
{
   float fft_inputbuf[FFT_LENGTH*2];
   float fft_outputbuf[FFT_LENGTH];       
   float fft_output[FFT_LENGTH];      
    arm_cfft_radix4_instance_f32 scfft;
    u32 fre;
        u32 F=56250;        //adc采样频率
        u16 i;
       
        float maxvalue;
        u32 index;
        Cache_Enable();            
    HAL_Init();                                     
    Stm32_Clock_Init(432,25,2,9);      //系统时钟216Mhz
    delay_init(216);               
    uart_init(115200);                       
    LED_Init();                    
    arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);         
    while(1)
        {
                for(i=0;i<FFT_LENGTH;i++)              //fft输入值
                        {
                                fft_inputbuf[2*i]=audio_data_buffer[i];  
                               
                                fft_inputbuf[2*i+1]=0;//Dé2&#191;è&#171;2&#191;&#206;a0
                        }
               
                        arm_cfft_radix4_f32(&scfft,fft_inputbuf);        //FFT变换
                       
                        arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);        //求出幅值

                        fft_output[0]=fft_outputbuf[0]/FFT_LENGTH;     //求出实际值
                        for(i=1;i<FFT_LENGTH;i++)
                        {
                                fft_output[i]=(fft_outputbuf[i]*2)/FFT_LENGTH;
                       
                        }
                       
                        arm_max_f32(fft_output,FFT_LENGTH,&maxvalue,&index);   //求出最大值
                                                                
                       
                        fre=(F*index)/FFT_LENGTH;    //求出最大值对应的频率
                       
                        for(i=0;i<FFT_LENGTH;i++)
                        {
                                printf("fft_output[%d]:%f ",i,fft_output[i]);
                        }
                        printf("maxvalue:%f ,index:%d ",maxvalue,index);
                       
                break;
}
return;

}

//采样函数
void audio_sample(u32 * audio_data_buffer)
{
       
        u16 j;
        u32 x;
        LED0(0);
        delay_ms(10);
        LED0(1);
    ADC_ChannelConfTypeDef  ADC1_ChanConf;
    ADC1_ChanConf.Channel=ADC_CHANNEL_5;                        
    ADC1_ChanConf.Rank=1;                                    
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_3CYCLES;      
    ADC1_ChanConf.Offset=0;                 
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf);      
    HAL_ADC_Start_DMA(&ADC1_Handler, audio_data_buffer, 1024);//开始进行采样
       
        while(1)
        {
               
                                               
                if(__HAL_DMA_GET_FLAG(&ADC1DMA_Handler,DMA_FLAG_TCIF0_4))//dma传输完成时
                {
                                       
                        __HAL_DMA_CLEAR_FLAG(&ADC1DMA_Handler,DMA_FLAG_TCIF0_4);
                        printf("translate done");
                       
                       
                        HAL_ADC_Stop_DMA(&ADC1_Handler);                         
                       
                        for(j=0;j<1024;j++)                 //输出dma传输到存储器中的值
                        {
                                x=audio_data_buffer[j];
                                printf("audio_data_buffer[%d]=%d ",j,x);
                        }
               
                        printf("data in audio_data_buffer");
                       
                        break;
                }
                delay_ms(50);
        }
               
       
}

//main
int main(void)
{
       
        u8 key;
        u8 led0sta=1,led1sta=1;       
    Cache_Enable();               
    HAL_Init();                                       
    Stm32_Clock_Init(432,25,2,9);  
    delay_init(216);           
        uart_init(115200);                        
    LED_Init();                     
    KEY_Init();                    
    LCD_Init();                    
    my_mem_init(SRAMIN);                   
        MY_ADC_Init();               
    MYDMA_Config(DMA2_Stream0,DMA_CHANNEL_0);
        LCD_ShowString(30,50,200,16,16,"Apollo STM32F4/F7");       
        LCD_ShowString(30,70,200,16,16,"ADC FFT TEST");               
        LCD_ShowString(30,130,200,16,16,"KEY0:Run ADC");
        while(1)
        {
                key=KEY_Scan(0);                     //μ&#195;μ&#189;&#188;ü&#214;μ
                   if(key)
                {                                                  
                        switch(key)
                        {                                 
                                case WKUP_PRES:        //&#191;&#216;&#214;&#198;LED0,LED1&#187;¥3aμ&#227;áá
                                        led1sta=!led1sta;
                                        led0sta=!led1sta;
                                        break;
                                case KEY0_PRES:        //&#191;aê&#188;2é&#209;ù×a&#187;&#187;
                                        audio_sample(&audio_data_buffer[0]);
                           MY_DSP();       
                                        break;                               
                        }
                        LED0(led0sta);               
                        LED1(led1sta);               
                }else delay_ms(10);
        }
}

这是主要的代码,需要完成的功能是:adc从PA5口采集1024个数据并进行转换,通过DMA传输到内存audio_data_buffer中,然后进行fft变换并求出其中最大值和对应频率,通过串口助手显示到屏幕上。可是运行不出来结果,希望大家帮我看看。我百度有说是因为cache同步的问题,不是很懂。我加了很多显示模块,好像MY_DSP部分并没有执行,不知道原因是什么。



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
2条回答
zhang313957217
1楼-- · 2019-07-20 06:07
 精彩回答 2  元偷偷看……
还望指教
2楼-- · 2019-07-20 11:31
我的QQ: 2430290933 ,正在做类似的DMA采集ADC的数据,有些东西比较一致,可以互相讨论一下,麻烦加一下我,谢谢。

一周热门 更多>