您的位置 首页 发布

STM32F4xx FPU的设置

浮点运算一直是定点CPU的难题,比如一个简单的11+11,定点CPU必须要按照IEEE-754标准的算法来完成运算,对于8位单片机来说已经完全是噩

浮点运算一直是定点CPU的难题,比方一个简略的1.1+1.1,定点CPU有必要要依照IEEE-754规范的算法来完结运算,关于8位单片机来说现已完 满是噩梦,对32为单片机来说也不会有多大改进。尽管将浮点数进行Q化处理能充分发挥32位单片机的运算功用,可是精度受到限制而不会太高。关于有 FPU(浮点运算单元)的单片机或许CPU来说,浮点加法仅仅几条指令的工作。

现在又FPU或许硬件浮点运算才干的主要有高端DSP(比方TI F28335/C6000/DM6XX/OMAP等),通用CPU(X87数学协处理器)和高档的ARM+DSP处理器等。

STM32-F4归于Cortex-M4F构架,这和M0、M3的最大不同便是多了一个F-float,即支撑浮点指令集,因而在处理数学运算时能比M0/M3高出数十倍乃至上百倍的功用,可是要充分发挥FPU的数学功用,还需求一些小小的设置

1.编译操控选项:尽管STM32F4XX固件库的例程之system_stm32f4XXX.c文件中增加了对应的代码,但给用户评价运用的 STM32F4-Discovery例程中却没有,因而MDK4.23编写浮点运算程序时,尽管编译器正确产生了V指令来进行浮点运算,可是由于 system_stm32f4XXX.c文件没有启用FPU,因而CPU执行时只认为是遇到不合法指令而跳转到HardFault_Handler()中止 中原地踏步。因而要确保这个过错不发生,有必要要在system_init()函数里边增加如下代码:


#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
#endif

由于这个选项是有条件编译操控的,因而需求在工程选项(Project->Options for target “XXXX”)中的C/C++选项卡的Define中参加如下的句子:__FPU_PRESENT=1,__FPU_USED =1。这样编译时就参加了发动FPU的代码,CPU也就能正确高效的运用FPU进行简略的加减乘除了。

但这还远远不够。关于杂乱运算,比方三角函数,开方等运算,假如编程时仍是运用math.h头文件,那是无法提高功率的:由于math.h头文件是针对所 有ARM处理器的,其运算函数都是依据定点CPU和规范算法(IEEE-754),并没有预见运用FPU的状况,需求许多指令和杂乱的进程才干完结运算, 也就增加了运算时刻。因而要充分发挥M4F的浮点功用,就需求运用固件库自带的arm_math.h,这个文件依据编译操控项(__FPU_USED == 1)来决定是运用那一种函数办法:假如没有运用FPU,那就调用keil的规范math.h头文件中界说的函数;假如运用了FPU,那便是用固件库自带的 优化函数来解决问题。

在arm_math的最初部分是有这些编译操控信息:

#ifndef _ARM_MATH_H
#define _ARM_MATH_H

#define __CMSIS_GENERIC

#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
#include “string.h”
#include “math.h”

便是说假如不运用CMSIS的,就会调用keil自带的规范库函数。不然就用CMSIS的界说。这儿由于是用的STM32F4,所以应该要 ARM_MATH_CM4操控,即参加core_cm4.h,不然就用运用ARMCM4.h——但在编译时keil会提示找不到这文件。因而需求在工程选 项之C/C++选项卡的define中继续参加句子ARM_MATH_CM4。

参加上述编译操控项之后,高档数学函数的运用根本没问题了,比方正余弦三角函数的核算。但需求留意,假如你直接运用sin()、cos()、sqrt() 这样的函数,那成果还算调用keil的math.h,你能够在debug时看对应的代码,其汇编指令为BL.W __hardfp_xxx。因而这时要完结三角函数的核算就要运用arm_sin_f32()或许arm_cos_f32(),用法不变,这两个函数的原 型分别在arm_sin_f32.c和arm_cos_f32.c中。经过对256点三角函数表的查询和插值算法得到恣意视点的准确函数值,这就比“原 装”的sin()、cos()快多了。

当然有些破例的是开发函数sqrt(),在arm_math.h中是这么界说的:

static __INLINE arm_statusarm_sqrt_f32(float32_t in, float32_t *pOut)
{
if(in > 0)
{
//#if __FPU_USED
#if (__FPU_USED == 1) && defined ( __CC_ARM)
*pOut = __sqrtf(in);
#else
*pOut = sqrtf(in);
#endif
return (ARM_MATH_SUCCESS);
}
else
{
*pOut = 0.0f;
return (ARM_MATH_ARGUMENT_ERROR);
}
}

即开方用的函数是arm_sqrt_f32(),其间首要判别被开发的书是否大于0,只要大于0的才干进行运算,不然输出成果为0并回来“过错”标志。如 果大于0,而且实用了FPU和__CC_ARM操控项,那调用__sqrtf()来完结编译,不然调用sqrtf()——这个sqrtf()是能在 keil的math.h中找到的,即调用子函数来完结运算,而__sqrtf()呢?新出现的,信任我们都能猜到是什么玩意儿:对,便是VSQRT指令! 因而要把这点功用也要发挥出来,就需求工程选项之C/C++选项卡的define中继续参加句子__CC_ARM才行。我们能够比较一下是否参加 __CC_ARM编译后会汇编代码的不同巨大不同。

当然,关于arm_sqrt_f32()函数仍是有些费事,假如你承认被开方的书是大于等于0的,那就直接运用__sqrtf()函数完结运算,即一条简略的VSQRT指令。

STM32F4固件库还供给了其他很有用的数学函数,都坐落DSP_Lib文件夹,请我们渐渐探究,Discovery!

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/changshang/fabu/257653.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部