STM32F4 FPU简单设置

本文介绍如何在STM32F4系列微控制器上启用和利用浮点单元(FPU)进行高效浮点运算。通过详细步骤指导设置过程,并展示了使用FPU可以显著提高乘除法运算速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一步:
在stm32f4xx.h中定义宏__FPU_PRESENT ; __FPU_USED

#define __CM4_REV                 0x0001  /*!< Core revision r0p1                            */
#define __MPU_PRESENT             1       /*!< STM32F4XX provides an MPU                     */
#define __NVIC_PRIO_BITS          4       /*!< STM32F4XX uses 4 Bits for the Priority Levels */
#define __Vendor_SysTickConfig    0       /*!< Set to 1 if different SysTick Config is used  */
#define __FPU_PRESENT             1       /*!< FPU present                                   */
#define __FPU_USED                1

第二步:
在stm32f4xx.h中增加头文件arm_math.h

#include "core_cm4.h"             /* Cortex-M4 processor and core peripherals */
#include "system_stm32f4xx.h"
#include <stdint.h>
#include "arm_math.h"

第三步:
在system_stm32f4xx.c的SystemInit()中添加如下代码:

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif

第四步:
在配置的c++界面添加宏定义ARM_MATH_CM4, __CC_ARM

这里写图片描述
第五步 :
编译写个测试程序测试下代码

static void TaskProcess(void)
{
    static uint8_t flag = 0;
    static uint8_t eeprom_cmd = 1;
    static uint16_t i = 0;
    static float num_f = 0;
    static float a = 3.1415926;
    static float b = 87.6;
    static float c = 76.987;

    sd_card_test();
    TIM_SetCounter(RUNTIMER_TIM, 0);
    num_f = a * b / c;

        printf("t %dus \r\n",TIM_GetCounter(RUNTIMER_TIM)); 

  while(1); 
    while (1)
    {   
    printf("Hello STM32");
    }
}

定时器时钟为84M,不分频。
开启FPU运算时长为22×1/84 us;
不开启FPU运算时长为192×1/84 us;
可见开启FPU浮点运算乘除法快了8.7倍!!!
这里写图片描述

### STM32F4 浮点运算单元 (FPU) 配置与使用 #### 启用 FPUDSP 扩展功能 为了使STM32F4能够执行浮点运算,在项目初始化阶段需确保启用了硬件浮点运算支持。这涉及到修改`stm32f4xx_hal_conf.h`文件中的预处理器指令来激活必要的库特性[^1]。 ```c #define __FPU_PRESENT 1U /*!< Value is defined by CMSIS */ #define __FPU_USED 1U /*!< Set to 1 if FPU is used */ ``` 上述设置告知编译器该设备具备并打算利用内置的浮点处理能力。当这两个宏被定义为 `1` 时,意味着目标MCU确实装备有FPU,并且应用程序计划调用其资源来进行更复杂的数学计算操作。 #### 初始化过程中的注意事项 在启动代码里应当包含适当的配置步骤以正确地准备FPU环境。通常情况下,HAL库会自动完成大部分工作;然而开发者仍需要注意某些特定情况下的额外需求: - 如果采用裸机编程方式,则可能需要手动编写汇编代码片段用于开启协处理器接口。 - 对于链接脚本而言,应该指定`.fpreg`段放置位置以便保存寄存器状态信息。 #### 编写高效的浮点算法 一旦成功设置了这些选项之后就可以自由运用C/C++语言里的标准数据类型如float,double等进行开发了。值得注意的是,尽管有了专门设计过的加速引擎辅助,但在嵌入式环境中合理规划内存占用量以及优化性能依然是至关重要的考量因素之一。 对于那些对精度要求不高或者希望进一步提升效率的应用场景来说,可以考虑使用单精度(`float`)代替双精度(`double`)变量,因为前者往往能带来更好的速度表现同时减少存储空间消耗。 #### 实际应用案例分析 假设现在有一个简单的例子想要展示如何在一个基于STM32CubeMX生成的基础框架上实现基本正弦波形发生器的功能。这里的关键在于理解怎样通过调整定时器中断频率配合恰当的比例因子将角度转换成对应的幅度值输出给DAC模块形成连续变化信号。 ```c #include "main.h" void SystemClock_Config(void); static void MX_GPIO_Init(void); int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); /* Enable the FPU before using floating-point operations */ SCB->CPACR |= ((3UL << 10*2)|(3UL<<11*2)); //Enable CP10 and CP11 Full Access while (1){ float angle = 0; for(angle=0;angle<360;angle+=0.1){ float amplitude = sin((angle * M_PI)/180); // Convert degrees to radians then calculate sine value. uint16_t dac_value = (uint16_t)((amplitude + 1)* DAC_MAX_VALUE/2); // Scale between 0~Vref HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R,dac_value); HAL_Delay(1); } } } ``` 此程序展示了如何安全有效地启用FPU访问权限并通过它完成一次完整的周期性函数绘图任务。注意这里的延迟是为了模拟实际应用场景中可能会存在的采样间隔时间差异而加入的人工延时机制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值