0背景
今日、私はSTM32F4を使用してsin()を計算する必要があります。インターネット上にSTM32F407VGのFPUを開いてDSPライブラリを呼び出すためのチュートリアルがあることに気づきました。無料のSTM32CubeIDEを使用してSTM32を開発しています。適用できるかどうか疑問に思います。
1つの環境
Windows 10 + STM32CubeIDE 1.0.2 + STM32CubeMX 5.3.0 + STM32Cube_FW_F4_V1.24.1 + STM32F4discovery
2STM32CubeMXは初期化コードを生成します
(スキップ)
ボード初期化プログラムを選択することにより、オンボード周辺機器初期化コードを自動生成できます。STM32F4Discoery用のLED、ボタンなどを自動生成できます。
TIM1とTIM3の初期化を自分で増やしました。
3公式DSPライブラリを追加します
フォルダ内の公式DSPライブラリに必要なLIB、ヘッダーファイル、およびソースファイルを見つけ、それらをコピーしてプロジェクトディレクトリに貼り付けます。必要書類を下図に示します。
3.1 LIB
STM32F407VGに対応するライブラリファイルはarm_cortexM4lf_math.libです。
C:\ Users \ Username \ STM32Cube \ Repository \ STM32Cube_FW_F4_V1.24.0 \ Drivers \ CMSIS \ Lib \ ARM \ arm_cortexM4lf_math.lib
3.2ヘッダーファイル
3つのDSPライブラリヘッダーファイルがあり、パスは
C:\ Users \ Username \ STM32Cube \ Repository \ STM32Cube_FW_F4_V1.24.0 \ Drivers \ CMSIS \ DSP \ Include
3.3ソースファイル
ソースファイルはいくつかの数学演算であり、armで最適化されています。多くのフォルダがあり、それらを直接コピーしてプロジェクトのソースファイルディレクトリに貼り付けます。
C:\ Users \ Username \ STM32Cube \ Repository \ STM32Cube_FW_F4_V1.24.0 \ Drivers \ CMSIS \ DSP \ Source
4IDEを構成します
プロジェクトを右クリックして、プロパティを選択します。次の定義をC / C ++のシンボルに追加します。一般->パスとシンボル
値が1の__FPU_PRESENT
__FPU_USED、値は1
__TARGET_FPU_VFP
ARM_MATH_CM4
最後にプロジェクトをコンパイルします。
5コンピューターテスト
main.cの増加
#include "math.h"
#include "arm_math.h"
5.1DSPライブラリを使用しないでください
math.hのsinを使用して正弦を直接計算します。
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET);
Vrefa = Modul_Factor * sin(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000) / 2 + 0.5;
Vrefb = Modul_Factor * sin(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000 + 2*PI/3) / 2 + 0.5;
Vrefc = Modul_Factor * sin(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000 - 2*PI/3) / 2 + 0.5;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
PE7の高レベル時間を観察すると、これらの3行のコードの操作時間を取得できます。測定結果は59usです(各計算には数usの誤差があります)。私の数行のコードは、TIM3の周期的割り込み関数で計算されます。3KHzは毎秒計算されます。
5.2DSPライブラリを使用する
arm_math.hでarm_sin_f32を使用して正弦を計算します(この関数の入力と出力は両方ともfloat32浮動小数点数です)。
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_SET);
Vrefa = Modul_Factor * arm_sin_f32(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000) / 2 + 0.5;
Vrefb = Modul_Factor * arm_sin_f32(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000 + 2*PI/3) / 2 + 0.5;
Vrefc = Modul_Factor * arm_sin_f32(2*PI*b_SinWaveFreq*b_PwmPrdUpdateCnt/3000 - 2*PI/3) / 2 + 0.5;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_7, GPIO_PIN_RESET);
PE7の高レベル保持時間を引き続き観察します。結果は5usです。10倍の速度を最適化しました。