STM32-F4屬于Cortex-M4F構(gòu)架,這與M0、M3的最大不同就是具有FPU(浮點(diǎn)運(yùn)算單元),支持浮點(diǎn)指令集,因此在處理數(shù)學(xué)運(yùn)算時(shí)能比M0/M3高出數(shù)十倍甚至上百倍的性能,但是要充分發(fā)揮FPU的數(shù)學(xué)性能,除了#include “arm_math.h”(而非用編譯器自帶的math.h)以外,(arm_math.h位于LibrariesCMSISInclude文件夾)還需要進(jìn)行設(shè)置。
本文引用地址:http://m.butianyuan.cn/article/201611/322357.htm1、代碼設(shè)置
如果沒有啟動(dòng)FPU而使用數(shù)學(xué)函數(shù)運(yùn)算時(shí),CPU執(zhí)行時(shí)認(rèn)為遇到非法指令而跳轉(zhuǎn)到HardFault_Handler()中斷函數(shù)中死循環(huán)。因此,需要在系統(tǒng)初始化時(shí)開啟FPU。在system_stm32f4xx.c中的SystemInit()函數(shù)中添加如下代碼:
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
#endif
2、編譯控制
從上面的代碼可以看出,當(dāng)__FPU_PRESENT=1且__FPU_USED=1時(shí), 編譯時(shí)就加入了啟動(dòng)FPU的代碼,CPU也就能正確高效的使用FPU進(jìn)行簡單的加減乘除了。但是對(duì)于復(fù)雜運(yùn)算要充分發(fā)揮M4F的浮點(diǎn)功能,就需要使用固件 庫自帶的arm_math.h而非編譯器自帶的math.h,這個(gè)文件根據(jù)編譯控制項(xiàng)(__FPU_USED ==1)來決定是使用哪一種函數(shù)方法:如果沒有使用FPU,那就調(diào)用keil的標(biāo)準(zhǔn)math.h頭文件中定義的函數(shù);如果使用了FPU,那就是用固件庫自 帶的優(yōu)化函數(shù)來解決問題。
在arm_math.h開頭部分有一些編譯控制信息:
#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"
從中可以看出,為了使用STM32F4的arm_math.h,我們需要定義ARM_MATH_CM4;否則如果不使用CMSIS的庫,就會(huì)調(diào)用Keil自帶的math.h。
另外,定義控制項(xiàng)__CC_ARM在某些數(shù)學(xué)函數(shù)中會(huì)使用VSQRT指令(浮點(diǎn)運(yùn)算指令),運(yùn)算速度比Q指令要快很多。
總結(jié)一下,需要在Project->Options for target"XXXX")中的C/C++選項(xiàng)卡的Preprocessor Symbols欄的Define中加入如下的語句:ARM_MATH_CM4, __FPU_PRESENT=1, __FPU_USED =1, __CC_ARM。
3、添加庫
根據(jù)使用的器件和運(yùn)算模式,添加arm_cortexMxx_math.lib到工程文件中,位于LibrariesCMSISLibARM中。
* The library installer contains prebuilt versions of the libraries in theLibfolder.
* - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4)
* - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4)
* - arm_cortexM4l_math.lib (Little endian on Cortex-M4)
* - arm_cortexM4b_math.lib (Big endian on Cortex-M4)
* - arm_cortexM3l_math.lib (Little endian on Cortex-M3)
* - arm_cortexM3b_math.lib (Big endian on Cortex-M3)
* - arm_cortexM0l_math.lib (Little endian on Cortex-M0)
* - arm_cortexM0b_math.lib (Big endian on Cortex-M3)
注:如果存儲(chǔ)空間不允許,也可以不添加庫,只添加LibrariesCMSISDSP_LibSource中需要的源文件和arm_math.h。
其他DSP使用示例見LibrariesCMSISDSP_LibExamples。
下圖所示為DSP_Lib的文件結(jié)構(gòu)
BasicMathFunctions
提供浮點(diǎn)數(shù)的各種基本運(yùn)算函數(shù),如加減乘除等運(yùn)算。對(duì)于M0/M3只能用Q運(yùn)算,即文件夾下以_q7、_q15和_q31結(jié)尾的文件;而M4F能直接硬件浮點(diǎn)計(jì)算,屬于文件夾下以_f32結(jié)尾的文件。
CommonTables
arm_common_tables.c文件提供位翻轉(zhuǎn)或相關(guān)參數(shù)表。
ComplexMathFunctions
復(fù)述數(shù)學(xué)功能,如向量處理,求模運(yùn)算的。
ControllerFunctions
控制功能,主要為PID控制函數(shù)。arm_sin_cos_f32/-q31.c函數(shù)提供360點(diǎn)正余弦函數(shù)表和任意角度的正余弦函數(shù)值計(jì)算功能。
FastMathFunctions
快速數(shù)學(xué)功能函數(shù),提供256點(diǎn)正余弦函數(shù)表和任意任意角度的正余弦函數(shù)值計(jì)算功能,和Q值開平方運(yùn)算:
Arm_cos_f32/_q15/_q31.c:提供256點(diǎn)余弦函數(shù)表和任意角度余弦值計(jì)算功能。
Arm_sin_f32/_q15/_q31.c:提供256點(diǎn)正弦函數(shù)表和任意角度正弦值計(jì)算功能。
Arm_sqrt_q15/q31.c:提供迭代法計(jì)算平方根的函數(shù)。對(duì)于M4F的平方根運(yùn)算,通過執(zhí)行VSQRT指令完成。
FilteringFunctions
濾波函數(shù)功能,主要為FIR和LMS(最小均方根)濾波函數(shù)。
MatrixFunctions
矩陣處理函數(shù)。
StatisticsFunctions
統(tǒng)計(jì)功能函數(shù),如求平均值、計(jì)算RMS、計(jì)算方差/標(biāo)準(zhǔn)差等。
SupportFunctions
支持功能函數(shù),如數(shù)據(jù)拷貝,Q格式和浮點(diǎn)格式相互轉(zhuǎn)換,Q任意格式相互轉(zhuǎn)換。
TransformFunctions
變換功能。包括復(fù)數(shù)FFT(CFFT)/復(fù)數(shù)FFT逆運(yùn)算(CIFFT)、實(shí)數(shù)FFT(RFFT)/實(shí)數(shù)FFT逆運(yùn)算(RIFFT)、和DCT(離散余弦變換)和配套的初始化函數(shù)。
評(píng)論