打印
[STM32F4]

使用STM32F4XX自带数学库"arm_math.h"

[复制链接]
7041|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
使用STM32F4XX自带数学库"arm_math.h"

    STM32-F4属于Cortex-M4F构架,这与M0、M3的最大不同就是具有FPU(浮点运算单元),支持浮点指令集,因此在处理数**算时能比M0/M3高出数十倍甚至上百倍的性能,但是要充分发挥FPU的数学性能,除了#include “arm_math.h”(而非用编译器自带的math.h)以外,(arm_math.h位于\Libraries\CMSIS\Include文件夹)还需要进行设置。

1、代码设置
    如果没有启动FPU而使用数学函数运算时,CPU执行时认为遇到非法指令而跳转到HardFault_Handler()中断函数中死循环。因此,需要在系统初始化时开启FPU。在system_stm32f4xx.c中的SystemInit()函数中添加如下代码:
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif

2、编译控制
    从上面的代码可以看出,当__FPU_PRESENT=1__FPU_USED=1时,编译时就加入了启动FPU的代码,CPU也就能正确高效的使用FPU进行简单的加减乘除了。但是对于复杂运算要充分发挥M4F的浮点功能,就需要使用固件库自带的arm_math.h而非编译器自带的math.h,这个文件根据编译控制项(__FPU_USED ==1)来决定是使用哪一种函数方法:如果没有使用FPU,那就调用keil的标准math.h头文件中定义的函数;如果使用了FPU,那就是用固件库自带的优化函数来解决问题。
    在arm_math.h开头部分有一些编译控制信息:
#ifndef _ARM_MATH_H
#define _ARM_MATH_H

#define __CMSIS_GENERIC              /* disable NVIC and Systick functions */
#if defined (ARM_MATH_CM4)
  #include "core_cm4.h"
#elif defined (ARM_MATH_CM3)
  #include "core_cm3.h"
#elif defined (ARM_MATH_CM0)
  #include "core_cm0.h"
#else
#include "ARMCM4.h"
#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....."
#endif

#undef  __CMSIS_GENERIC              /* enable NVIC and Systick functions */
  #include "string.h"
  #include "math.h"


    从中可以看出,为了使用STM32F4的arm_math.h,我们需要定义ARM_MATH_CM4;否则如果不使用CMSIS的库,就会调用Keil自带的math.h。
    另外,定义控制项__CC_ARM在某些数学函数中会使用VSQRT指令(浮点运算指令),运算速度比Q指令要快很多。
    总结一下,需要在Project->Options for target"XXXX")中的C/C++选项卡的Preprocessor Symbols栏的Define中加入如下的语句:ARM_MATH_CM4, __FPU_PRESENT=1, __FPU_USED =1, __CC_ARM

3、添加库
    根据使用的器件和运算模式,添加arm_cortexMxx_math.lib到工程文件中,位于\Libraries\CMSIS\Lib\ARM中。

   * The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder.
   * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
   * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
   * - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
   * - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
   * - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
   * - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
   * - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
   * - arm_cortexM0b_math.lib (Big endian on Cortex-M3)


注:如果存储空间不允许,也可以不添加库,只添加\Libraries\CMSIS\DSP_Lib\Source中需要的源文件和arm_math.h。
    其他DSP使用示例见\Libraries\CMSIS\DSP_Lib\Examples。

下图所示为DSP_Lib的文件结构
BasicMathFunctions
提供浮点数的各种基本运算函数,如加减乘除等运算。对于M0/M3只能用Q运算,即文件夹下以_q7、_q15和_q31结尾的文件;而M4F能直接硬件浮点计算,属于文件夹下以_f32结尾的文件。
CommonTables
arm_common_tables.c文件提供位翻转或相关参数表。
ComplexMathFunctions
复述数学功能,如向量处理,求模运算的。
ControllerFunctions
控制功能,主要为PID控制函数。arm_sin_cos_f32/-q31.c函数提供360点正余弦函数表和任意角度的正余弦函数值计算功能。
FastMathFunctions
快速数学功能函数,提供256点正余弦函数表和任意任意角度的正余弦函数值计算功能,和Q值开平方运算:
Arm_cos_f32/_q15/_q31.c:提供256点余弦函数表和任意角度余弦值计算功能。
Arm_sin_f32/_q15/_q31.c:提供256点正弦函数表和任意角度正弦值计算功能。
Arm_sqrt_q15/q31.c:提供迭代法计算平方根的函数。对于M4F的平方根运算,通过执行VSQRT指令完成。
FilteringFunctions
滤波函数功能,主要为FIR和LMS(最小均方根)滤波函数。
MatrixFunctions
矩阵处理函数。
StatisticsFunctions
统计功能函数,如求平均值、计算RMS、计算方差/标准差等。
SupportFunctions
支持功能函数,如数据拷贝,Q格式和浮点格式相互转换,Q任意格式相互转换。
TransformFunctions
变换功能。包括复数FFT(CFFT)/复数FFT逆运算(CIFFT)、实数FFT(RFFT)/实数FFT逆运算(RIFFT)、和DCT(离散余弦变换)和配套的初始化函数。
沙发
598330983|  楼主 | 2016-2-6 10:05 | 只看该作者

使用特权

评论回复
板凳
JIANG_WX| | 2016-2-18 13:01 | 只看该作者
arm_math.h中,关于求平方根的函数arm_sqrt_f32()中,有一段代码:
    #if (__FPU_USED == 1) && defined ( __CC_ARM   )
        *pOut = __sqrtf(in);
    #else
        *pOut = sqrtf(in);
    #endif

我有几个问题:
1. 在MDK 编译器中,调用了库函数 __sqrtf(),该函数是不是直接用了VSQRT.f32汇编指令?该函数在哪个文件目录中可以找到?
2. 我使用的是IAR编译器,发现它调用的是库函数 sqrtf(),这是个包含在math.h中的标准库函数,没有用到VSQRT.f32汇编指令,我发现执行arm_sqrt_f32()
    的时间很长;
   我的问题是在IAR中怎么用到VSQRT.f32汇编指令来求平方根?因为这样运算速度会快很多。

使用特权

评论回复
地板
598330983|  楼主 | 2016-2-22 11:27 | 只看该作者
我使用的是IAR编译器,发现它调用的是库函数 sqrtf(),这是个包含在math.h中的标准库函数,没有用到VSQRT.f32汇编指令,我发现执行arm_sqrt_f32()的时间很长?
我没用过IAR,都是KEIL

使用特权

评论回复
5
itelectron| | 2016-4-17 14:20 | 只看该作者
为什么我用库计算的结果错误

使用特权

评论回复
6
itelectron| | 2016-4-17 14:33 | 只看该作者
为什么我用库计算的结果是错误的  应该一个结果是5  另外一个结果是8

使用特权

评论回复
7
itelectron| | 2016-4-17 14:34 | 只看该作者
1为什么25开根号出来是0X389
2为什么64开根号出来是0X5A8

使用特权

评论回复
8
BBSTOM| | 2016-4-17 23:07 | 只看该作者
数学库是个好东西!

但我们这里 真正搞算法的工程师并不多。 好比JPEG, MP3,AAC,ADPCM, H.264.... 这些算法。 都是外国人搞的呢。

使用特权

评论回复
9
598330983|  楼主 | 2016-4-24 11:04 | 只看该作者
对于数据处理必须要用到的一个库,好多数据知识和常量

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

246

主题

5384

帖子

22

粉丝