电子产业一站式赋能平台

PCB联盟网

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

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

[复制链接]

1001

主题

1001

帖子

8809

积分

高级会员

Rank: 5Rank: 5

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

b1h2vhzsnjw6404285829.gif

b1h2vhzsnjw6404285829.gif

! y- B! q  O: |点击上方蓝色字体,关注我们
5 V, a2 f5 K1 L6 R# I' [2 k! u$ ?3 L% D+ t7 T
( p! E6 H/ P0 [4 ]: }  [' r, W
本文将深入探讨如何启用 FPU、进行精确计算以及优化代码性能,并提供详细的代码示例。8 s8 z7 x( e" O/ H5 g0 M
- \# `; U$ Q  k- k
FPU 是处理器中的硬件模块,专门处理浮点运算(如加、减、乘、除),相比软件实现,其执行速度更快,精度更高。, q6 S! f& a5 k. f3 l* T+ z9 C5 @

: N4 L6 A0 M4 l9 N6 q! `根据研究,STM32F4、F7、H7 和 L4 系列支持 FPU,其中 F4 和 L4 支持单精度浮点(32 位),而 H7 系列支持双精度浮点(64 位),这为高精度应用提供了更多选择。2 Q, V4 F1 p8 ]+ M
* _* g+ Q: ^# R0 V

zhmyjtgdxr46404285930.png

zhmyjtgdxr46404285930.png

9 n7 o1 `* }$ Z; E* t例如,STM32 官方网站 提供了详细的系列对比。- I8 w6 K6 P: f

2 P: F8 I. j0 k* B" F0 n& n; i: r

m2xwct4rxhh6404286030.png

m2xwct4rxhh6404286030.png
& i3 t* c+ u& F9 x0 |
( w+ Y( c3 S( Q* K
1- H& k& C2 g2 u2 d! ~- R# ?" y+ I
启用 FPU 的步骤
: T# E& }$ G& a, j  F3 b; F要使用 FPU,需要完成以下两个步骤:
- B) E& x0 s' R) K( j
  • 设置编译器标志:确保编译器生成硬件浮点指令。对于 GCC,使用 -mfloat-abi=hard 标志,指示使用硬件 FPU。可以通过 IDE(如 STM32CubeIDE)或命令行设置。例如,在 STM32CubeIDE 中,右键项目 -> 属性 -> C/C++ Build -> Settings -> MCU Settings,确保启用硬件浮点支持。
  • 启用 FPU 寄存器:在代码中设置系统控制块(SCB)的协处理器访问控制寄存器(CPACR),启用 FPU。代码如下:
    # i5 {4 [3 `5 \( H
  • #include "stm32f4xx.h"SCB->CPACR |= ((3UL 20) | (3UL 22));  // 启用 CP10 和 CP11,允许 FPU 使用& d  b5 K5 j+ N9 ?
    2  r2 }) U* m/ }) d" q% t0 V' {
    使用 FPU 进行精确计算7 r; C4 C, O* ~: f: Y6 n, b
    启用 FPU 后,可以执行各种浮点运算。
    ; P+ ?* ^2 ^# x, R7 Y$ I9 p+ Q. u2 @4 C- ~4 x6 q& C% A3 r
    以下是使用 FPU 的典型示例:8 ]: q" P" h2 g1 T
    5 k8 x* F( X# g* x+ C
    基本运算:直接使用浮点变量进行加减乘除,如:3 T' I* w2 H9 }* R: q: u3 S3 G
    % J5 `% s  u$ A# i# O
  • float a = 5.5f; float b = 3.25f; float c = a + b;标准库函数:使用数学库函数,如 sinf、cosf 等。例如,计算正弦值:: B. h! i' w2 z# R$ k3 N' H% q: [
    ; q$ l/ T6 F" X9 r; @
  • float angle = 0.0f;float sine = sinf(angle);一个实际应用是控制 LED 亮度,通过正弦波生成呼吸效果:
    5 E0 S: S8 f- i3 T# `- D
    2 E& p: ?, H8 ?, I0 e) p2 V
  • #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++);  // 简单延时    }}
      x$ {( e! w3 v' h8 m& d( i2 U& @: K3
    / f3 {; r3 {" A7 E# Q/ N9 r+ s性能优化与比较9 |5 ?. V* U# p1 t
    FPU 的主要优势是提升浮点运算性能。. z" P6 F5 v/ r7 t/ a

    " `2 @, S  r# d/ P以下是比较 FPU 和软件浮点运算性能的示例代码:. U( f, i/ {% H* ^
    : O8 x* L  |" y% B' d) |
  • #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);  // 无限循环,供调试}- k) \8 \; y8 I" V# e6 M# `1 [+ N
    运行发现,FPU 模式下的执行时间通常比软件浮点模式快数倍,尤其在密集计算场景中。3 H& \, l1 n1 G0 ~2 m7 E! y* p
    4
    5 T: Y% B- f" C- ?# z: |精度与异常处理
    * r, Y" {0 E2 D/ \7 N; `' xSTM32F4 系列的 FPU 支持单精度浮点(32 位),精度约为 6-7 位有效数字,适合大多数嵌入式应用。
    6 {. }' E+ O% }- ]3 }" p2 n- ^, f2 O1 o% w# v  ?
    而 H7 系列支持双精度浮点(64 位),精度更高,适合科学计算和金融应用。
    * m& r& Y9 e& M3 i& k6 e; E
    5 h2 y3 i, P2 _/ f" ^需要注意的是,尝试使用双精度运算可能导致异常(如 STM32F4 不支持),需检查数据类型和编译器设置。" `# `, l5 P* I$ f4 ?9 |6 P; S% [
    % u. i5 L+ Y0 v; ~) ~5 o% z" m
    浮点异常处理涉及检测溢出、下溢和无效操作,可通过配置 FPU 的控制寄存器实现,具体方法可参考 ARM Cortex-M 编程指南。
    0 v  w6 B5 y. r5
    0 w) z* T  }: `9 ?5 h, d, j$ P优化技巧与注意事项
    * t7 \1 r7 i4 ?6 R/ v! \
  • 减少不必要的浮点运算:将浮点运算替换为定点运算(如使用整数代替小数),减少 FPU 使用。
  • 数据类型选择:优先使用 float 而非 double,减少内存和计算开销。
  • 中断与任务管理:在多任务或中断场景下,确保 FPU 状态正确保存,防止寄存器冲突。# J9 J) j0 n0 [. u" i! j
    通过正确启用和使用 FPU,STM32 微控制器可在浮点运算中实现高精度和高性能。
    " a3 t- x* a. L" p* B( q1 {+ T

    3fct344ufwd6404286131.jpg

    3fct344ufwd6404286131.jpg
    - z6 u) g* ]& F* T) K

    2bgzbxzcrwi6404286231.gif

    2bgzbxzcrwi6404286231.gif

    ! |" U$ U) [' e5 A6 H6 x+ R* M点击阅读原文,更精彩~
  • 回复

    使用道具 举报

    发表回复

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

    本版积分规则


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