主要程序如下: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¿è«2¿Î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); //μÃμ½¼üÖμ
if(key)
{
switch(key)
{
case WKUP_PRES: //¿ØÖÆLED0,LED1»¥3aμãáá
led1sta=!led1sta;
led0sta=!led1sta;
break;
case KEY0_PRES: //¿aê¼2éÑù×a»»
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部分并没有执行,不知道原因是什么。
一周热门 更多>