电子产业一站式赋能平台

PCB联盟网

搜索
查看: 214|回复: 0
收起左侧

STM32浮点单元(FPU)使用与性能优化

[复制链接]

989

主题

989

帖子

8575

积分

高级会员

Rank: 5Rank: 5

积分
8575
发表于 2025-2-27 08:00:00 | 显示全部楼层 |阅读模式

b1h2vhzsnjw6404285829.gif

b1h2vhzsnjw6404285829.gif

' b2 i9 i) o' t3 ?, p点击上方蓝色字体,关注我们
2 `- }+ I1 F; z& H  a' `8 p  ?0 n0 g# G0 E5 H

) b6 {+ r: k+ g7 E- Q本文将深入探讨如何启用 FPU、进行精确计算以及优化代码性能,并提供详细的代码示例。
1 p) h' }) I1 k; i" @5 ^/ d1 t6 b( H4 ?/ h# a+ `+ R/ l* D
FPU 是处理器中的硬件模块,专门处理浮点运算(如加、减、乘、除),相比软件实现,其执行速度更快,精度更高。, K) s1 I' A5 C8 r3 _+ N
3 \3 r4 `* S2 q3 R+ J
根据研究,STM32F4、F7、H7 和 L4 系列支持 FPU,其中 F4 和 L4 支持单精度浮点(32 位),而 H7 系列支持双精度浮点(64 位),这为高精度应用提供了更多选择。
9 z0 w% _8 \2 \: j  f2 Z8 V! _; r4 A, C

zhmyjtgdxr46404285930.png

zhmyjtgdxr46404285930.png

. y0 _' v# u* f, j1 R7 q; O% A, V例如,STM32 官方网站 提供了详细的系列对比。
& H( W% M& [" k, s# |+ F3 p4 u* `
. L" l3 P0 ~: ?& `5 L

m2xwct4rxhh6404286030.png

m2xwct4rxhh6404286030.png

/ U- @9 q8 Y: B; w7 V( X: G0 Z9 M) W  P( s* ^, \7 |2 q2 d! V
1
$ k$ p! {3 _# @# _启用 FPU 的步骤* b* E7 h: ]* i  Z* u; V) x# C
要使用 FPU,需要完成以下两个步骤:5 Z$ ^: E) d6 h* o  o- ~5 r/ G
  • 设置编译器标志:确保编译器生成硬件浮点指令。对于 GCC,使用 -mfloat-abi=hard 标志,指示使用硬件 FPU。可以通过 IDE(如 STM32CubeIDE)或命令行设置。例如,在 STM32CubeIDE 中,右键项目 -> 属性 -> C/C++ Build -> Settings -> MCU Settings,确保启用硬件浮点支持。
  • 启用 FPU 寄存器:在代码中设置系统控制块(SCB)的协处理器访问控制寄存器(CPACR),启用 FPU。代码如下:
    ; x, z0 x9 Y3 Y
  • #include "stm32f4xx.h"SCB->CPACR |= ((3UL 20) | (3UL 22));  // 启用 CP10 和 CP11,允许 FPU 使用
    . c; ]$ c2 O8 \9 _$ G8 k2# Q1 v: S2 N; e) m: y6 Z
    使用 FPU 进行精确计算
    % y! \* N+ ~* {3 M: ^启用 FPU 后,可以执行各种浮点运算。# j# F, `2 E* y3 \$ b1 g) p4 x+ v1 S

    4 E$ K6 H; Y+ m! m: X以下是使用 FPU 的典型示例:$ E  x+ F' x" p9 f6 o0 {' k

      N& [4 @% ?! y' Q& N% _, I基本运算:直接使用浮点变量进行加减乘除,如:
    2 @9 @  |" e# o2 \8 f# ~" h! l
    : \: A) }) I8 r7 f$ E
  • float a = 5.5f; float b = 3.25f; float c = a + b;标准库函数:使用数学库函数,如 sinf、cosf 等。例如,计算正弦值:6 v2 X* \% f! y% Y
    4 \8 L) B" f( q! J1 _
  • float angle = 0.0f;float sine = sinf(angle);一个实际应用是控制 LED 亮度,通过正弦波生成呼吸效果:
    9 u4 C% g- D/ D% b# j4 L1 g3 T' F/ _- V& y6 ^# f" @
  • #include "stm32f4xx.h"intmain(void){    SCB->CPACR |= ((3UL 20) | (3UL 22));  // 启用 FPU    // 初始化 PWM 输出,假设使用 TIM3 CH1 控制 LED    RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;    TIM3->ARR = 1000;  // 自动重装载值    TIM3->CCR1 = 0;    // 初始占空比    TIM3->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1;  // PWM 模式 1    TIM3->CCER |= TIM_CCER_CC1E;  // 启用通道 1    TIM3->CR1 |= TIM_CR1_CEN;     // 启用定时器    float angle = 0.0f;    while (1) {        float brightness = (sinf(angle) + 1.0f) / 2.0f * 1000.0f;        TIM3->CCR1 = (uint32_t)brightness;        angle += 0.01f;        if (angle > 2.0f * 3.14159f) angle = 0.0f;        for (volatileint i = 0; i 10000; i++);  // 简单延时    }}4 I6 r; q9 K, r2 J8 P
    3
    ! A1 ]6 y0 N0 j/ ^  F性能优化与比较
    , |. b+ q/ I+ z3 pFPU 的主要优势是提升浮点运算性能。
    * U6 B9 `0 \& V
    7 X  a# L; w. D$ d以下是比较 FPU 和软件浮点运算性能的示例代码:+ M: p0 e7 W' r2 i: @% A0 s
    & C! T, v" R+ M" ?
  • #include "stm32f4xx.h"#includevolatilefloat result;volatileuint32_t start, end;intmain(void){    // 启用 FPU    SCB->CPACR |= ((3UL 20) | (3UL 22));    // 测量 FPU 性能    start = DWT->CYCCNT;    for (int i = 0; i 1000; i++) {        result = sinf((float)i) * cosf((float)i);    }    end = DWT->CYCCNT;    uint32_t fpu_time = end - start;    // 禁用 FPU,模拟软件浮点(需设置编译器为 -mfloat-abi=soft)    // 这里假设已切换编译器设置    start = DWT->CYCCNT;    for (int i = 0; i 1000; i++) {        result = sinf((float)i) * cosf((float)i);    }    end = DWT->CYCCNT;    uint32_t soft_time = end - start;    while (1);  // 无限循环,供调试}
    5 V- c  ~1 t; q! `( a! H$ e运行发现,FPU 模式下的执行时间通常比软件浮点模式快数倍,尤其在密集计算场景中。1 s. `. e# H6 _8 a- k
    4
    9 H, j4 l5 M! h2 ^! ?/ B6 \7 e精度与异常处理
    7 u$ ^1 N! X! mSTM32F4 系列的 FPU 支持单精度浮点(32 位),精度约为 6-7 位有效数字,适合大多数嵌入式应用。# o9 r' b: f4 s/ o: S
    ' Y3 n$ ~9 ?- L4 ~' N. u
    而 H7 系列支持双精度浮点(64 位),精度更高,适合科学计算和金融应用。
    & Z* W; o+ K1 W2 v. Z
    " H# k3 r" T6 t& N需要注意的是,尝试使用双精度运算可能导致异常(如 STM32F4 不支持),需检查数据类型和编译器设置。+ i- A' ^. R- y! a+ f: x
    . t. K' s+ w0 n* a1 j
    浮点异常处理涉及检测溢出、下溢和无效操作,可通过配置 FPU 的控制寄存器实现,具体方法可参考 ARM Cortex-M 编程指南。
    . ~5 L: S3 P' n+ G5& ^9 R  C+ v( R) O
    优化技巧与注意事项# `: w5 S4 ?6 ~5 l* f
  • 减少不必要的浮点运算:将浮点运算替换为定点运算(如使用整数代替小数),减少 FPU 使用。
  • 数据类型选择:优先使用 float 而非 double,减少内存和计算开销。
  • 中断与任务管理:在多任务或中断场景下,确保 FPU 状态正确保存,防止寄存器冲突。
    / [5 }- h) R6 {8 i% Z' L通过正确启用和使用 FPU,STM32 微控制器可在浮点运算中实现高精度和高性能。
    ' _: `& E1 C% F0 `& d; b8 p& ~

    3fct344ufwd6404286131.jpg

    3fct344ufwd6404286131.jpg
    ; R  O. {1 f, b9 l( L7 s  `+ t# [: s

    2bgzbxzcrwi6404286231.gif

    2bgzbxzcrwi6404286231.gif
    % g* q! C# M; p7 B6 u
    点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表