STM32L4 属于 Cortex M4F 架构,带有 32 位单精度硬件 FPU,支持浮点指令集,相对于Cortex M0 和 Cortex M3 等,高出数十倍甚至上百倍的运算性能。
而我们在处理音频数据的时候,有的时候需要使用官方的《arm_cortexM4lf_math.lib》来处理数据,在使用滤波器的同时就需要进行大量的浮点数计算。
STM32L4 硬件上要开启 FPU 是很简单的,通过一个叫:协处理器控制寄存器(CPACR)的寄存器设置即可开启 STM32L4 的硬件 FPU。
这里我们就是要设置 CP11 和 CP10 这 4 个位,复位后,这 4 个位的值都为 0,此时禁止访问协处理器(禁止了硬件 FPU),我们将这 4 个位都设置为 1,即可完全访问协处理器(开启硬件 FPU),此时便可以使用 STM32L4 内置的硬件 FPU 了。
那么如何在程序里面设置开启FPU。
首先在system_stm32l4xx.c文件中可以找到一个系统的初始化函数SystemInit,里面定义了开启FPU的设置
在这里可以看到通过__FPU_PRESENT和__FPU_USED来控制FPU的开启。
__FPU_PRESENT:用以确认处理器带有FPU功能。
__FPU_USED:用以确认开启FPU功能。
然后我们在stm32l475xx.h文件中发现了有这样一行代码
这一句说明我们的单片机是支持FPU的,此时__FPU_PRESENT是默认开启。
然后查找__FPU_USED的定义处。
在core_cm4.h中发现__FPU_USED的定义处
在这里发现默认__FPU_USED为失能状态。
发现__TARGET_FPU_VFP并没有定义。
需要在keil工程里加入几个宏定义
__TARGET_FPU_VFP :FPU的条件编译配置宏(开和关) -> 配置该宏,则开
ARM_MATH_MATRIX_CHECK:库函数参数检查配置宏(开和关)
ARM_MATH_ROUNDING:库函数运算是否开启四舍五入(开和关)
ARM_MATH_CM4:使用FPU,必须配置该宏,不配置该宏,编译之后,默认使用math.h库函数,不使用硬件FPU
__CC_ARM:不同编译器的编译配置宏(__CC_ARM代表MDK开发环境)
需要在工程Option -> C++ -> define 加入以下代码,用英文逗号隔开,第二项根据自己使用的单片机型号进行选择。
USE_HAL_DRIVER,STM32L475xx,__TARGET_FPU_VFP,ARM_MATH_CM4,__FPU_PRESENT,__CC_ARM
可以发现在里面也添加了宏定义__FPU_PRESENT。因为根据实际经验,如果不加入这个宏定义,会报错。
Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT
所以完整的宏定义为上述
USE_HAL_DRIVER,STM32L475xx,__TARGET_FPU_VFP,ARM_MATH_CM4,__FPU_PRESENT,__CC_ARM