STM32-FFT代码说明

合集下载

stm32F103-进行FFT算法教程

stm32F103-进行FFT算法教程
大家可以从网上搜索下载得到 STM32 的 DSP 库,这里提供一个下载的地址: %2fmcu%2fLists%2fcortex%5fmx%5fstm32%2fSTM32F10x%2 0DSP%20library%2c%20where%20is%20it 2.2 添加 DSP 库到自己的工程工程中 下载得到 STM32 的 DSP 库之后,就可以将其添加到自己的工程工程中了。 其中,inc 文件夹下的 stm32_dsp.h 和 table_fft.h 两个文件是必须添加的。 stm32_dsp.h 是 STM32 的 DSP 库的头文件。
12floatfx; 13for(i=0; i<NPT; i++) 14 { 15fx = 1500 * sin(PI2 * i * 350.0 / Fs) + 162700 * sin(PI2 * i * 8400.0 / Fs) + 174000 * sin(PI2 * i * 18725.0 / Fs); 18lBufInArray[i] = ((signed short)fx) << 16; 19 } 20 }
7*******************************************************************/ 8voidGetPowerMag() 9{ 10 signed shortlX,lY; 11floatX,Y,Mag; 12 unsigned shorti;
13for(i=0; i<NPT/2; i++)
为什么要这样做呢?是因为后面要调用 STM32 的 DSP 库函数,需要传入的 参数规定了必须是这样的数据格式。
下面是具体的实现代码:

STM32官方DSP的FFT库使用

STM32官方DSP的FFT库使用

STM32官方DSP的FFT库使用STMicroelectronics提供了用于STM32系列微控制器的官方DSP库,其中包括了快速傅里叶变换(FFT)的实现。

FFT是一种将时域信号转换为频域信号的算法,常用于音频处理、图像处理、通信系统等领域。

使用STM32官方DSP库中的FFT功能,需要以下几个步骤:2. 配置工程:在工程的编译选项中,确保已启用浮点运算支持。

这可以通过设置编译器选项“-u _printf_float”来实现。

3.初始化FFT配置:在使用FFT之前,需要初始化FFT的配置,包括长度、窗函数、比例缩放系数等。

例如,对于一个长度为N的FFT,可以使用arm_cfft_radix4_init_f32函数来初始化:```arm_cfft_radix4_instance_f32 S;arm_cfft_radix4_init_f32(&S, N, 0, 1);```4.执行FFT变换:在进行FFT变换之前,需要准备好输入缓冲区,并确保输出缓冲区具有足够的大小来存储FFT的结果。

例如,如果要对一个长度为N的实数序列进行FFT变换,可以使用arm_cfft_radix4_f32函数:```float32_t input[N];float32_t output[N*2];//将输入数据复制到输入缓冲区arm_cfft_radix4_f32(&S, input);//处理输出数据```注意,为了存储FFT结果中的实部和虚部,输出缓冲区的大小应为FFT长度的两倍(N*2)。

5.访问FFT结果:FFT变换的结果保存在输出缓冲区中。

对于每个频率分量,实部和虚部分别存储在相邻的位置上。

例如,要获取第n个频率分量的实部和虚部,可以使用以下代码:```float32_t re = output[2*n];float32_t im = output[2*n+1];```以上是使用STM32官方DSP库进行FFT的基本步骤。

stm32fft串口导出matlab

stm32fft串口导出matlab

stm32fft串口导出matlab摘要:1.简介- 介绍stm32fft 和matlab2.准备工具和库- 安装stm32cubeMX 和stm32fft 库- 安装matlab3.配置stm32fft 库- 使用stm32cubeMX 配置stm32fft 库- 生成代码并下载到STM32 微控制器4.编写matlab 脚本- 读取串口数据- 利用stm32fft 库进行FFT 变换- 绘制频谱图5.运行测试- 运行matlab 脚本- 观察并分析结果正文:1.简介STM32FFT 是一个针对STM32 微控制器的快速傅里叶变换(FFT)库,它可以在不使用DSP 的情况下进行高效的FFT 计算。

Matlab 是一种广泛使用的数学软件,可以进行各种数学计算和数据可视化。

将STM32FFT 与Matlab 结合,可以实现高效的数据处理和分析。

2.准备工具和库首先,需要安装STM32CubeMX 工具,用于配置STM32 微控制器和生成初始化代码。

同时,需要安装stm32fft 库。

另外,还需要安装Matlab 软件。

3.配置stm32fft 库使用STM32CubeMX 配置stm32fft 库,选择合适的微控制器型号,并将相关参数配置好。

然后,生成代码并下载到STM32 微控制器。

4.编写matlab 脚本编写matlab 脚本,首先需要读取串口数据。

通过调用stm32cubeMX 生成的库函数,可以实现串口数据的接收。

接下来,利用stm32fft 库进行FFT 变换。

将变换后的数据保存下来,然后绘制频谱图。

频谱图可以帮助我们更好地观察和分析数据。

5.运行测试运行matlab 脚本,观察并分析结果。

如果结果与预期相符,说明整个系统工作正常。

如果不符,需要检查各个环节是否存在问题。

通过以上步骤,可以完成stm32fft 串口数据导出到matlab 的工作。

stm32fft算最高频率代码

stm32fft算最高频率代码

stm32fft算最高频率代码【原创版】目录1.STM32 FFT 简介2.STM32 FFT 的最高频率3.实现 STM32 FFT 最高频率的代码示例正文1.STM32 FFT 简介STM32 FFT 是一款基于 ARM Cortex-M 内核的微控制器,广泛应用于各种嵌入式系统中,如音频处理、图像处理等。

FFT(快速傅里叶变换)是一种高效的算法,用于将信号从时域转换到频域。

STM32 FFT 算最高频率代码是指在 STM32 平台上实现 FFT 算法,并达到其最高频率。

2.STM32 FFT 的最高频率STM32 FFT 的最高频率受限于其硬件性能和软件算法。

一般来说,STM32 FFT 的最高频率可达到数 MHz,甚至更高。

具体的最高频率取决于处理器的型号、主频、内存容量以及 FFT 算法的实现。

3.实现 STM32 FFT 最高频率的代码示例为了实现 STM32 FFT 的最高频率,需要对硬件和软件进行优化。

以下是一个简单的代码示例,展示了如何在 STM32 上实现 FFT 算法:```c#include "stm32f1xx_hal.h"void FFT(complex_t *in, complex_t *out, uint32_t n){// 1.初始化输入和输出数组// 2.按位反转置换输入数组// 3.计算子序列的 FFT// 4.合并子序列的 FFT 结果// 5.输出结果}int main(void){// 1.初始化 STM32 硬件// 2.配置 FFT 算法相关参数// 3.调用 FFT 函数// 4.执行其他任务return 0;}```需要注意的是,上述代码示例只是一个简化的版本,实际应用中需要根据具体需求进行修改和优化。

此外,为了达到最高频率,还需对代码进行进一步优化,如使用查表法、蝶形算法等。

总之,通过在 STM32 平台上实现 FFT 算法,并结合硬件和软件的优化,可以实现 STM32 FFT 的最高频率。

stm32 傅里叶谐波计算

stm32 傅里叶谐波计算

stm32 傅里叶谐波计算一、傅里叶变换简介傅里叶变换是一种将信号从时域转换到频域的数学方法。

它可以将复杂的信号分解成一系列简单的正弦和余弦函数,即谐波。

这种方法在许多领域都有广泛的应用,如信号处理、图像处理等。

二、STM32硬件介绍STM32是意法半导体(STMicroelectronics)公司推出的一款基于ARM Cortex-M内核的微控制器。

它具有高性能、低功耗、多功能等特点,广泛应用于各种嵌入式系统和物联网领域。

三、傅里叶谐波计算原理傅里叶谐波计算是基于傅里叶变换的理论,通过将信号分解成无数个正弦波和余弦波,从而得到信号的频谱。

在每个频率成分上,可以根据幅度和相位信息还原原始信号。

四、STM32实现傅里叶谐波计算的方法在STM32上实现傅里叶谐波计算,可以采用FFT(快速傅里叶变换)算法。

FFT是一种高效计算离散傅里叶变换(DFT)的算法,时间复杂度为O(n log n),相较于直接计算DFT的O(n^2)时间复杂度,具有更高的计算效率。

STM32可以通过编程实现FFT算法,或者使用现有的库(如OpenMP、KissFFT等)来进行傅里叶谐波计算。

在实际应用中,首先需要对输入信号进行采样和窗函数处理,以减少频谱泄漏和旁瓣干扰。

接下来,按照FFT算法进行计算,得到信号的频谱。

最后,根据频谱信息进行谐波分析,提取有用信号。

五、应用场景及优势傅里叶谐波计算在许多领域都有广泛的应用,如电力系统中的谐波分析、音频信号处理、图像处理等。

通过STM32实现傅里叶谐波计算,可以充分发挥其高性能、低功耗的特点,满足实时性和精度要求。

六、总结本文介绍了傅里叶变换及其在STM32上的实现方法。

通过傅里叶谐波计算,可以有效地分析信号的频谱成分,为各种应用场景提供有用信息。

STM32-FFT代码说明

STM32-FFT代码说明

FFT 代码说明FFT 为Fast Fourier Transformation ,即快速傅里叶变换,本工程中,FFT 的目标是识别频率为形如式(1.1)的一个正弦信号:()sin(2)f x A ft π=•(1.1)其中,21Hz 5%f =±;因为单片机通过ADC 接口读取该正弦信号的电压值,而12位精度的ADC 的值范围在0-4096之间,如信号经过放大器后映射到之间,那么振幅A 的取值0-4096之间。

假设,信号经过放大器后,其电压值最大为,最小为0V ,那么此信号的振幅为,对应A=2048,即该信号为:()20482048sin(221)f x t π=+•⨯•(1.2)本文中给出的例程即通过FFT 识别式(1.2)这种正弦信号。

假设采样频率为Fs ,信号频率Fn ,采样点数为N 。

那么FFT 之后结果就是一个为N 点的复数。

每一个点就对应着一个频率点。

这个点的模值,就是该频率值下的幅度特性。

具体跟原始信号的幅度有什么关系呢?假设原始信号的峰值为A ,那么FFT 的结果的每个点〔除了第一个点直流分量之外〕的模值就是A 的N/2倍。

而第一个点就是直流分量,它的模值就是直流分量的N 倍。

第一个点表示直流分量〔即0Hz 〕,而最后一个点N 的再下一个点〔实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后〕那么表示采样频率Fs ,这中间被N -1个点平均分成N 等份,每个点的频率依次增加。

例如某点n 所表示的频率为:()1*/Fn n Fs N =-(1.3)频率分辨率〔/f Fs N ∆=〕等于采样时间的倒数。

例如要分辨,那么需要采集10s 。

1 基于STM32官方DSP 库的FFT 算法工程文件中包含三个函数库,分别为:分别对应数据点数为64,256和1024时的FFT算法。

下面将以数据点数是1024为例,说明FFT的实现过程。

1.1通过函数生成原始数据for(i=0;i<NPT;i++){Fx=2048+2048*sin(PI2*i*21/Fs+20)+1000*sin(PI2*i*15/Fs)+100*sin(PI2*i*25/Fs) +rand()%100;//振幅2048,频率21HZ,为主要的谐波分量,21HZ也是所需信号的频率,rand()%100为0-100之间的随机噪声lBUFIN[i] = ((s16)fx)<<16;//高位为实部,低位为虚部}Fs为采样频率,此处设为Hz,NPT为数据长度〔即前文中提到的N〕,为了能够分辨,数据长度NPT设为1024,那么频率分辨率=102.4/1024=Hz。

stm32fft功能指标实现方法

stm32fft功能指标实现方法

stm32fft功能指标实现方法【原创版2篇】目录(篇1)1.STM32 FFT 功能简介2.FFT 实现方法3.FFT 功能指标4.总结正文(篇1)【1.STM32 FFT 功能简介】STM32 是一种基于 ARM Cortex-M 内核的微控制器,广泛应用于各种嵌入式系统中。

其中,STM32 的 FFT(快速傅里叶变换)功能被广泛应用于信号处理、图像处理等领域。

FFT 是一种将时间域信号转换为频域信号的算法,可以有效地降低信号的复杂度,便于分析和处理。

【2.FFT 实现方法】STM32 中实现 FFT 的方法主要有两种:一种是基于 C 语言的库函数实现,另一种是基于 MATLAB 的 Simulink 模型实现。

基于 C 语言的库函数实现,需要开发者熟悉 ARM Cortex-M 的内部结构和指令集,编写底层的汇编代码。

这种方法的优点是运行速度快,缺点是需要开发者具备较高的技术水平。

基于 MATLAB 的 Simulink 模型实现,则需要开发者熟悉 MATLAB 和 Simulink 的使用方法,通过图形化的界面进行 FFT 的实现。

这种方法的优点是易于上手,缺点是运行速度相对较慢。

【3.FFT 功能指标】在 STM32 中实现 FFT 功能,需要考虑以下几个指标:首先是运算速度。

FFT 的运算量较大,因此需要尽可能提高运算速度。

这可以通过优化算法、提高处理器的时钟频率、减少数据传输的时间等手段来实现。

其次是精度。

FFT 的精度直接影响到信号处理的结果,因此需要保证FFT 的精度。

这可以通过选择合适的算法、提高数据精度、减少数据丢失等手段来实现。

最后是功耗。

在嵌入式系统中,功耗是一个重要的考虑因素。

可以通过选择低功耗的处理器、降低处理器的时钟频率、关闭不必要的功能等手段来降低功耗。

【4.总结】总的来说,STM32 的 FFT 功能是一种重要的信号处理手段,其实现方法有多种,需要根据具体的应用场景和需求进行选择。

基于STM32芯片的128点FFT

基于STM32芯片的128点FFT

Main函数/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** * File Name : main.c* Author : MCD Application Team* Version : V2.0.1* Date : 06/13/2008* Description : Main program body******************************************************************************* ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME.* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE* CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.******************************************************************************* //* Includes ------------------------------------------------------------------*/#include "stm32f10x_lib.h"#include "stdio.h"#include "math.h"#include "stm32_dsp.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*/#define ADC1_DR_Address ((u32)0x4001244C)#define USART1_DR_Base ((u32)0x40013804)#define LEN 128/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/ErrorStatus HSEStartUpStatus;/* Private function prototypes -----------------------------------------------*/void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void TIM_BaseConfiguration(void);void DMA_Configuration(void);void USART_Configuration(void);void ADC_Configuration(void);void ADC_ALL_Init(void);void FFT_Configuration(double *pr,double *pi,int n,int k,double*fr,double*fi,int l,int il);void FFT_solve(void);void Delay(u32 counter);/* Private functions ---------------------------------------------------------*/u16 data_buff[LEN];u16 px_buff[LEN];u16 pz_buff[LEN];double x[128];double pr[128];double pi[128];double fr[128];double fi[128];double mo[128];//int *px = (int*)0x1f00;//int *pz = (int*)0x1f80;int xm,zm,i,t = 0;u8 Flag = 0;/****************************************************************************** ** Function Name : main* Description : Main program* Input : None* Output : None* Return : None******************************************************************************* /int main(void){#ifdef DEBUGdebug();#endif/* System clocks configuration ---------------------------------------------*/RCC_Configuration();/* NVIC configuration ------------------------------------------------------*/NVIC_Configuration();/* GPIO configuration ------------------------------------------------------*/GPIO_Configuration();/* ADC1 configuration ------------------------------------------------------*/ADC_Configuration();/*USART Configuration--------------------------------------------------------*/USART_Configuration();ADC_ALL_Init();while (1){FFT_solve();}}/****************************************************************************** ** Function Name : RCC_Configuration* Description : Configures the different system clocks.* Input : None* Output : None* Return : None******************************************************************************* /void RCC_Configuration(void){/* RCC system reset(for debug purpose) */RCC_DeInit();/* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */HSEStartUpStatus = RCC_WaitForHSEStartUp();if(HSEStartUpStatus == SUCCESS){/* Enable Prefetch Buffer */FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Flash 2 wait state */FLASH_SetLatency(FLASH_Latency_2);/* HCLK = SYSCLK */RCC_HCLKConfig(RCC_SYSCLK_Div1);/* PCLK2 = HCLK */RCC_PCLK2Config(RCC_HCLK_Div1);/* PCLK1 = HCLK/2 */RCC_PCLK1Config(RCC_HCLK_Div2);/* ADCCLK = PCLK2/4 */RCC_ADCCLKConfig(RCC_PCLK2_Div4);/* PLLCLK = 8MHz * 7 = 56 MHz */RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}/* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while(RCC_GetSYSCLKSource() != 0x08){}}/* Enable peripheral clocks --------------------------------------------------*//* Enable DMA1 clock */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);/* Enable USART2 clock */RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);/*Enable TIM2 clock*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);/* Enable ADC1 and GPIOC clock */RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA, ENABLE);}/****************************************************************************** ** Function Name : GPIO_Configuration* Description : Configures the different GPIO ports.* Input : None* Output : None* Return : None******************************************************************************* /void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure;/* Configure PC.04 (ADC Channel14) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure PA.03 (ADC Channel14) as analog input -------------------------*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure USART1 Rx (PA.10) as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure USART1 Tx (PA.09) as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);}/****************************************************************************** ** Function Name : NVIC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None*******************************************************************************/void NVIC_Configuration(void){NVIC_InitTypeDef NVIC_InitStructure;#ifdef VECT_TAB_RAM/* Set the Vector Table base location at 0x20000000 */NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);#else /* VECT_TAB_FLASH *//* Set the Vector Table base location at 0x08000000 */NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);#endif/* Enable the TIM2 gloabal Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Enable the ADC1_EOC Interrupt */NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}/****************************************************************************** ** Function Name : TIM_BaseConfiguration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void TIM_BaseConfiguration(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* Time base configuration */TIM_TimeBaseStructure.TIM_Period = 65535;TIM_TimeBaseStructure.TIM_Prescaler = 0;TIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);/*Enable TIM2*/TIM_Cmd(TIM2,ENABLE);/* TIM IT enable */TIM_ITConfig(TIM2, TIM_IT_Update , ENABLE);}/****************************************************************************** ** Function Name : ADC_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void ADC_Configuration(void){ADC_InitTypeDef ADC_InitStructure;ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; /*工作在独立模式*/ADC_InitStructure.ADC_ScanConvMode = ENABLE; /*规定了模数转换工作在扫描模式(多通道)还是单次(单通道)模式*/ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; /*规定了模数转换工作在连续还是单次模式*/ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; /*转换由软件而不是外部触发启动*/ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; /*规定了ADC 数据向左边对齐还是向右边对齐*/ADC_InitStructure.ADC_NbrOfChannel = 1; /*规定了顺序进行规则转换的ADC通道的数目*/ADC_Init(ADC1, &ADC_InitStructure);}void ADC_ALL_Init(void){/* ADC1 regular channel14 configuration */ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_7Cycles5);/*设置指定ADC的规则组通道,设置它们的转化顺序和采样时间*//* Enable ADC1 EOC interrupts */ADC_ITConfig(ADC1, ADC_IT_EOC , ENABLE);/* Enable ADC1 */ADC_Cmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register */ADC_ResetCalibration(ADC1); /*重置指定的ADC的校准寄存器*//* Check the end of ADC1 reset calibration register */while(ADC_GetResetCalibrationStatus(ADC1));/*获取ADC重置校准寄存器的状态*//* Start ADC1 calibaration */ADC_StartCalibration(ADC1);/* Check the end of ADC1 calibration */while(ADC_GetCalibrationStatus(ADC1));/* Start ADC1 Software Conversion */ADC_SoftwareStartConvCmd(ADC1, ENABLE);/*使能指定的ADC的软件转换启动功能*/}/****************************************************************************** ** Function Name : USART_Configuration* Description : Configures Vector Table base location.* Input : None* Output : None* Return : None******************************************************************************* /void USART_Configuration(void){USART_InitTypeDef USART_InitStructure;USART_ART_BaudRate = 9600;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;/* Configure USART1 */USART_Init(USART1, &USART_InitStructure);/*Enable USART1 */USART_Cmd(USART1, ENABLE);}/******************************************************************************* Function Name : FFT_Configuration* Description :* Input : None* Output : None* Return : None******************************************************************************* /void FFT_Configuration(double *pr,double *pi,int n,int k,double*fr,double*fi,int l,int il)//int n,k,l,il; double pr[],pi[],fr[],fi[];/*pr(实部),pi(虚部),n(点数),k(阶数)*/{int it,m,is,i,j,nv,l0;double p,q,s,vr,vi,poddr,poddi;/*雷德(Rader)算法,实现数据的倒位序排列-----------*/for (it=0; it<=n-1; it++){m=it;is=0;for (i=0; i<=k-1; i++){j=m/2;is=2*is+(m-2*j);m=j;}fr[it]=pr[is];fi[it]=pi[is];}pr[0]=1.0;pi[0]=0.0;p=6.283185306/(1.0*n);pr[1]=cos(p);pi[1]=-sin(p);if (l!=0)pi[1]=-pi[1];for (i=2; i<=n-1; i++){p=pr[i-1]*pr[1];q=pi[i-1]*pi[1];s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);pr[i]=p-q;pi[i]=s-p-q;}for (it=0; it<=n-2; it=it+2){vr=fr[it];vi=fi[it];fr[it]=vr+fr[it+1];fi[it]=vi+fi[it+1];fr[it+1]=vr-fr[it+1];fi[it+1]=vi-fi[it+1];}m=n/2;nv=2;for (l0=k-2; l0>=0; l0--){m=m/2;nv=2*nv;for (it=0; it<=(m-1)*nv; it=it+nv)for (j=0; j<=(nv/2)-1; j++){p=pr[m*j]*fr[it+j+nv/2];q=pi[m*j]*fi[it+j+nv/2];s=pr[m*j]+pi[m*j];s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);poddr=p-q;poddi=s-p-q;fr[it+j+nv/2]=fr[it+j]-poddr;fi[it+j+nv/2]=fi[it+j]-poddi;fr[it+j]=fr[it+j]+poddr;fi[it+j]=fi[it+j]+poddi;}}if (l!=0)for (i=0; i<=n-1; i++){ fr[i]=fr[i]/(1.0*n);fi[i]=fi[i]/(1.0*n);}if (il!=0)for (i=0; i<=n-1; i++){pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);if (fabs(fr[i])<0.000001*fabs(fi[i])){if ((fi[i]*fr[i])>0) pi[i]=90.0;elsepi[i]=-90.0;}elsepi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;}}/****************************************************************************** ** Function Name : FFT_solve* Description :* Input : None* Output : None* Return : None******************************************************************************* /void FFT_solve(void){if(Flag){/*寄存器接收满后Flag = 1,关闭ADC中断,进行FFT运算--------*/ADC_Cmd(ADC1, DISABLE);//px = (int*)0x1f00;/*转换存储位置-------------*/for(i=0;i<128;i++){//*px=data_buff[i];//px++;px_buff[i] = data_buff[i];}//px = (int*)0x1f00;/*将ADC采来的数据转换为实际的幅度值--------------*/for (i=0; i<=128; i++){//xm=*px;xm = px_buff[i];x[i]=xm/32768.0;pr[i]=x[i];/*pr数组存放函数点的实部-------------*/pi[i]=0; /*pi数组存放函数点的虚部-------------*///px++;}/*进行FFT运算----------------------*/FFT_Configuration(pr,pi,128,7,fr,fi,0,1);//pz = (int*)0x1f80;/*将最终计算出的值放入pz 中----------------------*/for (i=0;i<=128;i++){mo[i] = sqrt(fr[i]*fr[i]+fi[i]*fi[i]);zm = (int)(mo[i]*1000.0);//*pz = zm;//pz++;pz_buff[i] = zm;}}Flag = 0;}/****************************************************************************** ** Function Name : Delay* Description :* Input : None* Output : None* Return : None******************************************************************************* /void Delay(u32 counter){for(;counter > 0;counter--);}#ifdef DEBUG/****************************************************************************** ** Function Name : assert_failed* Description : Reports the name of the source file and the source line number* where the assert_param error has occurred.* Input : - file: pointer to the source file name* - line: assert_param error line source number* Output : None* Return : None******************************************************************************* /void assert_failed(u8* file, u32 line){/* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* Infinite loop */while (1){}}#endif/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/stm32f10x_it.c/******************** (C) COPYRIGHT 2008 STMicroelectronics ******************** * File Name : stm32f10x_it.c* Author : MCD Application Team* Version : V2.0.1* Date : 06/13/2008* Description : Main Interrupt Service Routines.* This file provides template for all exceptions handler* and peripherals interrupt service routine.******************************************************************************* ** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONL Y AIMS A T PROVIDING CUSTOMERS* WITH CODING INFORMA TION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SA VE TIME.* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE* CONTENT OF SUCH FIRMW ARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.******************************************************************************* //* Includes ------------------------------------------------------------------*/#include "stm32f10x_it.h"#include "stdio.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*/#define ADC1_DR_Address ((u32)0x4001244C)#define LEN 128/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*/extern u16 data_buff[LEN];extern int t ;extern u8 Flag;u32 *P = (u32*)0x4001244C;/****************************************************************************** ** Function Name : NMIException* Description : This function handles NMI exception.* Input : None* Output : None* Return : None******************************************************************************* /void NMIException(void){}/****************************************************************************** ** Function Name : HardFaultException* Description : This function handles Hard Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void HardFaultException(void){/* Go to infinite loop when Hard Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : MemManageException* Description : This function handles Memory Manage exception.* Input : None* Output : None* Return : None******************************************************************************* /void MemManageException(void){/* Go to infinite loop when Memory Manage exception occurs */while (1){}}/****************************************************************************** ** Function Name : BusFaultException* Description : This function handles Bus Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void BusFaultException(void){/* Go to infinite loop when Bus Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : UsageFaultException* Description : This function handles Usage Fault exception.* Input : None* Output : None* Return : None******************************************************************************* /void UsageFaultException(void){/* Go to infinite loop when Usage Fault exception occurs */while (1){}}/****************************************************************************** ** Function Name : DebugMonitor* Description : This function handles Debug Monitor exception.* Input : None* Output : None* Return : None******************************************************************************* /void DebugMonitor(void){}/****************************************************************************** ** Function Name : SVCHandler* Description : This function handles SVCall exception.* Input : None* Output : None* Return : None******************************************************************************* /void SVCHandler(void){}/****************************************************************************** ** Function Name : PendSVC* Description : This function handles PendSVC exception.* Input : None* Output : None* Return : None******************************************************************************* /void PendSVC(void){}/****************************************************************************** ** Function Name : SysTickHandler* Description : This function handles SysTick Handler.* Input : None* Output : None* Return : None******************************************************************************* /void SysTickHandler(void){}/****************************************************************************** ** Function Name : WWDG_IRQHandler* Description : This function handles WWDG interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void WWDG_IRQHandler(void){}/****************************************************************************** ** Function Name : PVD_IRQHandler* Description : This function handles PVD interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void PVD_IRQHandler(void){}/****************************************************************************** ** Function Name : TAMPER_IRQHandler* Description : This function handles Tamper interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void TAMPER_IRQHandler(void){}/****************************************************************************** ** Function Name : RTC_IRQHandler* Description : This function handles RTC global interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void RTC_IRQHandler(void){}/****************************************************************************** ** Function Name : FLASH_IRQHandler* Description : This function handles Flash interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void FLASH_IRQHandler(void){}/****************************************************************************** ** Function Name : RCC_IRQHandler* Description : This function handles RCC interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void RCC_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI0_IRQHandler* Description : This function handles External interrupt Line 0 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI0_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI1_IRQHandler* Description : This function handles External interrupt Line 1 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI1_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI2_IRQHandler* Description : This function handles External interrupt Line 2 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI2_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI3_IRQHandler* Description : This function handles External interrupt Line 3 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI3_IRQHandler(void){}/****************************************************************************** ** Function Name : EXTI4_IRQHandler* Description : This function handles External interrupt Line 4 request.* Input : None* Output : None* Return : None******************************************************************************* /void EXTI4_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel1_IRQHandler* Description : This function handles DMA1 Channel 1 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel1_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel2_IRQHandler* Description : This function handles DMA1 Channel 2 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel2_IRQHandler(void){}/******************************************************************************** Function Name : DMA1_Channel3_IRQHandler* Description : This function handles DMA1 Channel 3 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel3_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel4_IRQHandler* Description : This function handles DMA1 Channel 4 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel4_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel5_IRQHandler* Description : This function handles DMA1 Channel 5 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel5_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel6_IRQHandler* Description : This function handles DMA1 Channel 6 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel6_IRQHandler(void){}/****************************************************************************** ** Function Name : DMA1_Channel7_IRQHandler* Description : This function handles DMA1 Channel 7 interrupt request.* Input : None* Output : None* Return : None******************************************************************************* /void DMA1_Channel7_IRQHandler(void){}/****************************************************************************** ** Function Name : ADC1_2_IRQHandler* Description : This function handles ADC1 and ADC2 global interrupts requests.* Input : None* Output : None* Return : None******************************************************************************* /void ADC1_2_IRQHandler(void){if(ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET){ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);//*P = ADC1_DR_Address;data_buff[t] = *P;t++;while(t == 128){Flag = 1;t = 0;}}}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
假设,信号经过放大器后,其电压值最大为3.3V,最小为0V,则此信号的振幅为1.65V,对应A=2048,即该信号为:
本文中给出的例程即通过FFT识别式 这种正弦信号。
假设采样频率为Fs,信号频率Fn,采样点数为N。那么FFT之后结果就是一个为N点的复数。每一个点就对应着一个频率点。这个点的模值,就是该频率值下的幅度特性。具体跟原始信号的幅度有什么关系呢?假设原始信号的峰值为A,那么FFT的结果的每个点(除了第一个点直流分量之外)的模值就是A的N/2倍。而第一个点就是直流分量,它的模值就是直流分量的N倍。
FFT代码说明
FFT为Fast Fourier Transformation,即快速傅里叶变换,本项目中,FFT的目标是识别频率为形如式的一个正弦信号:
其中, ;因为单片机通过ADC接口读取该正弦信号的电压值,而12位精度的ADC的值范围在0-4096之间,如信号经过放大器后映射到0-3.3V之间,则振幅A的取值0-4096之间。
结果如下图所示。
图1f=0hz处幅值
图2f=15Hz处幅值
图3f=21hz处幅值
图4f=25hz处幅值
2
另外程序中给出了非官方FFT计算方法,文件名为FFT2.c,相关的函数如下:
dsp_g2_init();//用于生成计算所需原始数据,
dsp_g2_test(); //非STM32库中的FFT算法
{
Fx=2048+2048*sin(PI2*i*21/Fs+20)+1000*sin(PI2*i*15/Fs)+100*sin(PI2*i*25/Fs)
+rand()%100;//振幅2048,频率21HZ,为主要的谐波分量,21HZ也是所需信号的频率,rand()%100为0-100之间的随机噪声
lBUFIN[i] = ((s16)fx)<<16;//高位为实部,低位为虚部
}
Fs为采样频率,此处设为102.4Hz,NPT为数据长度(即前文中提到的N),为了能够分辨0.1Hz,数据长度NPT设为1024,则频率分辨率=102.4/1024=0.1Hz。
1.2
STM32库中给出的FFT函数格式如下:
1
工程文件中包含三个函数库,分别为:
cr4_fft_64_stm32.s
cr4_fft_256_stm32.s
cr4_fft_1024_stm32.s
分别对应数据点数为64,256和1024时的FFT算法。下面将以数据点数是102r(i=0;i<NPT;i++)
float Y= NPT * ((float)lY) /32768;
float Mag = sqrt(X*X + Y*Y)/NPT;
lBUFMAG[i]= (u32)(Mag * 65536);
} //真实振幅lBUFMAG[i]=sqrt(lX*lX + lY*lY)*2/NPT,先除以32768,又乘以65536是为了符合浮点数的计算规律
如图5所示,官方FFT算法耗时9ms,非官方耗时411ms。
图5两种算法所消耗时间
4
官方FFT算法与非官方FFT算法数据点为1024时,幅值精度均很高。但是官方FFT算法很快,仅耗时9ms,非官方库耗时较长,为411ms。
Voidcr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
其中,NPT为数据点个数,通过修改宏定义来修改NPT代表的值,此处为1024;LBUFOUT[NPT]和LBUFIN[NPT]均是长度为NPT的32位长整型的数组,高16位为实部,低16位为虚部,LBUFOUT[NPT]用于保存FFT之后的输出值;LBUFIN[NPT]用于保存输入的数值。
{
s16 lX,lY;
u32 i;
for(i=0;i<NPT/2;i++)//由于FFT的频谱结果是关于奈奎斯特频率对称的,所以只计算一半的点即可
{
lX = (lBUFOUT[i] << 16) >> 16;//取低16位,虚部
lY = (lBUFOUT[i] >> 16);//取高16位,实部
{
float X= NPT * ((float)lX) /32768;
对原始数据进行FFT之后,需要对输出数据进行处理。
1.2.1
每个频率点处代表的真实频率为
for(i=0;i<NPT/2;i++)
{
Fn=i*Fs/NPT//由于此处i是从0开始的,所以不需要再减1
}
1.2.2
经过FFT后,每个频率点处的真实幅值的计算公式如下。
void dsp_asm_powerMag(void)
}
lBUFMAG[0]= lBUFMAG[0]/2;//直流分量不需要乘以2,所以按照乘以2计算后,要除以2
}
得到每个频率点所代表的真实频率Fn,以及该真实频率所代表的原始信号的振幅A,将其通过串口打印到电脑上。
for(i=0;i<NPT/2;i++)
{
printf("%4d,%.2f%10d\n",i,((float)i*Fs/NPT),lBUFMAG[i]); }
printf_dsp_g2_Mag();//将各个频率点上的振幅打印到电脑上
timetest_g2FFT();//通过定时器测试该FFT算法消耗的时间,包括计算各个频率点的振幅计算时间
非官方的FFT算法的计算结果详见”非官方FFT结果.txt”附件
3
通过配置TIM6定时器进行计时,单位为ms。对官方FFT算法以及非官方FFT算法进行了耗时测试,测试10次FFT总时间,求取平均值,其中包括计算各个频率点幅值的时间,将测试结果打印到电脑上。
第一个点表示直流分量(即0Hz),而最后一个点N的再下一个点(实际上这个点是不存在的,这里是假设的第N+1个点,也可以看做是将第一个点分做两半分,另一半移到最后)则表示采样频率Fs,这中间被N-1个点平均分成N等份,每个点的频率依次增加。例如某点n所表示的频率为:
频率分辨率( )等于采样时间的倒数。例如要分辨0.1Hz,则需要采集10s。
相关文档
最新文档