你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32F3xx/STM32F4xx 使用浮点开方指令

[复制链接]
STMCU小助手 发布时间:2022-2-26 16:09
前言* D  t, d% R# V3 h6 y" L
STM32F3xx/STM32F4xx(ARM Cortex-M4 内核)中集成了 FPU,也就是浮点指令单元,可以将浮点运算变得简单快速,但如果想要发挥出这个浮点运算的最大功效,必须使用浮点指令集,开发者可以直接使用浮点指令集,但目前随着系统的集成度更大,开发者还是希望使用 C 语言进行编程,还要求执行时间短,当调用 DSP_Lib 库函数方式,时会有执行时间长的问题,本文以浮点开方为例对此类需求做相关说明。8 x" ?2 ?. ?1 q

5 n$ E/ r  ]* N/ |. cCortex-M4 内核浮点指令集  D2 V6 \+ Q5 @# {
数运算算浮点指令& @7 L$ W5 h* J; J1 g7 z2 `- {* i* f2 _
  V/ V& w6 O% V. f
CLF(4K4VWODK$AA7B2`8P~Y.png
& t/ {! T: G: r. j+ i
# [9 M/ c- P4 q3 r+ o转移,调用,比较浮点指令. j# V+ _  M" I; E8 @9 G3 X* G! O( R; B
3 F" t0 {' p/ j  l2 Z0 {  T- ^
49H_J7FC1THTGFNC`0VP8WP.png
+ ~( q. t: R/ z6 R/ G1 B6 e5 A6 n/ n2 v  S2 u$ u4 R
Keil 编译器的浮点开方使用
5 n8 T, Z$ j' ~: c& [2 @1) 编译器设定
  }4 r9 b; J: O4 f6 M6 a
首先选择单精度浮点硬件单元
- i/ T* ?) X2 i: m* r
* C! l8 L1 r- j4 }9 [0 v( [ SVW4E{PR7UKQF$J2B[XPV3Q.png
; y: U  q. ]& F. }
! Z: _/ A; ^, b& r7 s: U在 Define 部分增加 ARM_MATH_CM4,__FPU_PRESENT=1,__FPU_USED =1 的定义5 O/ u9 l3 ]" [: x

5 k4 R4 Z4 ^/ D" ?8 q+ q- C: J %PT)22Y1IYWX1DM@7_%PVVH.png
/ Z7 s- H: P% e7 k5 B. w6 h9 R( V8 G. r/ B0 ^( D
2) 加入包含文件#include "math.h"
& u: ~! _% p& I  a' S* b% o; t" m
9 I0 u) m. a. X" n+ Q
) ~3 m- X/ Y& y- _* S; P/ S
J6IZICGWE}J3P8RI3[XI[[0.png
' {% R# d( y$ d+ h
& @4 l- z; p5 W  j2 W3) 加入测试代码
' C* N1 g5 A! c) e1 {' q
直接调用内联函数__sqrtf()
) z% x6 \9 u* K3 M2 e4 Y! f: D
  1.    volatile float32_t Sqr_Inf1,Sqr_Inf2;
    / ^0 N9 p3 `8 B6 k
  2.    volatile float32_t Sqr_Outf[2];, ?6 p, D" r9 v
  3.    Sqr_Inf1 = 1560.69f;
    ( P' L+ w& S& j3 s  y/ k
  4.    Sqr_Inf2 = 123.2f;
    $ m0 D, t0 U. Y8 u+ E: \6 H7 N
  5.    while(1)
    ) ]$ }% ?* V. O& j9 B
  6.    {3 E" P0 S6 }5 m! J& h. f
  7.    Sqr_Outf[0] = __sqrtf(Sqr_Inf1);- b+ S, p7 `) m
  8.    Sqr_Outf[1] = __sqrtf(Sqr_Inf2);- U9 l) m* _# Y+ W) T
  9.    }
复制代码

. W2 G' X+ _: ]3 h" G3 R6 Q& P   汇编代码如下, 可以直观看到 VSQRT.F32 这条直接使用浮点开方运算的指令
0 k/ t" I# @9 P, u; ^0 m
, _; M- |; p9 m4 Z' E$ Z3 ]2 p 5F]MFZMTLXR4}9GL2S]UL.png
# R% Z, k5 M& s) l3 c
0 B% Q8 e' k* [. J- l+ L, z# a1 u0 K IAR 编译器的浮点开方使用% B0 M* G. T+ T' P1 p% j' u
1) 编译器设定
* B" S" i. I2 q* \  H6 R. w0 R
   选择单精度浮点硬件单元5 a/ W$ L) G% ]0 Y# X7 h
7 E' N- R% C' C1 z+ G: D( P3 H
UJ($JVL[O36BAB$`V@)1)GO.png + }0 [9 @7 x$ _' |: |/ F
; p9 u6 I6 s. g1 J) q
2) 加入包含文件#include "math.h"
: _$ R0 x* \  A; m# p. H
4 \2 L! M' P' e/ }4 o7 g {Y00XKN$Z8)XH@D()}1G6]H.png
6 Z* k% \( m6 f9 J7 g( G* Y2 g- M1 C+ W2 m2 {9 Q: c
3) 加入测试代码; v5 j$ }1 _7 L+ W- n
   需要调用 sqrtf 这个函数# c) c. L2 \0 _
  1.    volatile float32_t Sqr_Inf1,Sqr_Inf2;
    - p, z$ ]# e: d" [4 q' P' r0 b' B
  2.    volatile float32_t Sqr_Outf[2];
    , h1 H, b) P; d% u- k- G8 N; {6 O9 |
  3.    Sqr_Inf1 = 1560.69f;4 ?5 e- D- q3 M2 V
  4.    Sqr_Inf2 = 123.2f;
    8 }2 V0 H9 z' ^- C4 ^* }- z
  5.    while(1)
    " @" {4 ]7 w- S1 C
  6.    {4 z" z5 L0 H$ f  Q, N* n
  7.    Sqr_Outf[0] = sqrtf(Sqr_Inf1);+ D) x. |/ R2 G7 L# v7 h; i
  8.    Sqr_Outf[1] = sqrtf(Sqr_Inf2);& ^. z) ~8 l' a! s* j' E: p
  9.    }
复制代码

- ]% g, ~# d5 J# |5 C  u   汇编代码如下,可以看到 VSQRT.F32 这条直接使用浮点开方运算的指令9 G; e- n- Y4 B$ O# f( e1 t
. _0 ^" i. d- k8 V! T
8V0$_K)674YX]20260(9HUY.png
' _, _' |2 B' K5 u5 o" D  M$ L8 V* f1 T) g$ L4 o: k
值得说明的是 IAR 浮点开方调用普通函数库 sqrtf,这个函数库中做了数据大于 0 的判断, 从软件角度上更安全, 但时间会长;而 Keil 的函数__sqrtf()实际上是类似 inline function 的属性,并没有函数调用和返回的指令,更为简单,执行时间短;
+ B7 t  m4 V1 `( W$ l  Z7 n/ t8 Z3 k) g8 q1 d7 w1 L

1 _- }2 B2 I8 Q6 e) U  B. f3 }) w3 K
赞 收藏 评论0 发布时间:2022-2-26 16:09

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版