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

本文介绍了如何在STM32F4微控制器上充分利用其内置的浮点运算单元(FPU)进行高效数学运算。关键步骤包括在代码中启用FPU设置,使用CMSIS库中的arm_math.h而不是标准的math.h,并添加相应的库文件。通过定义预处理器宏ARM_MATH_CM4和__FPU_PRESENT=1,__FPU_USED=1,可以确保使用优化的浮点运算函数。同时,文章还提到了不同库文件的选择,以及CMSIS库中提供的各种数学和滤波功能。
AI助手已提取文章相关产品:

使用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(离散余弦变换)和配套的初始化函数。

您可能感兴趣的与本文相关内容

Build started: Project: spwm *** Using Compiler 'V6.16', folder: 'F:\MDK keil\ARM\ARMCLANG\Bin' Build target 'spwm' compiling stm32f4xx_hal_dma_ex.c... compiling stm32f4xx_hal_rcc.c... compiling stm32f4xx_hal_msp.c... compiling stm32f4xx_hal_pwr.c... compiling stm32f4xx_hal_gpio.c... compiling stm32f4xx_hal_flash.c... compiling stm32f4xx_hal_adc_ex.c... compiling stm32f4xx_ll_adc.c... compiling tim.c... compiling gpio.c... compiling stm32f4xx_hal_flash_ramfunc.c... compiling svpwm.c... compiling dma.c... compiling stm32f4xx_hal.c... compiling i2c.c... compiling adc.c... compiling pid.c... compiling menu.c... compiling pfc.c... compiling stm32f4xx_hal_cortex.c... compiling stm32f4xx_it.c... compiling key.c... compiling stm32f4xx_hal_adc.c... compiling OLED.c... compiling stm32f4xx_hal_pwr_ex.c... compiling stm32f4xx_hal_flash_ex.c... ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(341): error: "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS, ARM_MATH_CM0, ARM_MATH_ARMV8MBL, ARM_MATH_ARMV8MML" ^ ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(491): warning: '__PKHBT' macro redefined [-Wmacro-redefined] #define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1851): note: previous definition is here #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(493): warning: '__PKHTB' macro redefined [-Wmacro-redefined] #define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1854): note: previous definition is here #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(680): error: redefinition of '__QADD8' CMSIS_INLINE __STATIC_INLINE uint32_t __QADD8( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1332): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(698): error: redefinition of '__QSUB8' CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB8( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1381): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(716): error: redefinition of '__QADD16' CMSIS_INLINE __STATIC_INLINE uint32_t __QADD16( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1430): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(733): error: redefinition of '__SHADD16' CMSIS_INLINE __STATIC_INLINE uint32_t __SHADD16( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1438): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(749): error: redefinition of '__QSUB16' CMSIS_INLINE __STATIC_INLINE uint32_t __QSUB16( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1478): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(765): error: redefinition of '__SHSUB16' CMSIS_INLINE __STATIC_INLINE uint32_t __SHSUB16( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1486): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(781): error: redefinition of '__QASX' CMSIS_INLINE __STATIC_INLINE uint32_t __QASX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1526): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QASX(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(797): error: redefinition of '__SHASX' CMSIS_INLINE __STATIC_INLINE uint32_t __SHASX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1534): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(813): error: redefinition of '__QSAX' CMSIS_INLINE __STATIC_INLINE uint32_t __QSAX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1574): note: previous definition is here __STATIC_FORCEINLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(829): error: redefinition of '__SHSAX' CMSIS_INLINE __STATIC_INLINE uint32_t __SHSAX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1582): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(845): error: redefinition of '__SMUSDX' CMSIS_INLINE __STATIC_INLINE uint32_t __SMUSDX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1750): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(856): error: redefinition of '__SMUADX' CMSIS_INLINE __STATIC_INLINE uint32_t __SMUADX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1684): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(868): error: redefinition of '__QADD' CMSIS_INLINE __STATIC_INLINE int32_t __QADD( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1816): note: previous definition is here __STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(879): error: redefinition of '__QSUB' CMSIS_INLINE __STATIC_INLINE int32_t __QSUB( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1824): note: previous definition is here __STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(890): error: redefinition of '__SMLAD' CMSIS_INLINE __STATIC_INLINE uint32_t __SMLAD( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1692): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(904): error: redefinition of '__SMLADX' CMSIS_INLINE __STATIC_INLINE uint32_t __SMLADX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1700): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(918): error: redefinition of '__SMLSDX' CMSIS_INLINE __STATIC_INLINE uint32_t __SMLSDX( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1766): note: previous definition is here __STATIC_FORCEINLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) ^ ../Core/Src/main.c(36): warning: In file included from... ../Middlewares/ST/ARM/DSP/Inc\arm_math.h(932): error: redefinition of '__SMLALD' CMSIS_INLINE __STATIC_INLINE uint64_t __SMLALD( ^ ../Drivers/CMSIS/Include/cmsis_armclang.h(1708): note: previous definition is here __STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) ^ fatal error: too many errors emitted, stopping now [-ferror-limit=] 2 warnings and 20 errors generated. compiling main.c... compiling stm32f4xx_hal_exti.c... compiling stm32f4xx_hal_rcc_ex.c... compiling stm32f4xx_hal_dma.c... compiling stm32f4xx_hal_i2c.c... compiling stm32f4xx_hal_i2c_ex.c... compiling system_stm32f4xx.c... compiling stm32f4xx_hal_tim_ex.c... compiling stm32f4xx_hal_tim.c... "spwm\spwm.axf" - 19 Error(s), 2 Warning(s). Target not created. Build Time Elapsed: 00:00:44
07-31
Build started: Project: spwm *** Using Compiler 'V6.16', folder: 'F:\MDK keil\ARM\ARMCLANG\Bin' Build target 'spwm' compiling gpio.c... compiling stm32f4xx_hal_flash.c... compiling key.c... compiling stm32f4xx_hal_flash_ramfunc.c... compiling stm32f4xx_hal_flash_ex.c... compiling stm32f4xx_hal_pwr.c... compiling stm32f4xx_hal_pwr_ex.c... compiling pfc.c... compiling stm32f4xx_hal_rcc_ex.c... compiling stm32f4xx_hal_cortex.c... compiling stm32f4xx_hal_adc_ex.c... compiling svpwm.c... compiling pid.c... compiling tim.c... compiling stm32f4xx_hal_dma.c... compiling stm32f4xx_hal_adc.c... compiling stm32f4xx_ll_adc.c... compiling stm32f4xx_hal_rcc.c... compiling dma.c... compiling stm32f4xx_hal_msp.c... compiling adc.c... compiling stm32f4xx_hal.c... compiling stm32f4xx_hal_gpio.c... ../Core/Src/main.c(66): warning: '_USE_MATH_DEFINES' macro redefined [-Wmacro-redefined] #define _USE_MATH_DEFINES ^ <command line>(8): note: previous definition is here #define _USE_MATH_DEFINES 1 ^ ../Core/Src/main.c(153): error: use of undeclared identifier 'M_PI' if (theta > 2 * M_PI) theta = 0; ^ 1 warning and 1 error generated. compiling main.c... compiling stm32f4xx_it.c... compiling i2c.c... compiling stm32f4xx_hal_dma_ex.c... compiling stm32f4xx_hal_exti.c... compiling OLED.c... compiling menu.c... compiling stm32f4xx_hal_i2c.c... compiling stm32f4xx_hal_i2c_ex.c... compiling system_stm32f4xx.c... compiling stm32f4xx_hal_tim_ex.c... compiling stm32f4xx_hal_tim.c... "spwm\spwm.axf" - 1 Error(s), 1 Warning(s). Target not created. Build Time Elapsed: 00:00:46
07-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值