前回までの小ピンでRISC-V搭載のマイコンCH32V003J4M6から、今回は唐突に小ピンでないArmコアマイコンSTM32へと飛びました。ようやく気付いたからです。WCHのCH32マイコンはST社のSTM32をリスペクト?するあまりHALレベルの関数がほぼほぼ互換にできているということに。STM32で予習したら楽?
Arduino環境だけれども。。。
本シリーズではArduino IDE環境で8ピンDIPの大変お求めやすいマイコン、CH32V003J4M6を使ってます。Arduino環境がお楽で人気なのは、何といってもマイコン制御するときに低レイヤのレジスタなどを意識することなく使えるということでしょう。本当はアチコチのレジスタを操作してようやくできる操作が関数一つ呼んでやるだけで動くと。どれだけ便利か。これに慣れると後戻りはできませぬなあ。
しかし、数回CH32V003のプログラムをArduino IDE上で書くうちに以下に気づきました。
-
- 御本家Arduino.ccのLanguage Reference掲載のAPI関数のうち実装されているのはサブセットである(サブセットでも使用できるのはコミュニティの方々のお陰です。感謝感激。)
- CH32のハードウエアがサポートしている機能でも、ArduinoレベルのAPI不在の場合は「HAL」レイヤ相当の関数を呼んでやる必要がある。HALレイヤ機能はハードウエア機能を網羅しているように見える。勿論、そのレベルのAPI関数もArduino環境の「スケッチ」から呼び出して使うことが可能。
そしてようやく気付いたのが
-
- CH32のHALレイヤ相当の関数群はST microelectronics製のArmコアマイコンSTM32のHALにクリソツ。
ということであります。なんだ、STM32のつもりで書けばよかったんだ。しかしです。さらにあることに気づきました。自分のせいね。
-
- STM32、結構お世話になっている気がするけれど、C/C++で書くときはいつもMbedOS環境でプログラムしていた。後はMicroPythonとか。
おおっと。全然HALレベルでプログラムなどしてませんでした。だってメンドイのだもの。それに御本家ST様のツールでも、何やらGUIを使ってHALレベルの関数は自動生成してくれたような。。。
ま、しかし、今回CH32Vのために、STM32のHALレベルのプログラミング(それもArduino IDEから)をやってみるべしと。これが自在に使えるようになった暁にはCH32Vなどお茶の子さいさいと。調子がいいな、ホントか?
手元のArduino IDE環境においてCH32VとSTM32のHAL相当のAPI群がどこにしまわれているのが調べたので書き留めておきます。
-
- CH32V
インストールパスの\Arduino15\packages\WCH\hardware\ch32v\1.0.3\system\CH32V00x\SRC\Peripheral\src
-
- STM32
インストールパスの\Arduino15\packages\STMicroelectronics\hardware\stm32\2.6.0\system\Drivers\STM32F0xx_HAL_Driver
なお、APIはほぼほぼ同等のものがそろっているように見えます(CH32Vの方が若干サブセットぎみ)が、関数名や引数などは「細かいところ」は異なります。たとえばTIMERの初期化であると、こんな感じ。
-
- STM32版HAL
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)
-
- CH32V版HAL
void TIM_TimeBaseInit(TIM_TypeDef *TIMx, TIM_TimeBaseInitTypeDef *TIM_TimeBaseInitStruct)
APIを眺めていると、STM32版のAPIで書いておけば、ほぼほぼ1対1対応で、CH32V版かけるんじゃないかという気がしてきました。ホントか?
しかし、もう一レイヤ、抜けとるのよ。。。
HALレベルで直接プログラムを書いておれば、1対1で済むのでありますが、今回使用しているのはArduino IDEの「スケッチ」ソース形式です。ぶっちゃけ、STM32用のプログラムを「スケッチ」環境で記述する場合、やっぱりArduinoのAPI関数全てが使えるわけではないのですが、かといって直接HALで書かねばならない、ということも無いのであります。
STM32のArduino環境の場合、HALレベルの階層とArduino APIの中間に
-
- ソースラッパ
などというレイヤが存在します。手元のArduino環境での在処を以下に記しておきます。
インストールパスの\Arduino15\packages\STMicroelectronics\hardware\stm32\2.6.0\libraries\SrcWrapper\src
この環境を使うと以下の「毟った」引用コード(オリジナルのコードはこちら)程度で端子へのPWM出力が可能です。HALレベルに比べたら随分お楽ね。
void setup() { TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM); uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM)); HardwareTimer *MyTim = new HardwareTimer(Instance); MyTim->setPWM(channel, pin, 5, 10); }
残念なことにCH32Vの場合、このような中間レイヤは存在しないようなので、直HALレベルで記述せんといかんような気がします。
次回はSTM32の上でソースラッパレイヤの上でハードを制御し、そこからゆるゆるとHALへと降りていきたいと思います。メンドイな。