標(biāo)題:
STM32F1DMA方式ADC采集雙聲道音頻FFT變換顯示頻譜 源程序
[打印本頁(yè)]
作者:
新洲羅遠(yuǎn)
時(shí)間:
2021-1-21 15:48
標(biāo)題:
STM32F1DMA方式ADC采集雙聲道音頻FFT變換顯示頻譜 源程序
STM32F103C8_DMA方式2路ADC采集雙聲道音頻FFT變換顯示頻譜
這是一個(gè)完整的項(xiàng)目,沒(méi)有加狗
關(guān)鍵點(diǎn)在于多路采集,F(xiàn)FT庫(kù)函數(shù)應(yīng)用,這個(gè)FFT函數(shù)用匯編優(yōu)化,速度比較快。
當(dāng)然,本系統(tǒng)速度瓶頸在畫點(diǎn)顯示。后期我采用直接寫顯存,就比較快了。
上段忙,這也是我對(duì)同道的一點(diǎn)小小的貢獻(xiàn)
51hei圖片20210121160005.jpg
(130.86 KB, 下載次數(shù): 83)
下載附件
2021-1-21 16:00 上傳
單片機(jī)源程序如下:
#include "stm32f10x.h"
#include "usart.h"
#include "adc.h"
#include "delay.h"
#include "Lcd_Driver.h"
#include "LCD_Config.h"
#include "stm32_dsp.h"
#include "math.h"
#define NPT 256 //FFT采樣點(diǎn)數(shù)
long lBUFMAG[NPT+NPT]; //存儲(chǔ)求模后的數(shù)據(jù)[NPT+NPT/2]
long lBUFOUT[NPT]; //FFT輸出序列NPT=256
long lBUFIN0[NPT]; //FFT輸入系列
long lBUFIN1[NPT]; //FFT輸入系列
void dsp_column0(void);
void dsp_column1(void);
void powerMag(long nfill);//計(jì)算頻點(diǎn)幅值
void dsp_column_1(void);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u16 dot);
extern __IO uint16_t ADC_ConvertedValue[NOFCHANEL];
// 局部變量,用于保存轉(zhuǎn)換計(jì)算后的電壓值
float ADC_ConvertedValueLocal[NOFCHANEL];
int main(void)
{
u16 i;
uart_init(115200);
ADCx_Init();
delay_init();
Lcd_Init();//初始化硬件SPI
Lcd_Clear(BLUE); //清屏函數(shù)
while(1)
{
ADC_SoftwareStartConvCmd(ADC_x, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
DMA_ClearFlag(DMA1_FLAG_TC1);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
ADC_ConvertedValueLocal[0] =(float) ADC_ConvertedValue[0]/4096*3.3;
ADC_ConvertedValueLocal[1] =(float) ADC_ConvertedValue[1]/4096*3.3;
printf("CH0 = %f V \r\n",ADC_ConvertedValueLocal[0]);
printf("CH1 = %f V \r\n",ADC_ConvertedValueLocal[1]);
for(i=0;i<NPT;i++)
{// 由于沒(méi)有采用外部觸發(fā),所以使用軟件觸發(fā)ADC轉(zhuǎn)換
ADC_SoftwareStartConvCmd(ADC_x, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
DMA_ClearFlag(DMA1_FLAG_TC1);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
lBUFIN0[i] =(float) ADC_ConvertedValue[0];
lBUFIN1[i] =(float) ADC_ConvertedValue[1];
}
cr4_fft_256_stm32(lBUFOUT,lBUFIN1,NPT);//調(diào)用STM32的DSP庫(kù)作FFT變換
powerMag(NPT);//計(jì)算頻點(diǎn)幅值
dsp_column1();//顯示x根柱條。
cr4_fft_256_stm32(lBUFOUT,lBUFIN0,NPT);//調(diào)用STM32的DSP庫(kù)作FFT變換
//(FFT輸出序列,輸入序列,NPT=256)
powerMag(NPT);//計(jì)算頻點(diǎn)幅值
dsp_column0();//顯示x根柱條。
}
}
//顯示各頻點(diǎn)的柱條
void dsp_column0(void)
{
u8 i,j=80;
for(i=1;i<161;i+=2)
{ OLED_Fill(i,0,i,128,0x0000); //填充區(qū)域的對(duì)角坐標(biāo)
OLED_Fill(i,0,i,lBUFMAG[j],RED); //填充區(qū)域的對(duì)角坐標(biāo)
j --;
}
}
//顯示各頻點(diǎn)的柱條
void dsp_column1(void)
{
u8 i,j=80;
for(i=0;i<160;i+=2)
{ OLED_Fill(i,0,i,128,0x0000); //填充區(qū)域的對(duì)角坐標(biāo)
OLED_Fill(i,0,i,lBUFMAG[j],GREEN); //填充區(qū)域的對(duì)角坐標(biāo)
j --;
}
}
//x1,y1,x2,y2 填充區(qū)域的對(duì)角坐標(biāo)
//確保x1<=x2;y1<=y2 0<=x1<=127 0<=y1<=63
//dot:0,清空;1,填充
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u16 dot) //可以快
{
u8 x,y;
for(x=x1;x<=x2;x++)
{
for(y=y1;y<=y2;y++) Gui_DrawPoint(x,y,dot);//畫一個(gè)點(diǎn)
}
}
////////////////////////////////////////////
//計(jì)算各頻點(diǎn)的模值
void powerMag(long nfill) //計(jì)算頻點(diǎn)幅值
{ int32_t lX,lY;
uint32_t i,j;
for (i=0; i < nfill; i++) //256
{
lX= (lBUFOUT[i]<<16)>>16; /* sine_cosine --> cos */
lY= (lBUFOUT[i] >> 16); /* sine_cosine --> sin */
{
float X= 64*((float)lX)/32768;
float Y = 64*((float)lY)/32768;
float Mag = sqrt(X*X+ Y*Y)/nfill; // 先平方和,再開(kāi)方sqrt
j= (long)(Mag*65536); //存儲(chǔ)求模后的數(shù)據(jù)
if(j>128) j=128;//避免顯示越界
lBUFMAG[i] =j;
}
}
}
復(fù)制代碼
所有程序51hei提供下載:
DMA2通道ADC_FFT.7z
(216.08 KB, 下載次數(shù): 169)
2021-1-21 16:46 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
楊雪飛
時(shí)間:
2021-1-21 19:09
雖然不懂stm32,還是強(qiáng)烈支持一下。
作者:
liesnake
時(shí)間:
2021-1-22 20:12
這個(gè)不錯(cuò)的,很好的東西。
作者:
wangsh
時(shí)間:
2021-1-27 23:06
thank you very much!!!!!!!!!
作者:
羅程峰8200
時(shí)間:
2021-1-28 08:14
加油,雖然我不會(huì)玩,看看也好
作者:
VB老哥
時(shí)間:
2021-1-28 20:36
謝謝提供思路
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1