其它文章链接,独家吐血整理
(实验3)单片机,STM32F4学习笔记,代码讲解【按键输入实验】【正点原子】【原创】
(实验4)单片机,STM32F4学习笔记,代码讲解【串口实验】【正点原子】【原创】
(实验5)单片机,STM32F4学习笔记,代码讲解【外部中断实验】【正点原子】【原创】
(实验6,实验7)单片机,STM32F4学习笔记,代码讲解【看门狗实验】【正点原子】【原创】
(实验8)单片机,STM32F4学习笔记,代码讲解【定时器实验】【正点原子】【原创】
(实验9)单片机,STM32F4学习笔记,代码讲解【PWM输出实验】【正点原子】【原创】
(实验10)单片机,STM32F4学习笔记,代码讲解【输入捕获实验】【正点原子】【原创】
(实验11)单片机,STM32F4学习笔记,代码讲解【电容触摸按键实验】【正点原子】【原创】
(实验12)单片机,STM32F4学习笔记,代码讲解【OLED显示实验】【正点原子】【原创】
(实验13)单片机,STM32F4学习笔记,代码讲解【TFTLCD彩屏显示实验】【正点原子】【原创】
(实验15)单片机,STM32F4学习笔记,代码讲解【RTC实时时钟实验】【正点原子】【原创】
(实验17)单片机,STM32F4学习笔记,代码讲解【待机唤醒实验】【正点原子】【原创】
(实验23)单片机,STM32F4学习笔记,代码讲解【DMA实验】【正点原子】【原创】
(实验25)单片机,STM32F4学习笔记,代码讲解【SPI实验】【正点原子】【原创】
(实验34)单片机,STM32F4学习笔记,代码讲解【FLASH模拟EEPROM实验】【正点原子】【原创】
(实验36)单片机,STM32F4学习笔记,代码讲解【外部SRAM实验】【正点原子】【原创】
(实验37)单片机,STM32F4学习笔记,代码讲解【内存管理实验】【正点原子】【原创】
(实验38)单片机,STM32F4学习笔记,代码讲解【SD卡实验】【正点原子】【原创】
(实验39)单片机,STM32F4学习笔记,代码讲解【FATFS实验】【正点原子】【原创】
(实验46)单片机,STM32F4学习笔记,代码讲解【FPU测试实验】【正点原子】【原创】
(实验47)单片机,STM32F4学习笔记,代码讲解【DSP-FFT测试实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验-RTC时钟实验】【正点原子】【原创】
(实验55)单片机,STM32F4学习笔记,代码讲解【网络通信实验】【正点原子】【原创】
实验现象
本实验测试STM32F4的DSP 库的FFT函数,程序运行后,自动生成1024点测试序列,然后,每当KEY0按下后,调用DSP库的FFT算法(基4法)执行FFT运算,在LCD屏幕上面显示运算时间,同时将FFT结果输出到串口,DS0用于提示程序正在运行。
主程序
#define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组
float fft_outputbuf[FFT_LENGTH]; //FFT输出数组
u8 timeout;//定时器溢出次数
int main(void)
{
arm_cfft_radix4_instance_f32 scfft;
u8 key,t=0;
float time;
u8 buf[50];
u16 i;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
KEY_Init(); //初始化按键
LCD_Init(); //初始化LCD
TIM3_Int_Init(65535,84-1); //1Mhz计数频率,最大计时65ms左右超出
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
LCD_ShowString(30,70,200,16,16,"DSP FFT TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2014/7/2");
LCD_ShowString(30,130,200,16,16,"KEY0:Run FFT");//显示提示信息
LCD_ShowString(30,160,200,16,16,"FFT runtime:");//显示FFT执行时间
POINT_COLOR=BLUE; //设置字体为蓝色
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数
while(1)
{
key=KEY_Scan(0);
if(key==KEY0_PRES)
{
for(i=0;i<FFT_LENGTH;i++)//生成信号序列
{
fft_inputbuf[2*i]=100+
10*arm_sin_f32(2*PI*i/FFT_LENGTH)+
30*arm_sin_f32(2*PI*i*4/FFT_LENGTH)+
50*arm_cos_f32(2*PI*i*8/FFT_LENGTH); //生成输入信号实部
fft_inputbuf[2*i+1]=0;//虚部全部为0
}
TIM_SetCounter(TIM3,0);//重设TIM3定时器的计数器值
timeout=0;
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4)
time=TIM_GetCounter(TIM3)+(u32)timeout*65536; //计算所用时间
sprintf((char*)buf,"%0.3fms\r\n",time/1000);
LCD_ShowString(30+12*8,160,100,16,16,buf); //显示运行时间
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值
printf("\r\n%d point FFT runtime:%0.3fms\r\n",FFT_LENGTH,time/1000);
printf("FFT Result:\r\n");
for(i=0;i<FFT_LENGTH;i++)
{
printf("fft_outputbuf[%d]:%f\r\n",i,fft_outputbuf[i]);
}
}else delay_ms(10);
t++;
if((t%10)==0)LED0=!LED0;
}
}
FFT初始化程序
直接调用即可,故略
代码讲解
//FFT=fast fourier transform=快速傅里叶变换=将一个正弦信号转化为N个不同幅值不同频率的正弦信号叠加
//其实,FFT,网上有一堆文章来解释它,我以前也有总结过,比如知乎那一篇很有名的,献给“大连海事大学”
//总的来说就是,光由七中颜色组成(非肉眼可见光不知道还有没有),所以说一个正弦信号可不可以也拆分呢
//答案是一定的,通过FFT,可以得到第一行话那种意思,不过这是纯数学描述,计算机=单片机只认识数字0和1
//数学上来说,FFT将周期信号(即使是非周期,假设周期无限大那么看起来也是周期函数,所以也可以用FFT)
//时域中是信号,FFT之后变成频域中,其实还有复数域,来回倒腾
//数学上来说,一个信号=基波(直流分量)+奇次谐波(交流分量)+偶次谐波(幅值为0不算)(这一块不对待补充)
//上面说了,数学中是公示,但是计算机只认识数字,所以先利用“香农”采样定理,使用ADC采好点
//再用FFT对采样点进行处理,开发指南中说得很详细,也很浅显易懂,我这里小小总结一下
//采样N个点,N=2的整数次方(常用基2),N=(基4)4的整数次方(速度快)
//原始正弦信号幅值=A(此程序为100),采样频率=F
//FFT之后产生N个点=复数=实部+虚部,复数幅值=平方和再开根号=A*(N变/2)(除了第一个点=直流分量幅值=AN常)
//N个复数点频率=F(N变-1)/N常,频率分辨率=F/N常,所以N变=1时就是直流分量(频率=0)
//float fft_inputbuf[FFT_LENGTH2]; //FFT输入数组
//float fft_outputbuf[FFT_LENGTH]; //FFT输出数组
//输入数组必须2,因为它存储FFT之后的数据(实部和虚部数据),输出数组应该就是存储实部和虚部取模的值
//#define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
//16,64,256,1024,4096可供选择,此程序选择1024