1 . 建立工程,生成代码时选择包含所有库。
 
2. 打开 option for target 选择 Target 标签,在code generatio中,将floating point hardware 选择 USE Single Precision。
 
3.  打开 option for target 选择 C/C++ 标签

在define后添加:__TARGET_FPU_VFP,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING,ARM_MATH_CM4,__CC_ARM,由于使用HAL的库,所以前面有USE_HAL_DRIVER,STM32F429xx的全局宏定义,如果使用的不是HAL库,而是使用固件库的话,一般会有固件库的一个全局宏定义USE_STDPERIPH_DRIVER和STM32F4XXxx在里面。所以当前只需要添加
__TARGET_FPU_VFP,
ARM_MATH_MATRIX_CHECK,
ARM_MATH_ROUNDING,
ARM_MATH_CM4,
__CC_ARM
注意中间用英文逗号分开。其中ARM_MATH_MATRIX_CHECK是库函数的参数检查开关。ARM_MATH_ROUNDING这个是库函数在运算是是否开启四舍五入的功能,可以根据实际需要进行配置。ARM_MATH_CM4这个就非常重要,必须要配置进去,否则在编译之后,会默认使用math.h的库函数,而不会用到硬件的FPU的。__CC_ARM是不同编译器的编译配置宏定义,__CC_ARM就是代表MDK开发环境。
 4. 添加浮点库(.lib)文件到工程(或者添加源码库文件)。

如果用的是 uv4,打开 C:\Keil\ARM\CMSIS\Lib\ARM 目录,复制“arm_cortexM4lf_math.lib”文件到你的工程下,并加入工程。
如果用的是 uv5,打开 C:\Keil_v5\ARM\Pack\ARM\CMSIS\4.2.0\CMSIS\Lib\ARM 目录,复制“arm_cortexM4lf_math.lib”文件到工程下,并加入工程,4.2.0是库的版本,每个版本可能不一样。
也可以从官方下载固件库程序包中复制也行,  \STM32F4xx_DSP_StdPeriph_Lib\Libraries\CMSIS\Lib\ARM
如果查看DSP库的各个函数的原型,可以添加源码库文件, 则当前工程目录下的Drivers\CMSIS\DSP_Lib\Source目录可以查看,当然安装目录下也有该库源文件。
BasicMathFunctions
基本数学函数:提供浮点数的各种基本运算函数,如向量加减乘除等运算。 
CommonTables
arm_common_tables.c文件提供位翻转或相关参数表。
ComplexMathFunctions
复杂数学功能,如向量处理,求模运算的。
ControllerFunctions
控制功能函数。包括正弦余弦,PID电机控制,矢量Clarke变换,矢量Clarke逆变换等。
FastMathFunctions
快速数学功能函数。提供了一种快速的近似正弦,余弦和平方根等相比CMSIS计算库要快的数学函数。
FilteringFunctions
滤波函数功能,主要为FIR和LMS(最小均方根)等滤波函数。 
MatrixFunctions
矩阵处理函数。包括矩阵加法、矩阵初始化、矩阵反、矩阵乘法、矩阵规模、矩阵减法、矩阵转置等函数。
StatisticsFunctions
统计功能函数。如求平均值、最大值、最小值、计算均方根RMS、计算方差/标准差等。
SupportFunctions
支持功能函数,如数据拷贝,Q格式和浮点格式相互转换,Q任意格式相互转换。
TransformFunctions
变换功能。包括复数FFT(CFFT)/复数FFT逆运算(CIFFT)、实数FFT(RFFT)/实数FFT逆运算(RIFFT)、和DCT(离散余弦变换)和配套的初始化函数。
相关函数说明以及示例也可在安装路径Keil_v5\ARM\PACK\ARM\CMSIS\4.5.0\CMSIS\Documentation\DSP\html下获得,自行查阅。
5. DSP库的FFT变换示例。
在工程的main.c文件中添加如下代码
说明:采样频率为1024Hz,fft点数为1024点,则频率分辨率,计算公式:分辨率=采样频率/采样点数 = 1Hz,此时能看到0Hz,1Hz,2Hz,3Hz,.....512Hz的频率分量。
FFTOutput这个数组中,下标0对应的元素就是0Hz(也就是直流分量)的幅度,下标1对应的就是1Hz的幅度,下标2对应2Hz的幅度......,依次类推。
此点非常重要,例如采样率为2048Hz,那么频率分辨率为2Hz,那么能看到0Hz,2Hz,4Hz,6Hz,.....1024Hz的频率分量
FFTOutput这个数组中,下标0对应的元素就是0Hz(也就是直流分量)的幅度,下标1对应的就是2Hz的幅度,下标2对应4Hz的幅度......,依次类推。此时去看1Hz,3Hz,则会出现误差比较大的情况。
#include "arm_math.h"                  //添加头文件
#define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
#define SAMPLE_FREQ 1024 //采样频率
float fft_inputbuf[FFT_LENGTH*2];      //FFT输入输出数组,此数组为arm_cfft_radix4_f32的输入输出数组,前一个元素为实部,后一个为虚部,每两个元素代表一个点.
float fft_outputbuf[FFT_LENGTH]; //arm_cmplx_mag_f32()幅度输出数组
arm_cfft_radix4_instance_f32 scfft; //fft变换的初始化参数

在主函数进入while(1)之前添加如下代码

说明:arm_sin_f32函数生成采样点,采样信号为DC信号,100Hz,150Hz信号的叠加,此时分辨率为1Hz,刚好能够看到DC, 100Hz,150Hz频率分量的幅度,分别对应fft幅度输出数组的下标0,100,150

arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数
for(int i=0;i<FFT_LENGTH;i++)//生成信号序列
{
fft_inputbuf[2*i]=15 + 10*arm_sin_f32(2*PI*i*100/SAMPLE_FREQ) + \
5.5*arm_sin_f32(2*PI*i*150/SAMPLE_FREQ); //生成实部
fft_inputbuf[2*i+1]=0;//虚部全部为0
}
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4(即fft长度22*n),FFT长度只能为64,256,1024,4096目前测试过这几个长度,)
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值

DC分量值为15360.001,则对应的直流分量为15360.001/FFT点数 = 15360.001/1024=15

100Hz分量值为5119.99658,则对应的100Hz幅度为5119.99658*2/FFT点数 = 5119.99658*2/1024=10

150Hz分量值为2815.99976,则对应的150Hz幅度为2815.99976*2/FFT点数 = 2815.99976*2/1024=5.5

其余的频率的幅度近似为0。

若要查看某一频率分量的实部与虚部,则可以查看fft_inputbuf数组。下标对应乘以2,因为实部和虚部存在。

当把采样频率改为2048Hz,生成信号频率其中一路改为151Hz,读者可以自行测试该频率分量的幅度,肯定会存在误差。



基于HAL库的STM32的DSP库详解(附FFT应用)的更多相关文章

  1. 基于STM32的uCOS-II移植详解

    百度:基于STM32的uCOS-II移植详解 源:基于STM32的uCOS-II移植详解

  2. 对python3中pathlib库的Path类的使用详解

    原文连接   https://www.jb51.net/article/148789.htm 1.调用库 ? 1 from pathlib import 2.创建Path对象 ? 1 2 3 4 5 ...

  3. 基于python中staticmethod和classmethod的区别(详解)

    例子 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 class A(object):   def foo(self,x):     print "executing foo ...

  4. 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...

  5. 【转】VS2013动态库文件的创建及其使用详解

    一.VS2013动态库文件的创建 1.新建项目,win32,win32项目,输入项目名称,例如MakeDll. 2.”确定“——”下一步“,选择”DLL“选项,再点”完成“: 3.菜单栏选择”项目“— ...

  6. C运行时库(C Run-time Library)详解(提供的另一个最重要的功能是为应用程序添加启动函数。Visual C++对控制台程序默认使用单线程的静态链接库,而MFC中的CFile类已暗藏了多线程)

    一.什么是C运行时库 1)C运行时库就是 C run-time library,是 C 而非 C++ 语言世界的概念:取这个名字就是因为你的 C 程序运行时需要这些库中的函数. 2)C 语言是所谓的“ ...

  7. STM32时钟配置方法详解

      一.在STM32中,有五个时钟源,为HSI.HSE.LSI.LSE.PLL. ①HSI是高速内部时钟,RC振荡器,频率为8MHz. ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源, ...

  8. 基于Docker搭建Maven私服Nexus,Nexus详解

    备注:首先在linux环境安装Java环境和Docker,私服需要的服务器性能和硬盘存储要高一点,内存不足可能到时启动失败,这里以4核8GLinux服务器做演示 一:基于Docker安装nexus3 ...

  9. iOS framework静态库中使用xib和图片资源详解

    一.新建bundle 前2篇文章介绍了iOS 最新framework和.a静态库制作及使用全解   iOS 工程套子工程,主工程和framework工程或.a library静态库工程联调 我现在是在 ...

随机推荐

  1. (1)ASP.NET Core3.1 Ocelot介绍

    1.简介 Ocelot原本设计仅为与.NET Core一起使用的,它是一个.NET API网关,作为面向使用.NET运行微型服务/面向服务的体系结构需要统一的系统入口点,即当客户端(Web站点,手机A ...

  2. JS中this的指向性问题

    一.this用于访问当前方法所属的对象,谁调用的方法,方法就属于谁 // 普通函数 let obj = { a : 12, fn() { console.log(this == obj); // tr ...

  3. Markdown tricks

    编辑排版 仅仅了解 Markdown 语法还不够,知道这些 排版技巧 增色您的文章内容. 空格和空行 留白,从艺术角度上说,留白就是以"空白"为载体进而渲染出美的意境的艺术.从应用 ...

  4. 排序算法—快速排序(Quick Sort)

    快速排序(Quick Sort) 快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序. ...

  5. CF1008D Pave the Parallelepiped

    容斥原理 解法一: 其他容斥原理的题也可以用这种思想 先把$A$,$B$,$C$分解因数 一种很暴力的想法是,将这些因数分成若干个集合(画出韦恩图),然后对有序数组的三个数分别枚举其位于哪一个集合中 ...

  6. Java_流相关

    java.io包中重要的5个类3个接口 类名 说明 File 文件类 InputStream 字节流输入 OutputStream 字节流输出 Reader 字符输入流 Writer 字符输出流 Cl ...

  7. Mongoose Guide(转)

    转自:http://www.w3c.com.cn/mongoose-guide Queries 文件可以通过一些静态辅助模型的方法检索. 任何涉及 指定 查询 条件的模型方法,有两种执行的方式: 当一 ...

  8. layui导航

    关于导航 首先看一下官网的样式: <!DOCTYPE html><html><head> <meta charset="utf-8" /& ...

  9. Unix/Linux常用文件操作

    Unix/Linux常用文件操作 秘籍:man命令是Unix/Linux中最常用的命令,因为命令行命令过多,我相信每个人都会经常忘记某些命令的用法,man命令就可以显示一个命令的所有选项,参数和说明, ...

  10. Kubernetes+Promethues+Cloud Alert实践分享

    前言 容器集群管理系统 Kubernetes(简称K8s),为容器化的应用提供部署运行.容器编排.负载均衡.服务发现和动态伸缩等一系列完整功能,Prometheus 对 K8s 支持非常棒,能够自动发 ...