CH32V003覚え書き
CH340 などでおなじみの、WCH 製の RISC-V マイコンです。 2023 年の年頭から「10セントマイコン」と呼ばれて話題になっていたものです。 半年くらいいろいろ使ってみたので、軽くメモしておきます。
概要
超おおさっばに言うと、STM8S003F3 のガワに STM32 風の周辺機器をいれてコアを RISC-V にしたものです。 STM8S003F と物理的に置き換えが可能です。(ソフトは互換性ありません。) 周辺機能は STM32 とほぼ同等なので STM32 に慣れた人なら難なくつかえるかと思います。
良いところ
- 安い
秋月電子で SOP8 版が40円(TSOP20 版 50円)、Aliexpress で 50 個 800 円 (1100円) と激安です。(送料別) 2023 年現在、おそらく一番安価なフラッシュ書き換え可能マイコンの一つかと思われます。
- 速い
比較対象としては ATTiny シリーズになるかと思いますが、AVR が 20MHz なのに対して 48MHz の CPU を積んでるので速いです。 しかも外部クロック不要です。
- 5V で動く
STM8S003 とピン互換ということで、最近のマイコンとしては珍しく 5V 動作をサポートしています。
悪いところ
- 専用の書き込み機が必要
いくつかコミュニティ製の書き込み機が発表されていますが、基本的に専用の書き込み機がないとプログラムできません。 本体にはブートローダ用のフラッシュ領域もありますが、出荷時にはダミーしか書き込まれていません。
- スリープ時の消費電力が大きい
ATTiny202 など 1μA 未満のマイコンも珍しくない昨今、 CH32V003 は Standby モード(Stop モード)時の消費電力が 10μA ほどあります。 年単位で電池駆動するような用途には向かないかもしれません。
- 最低動作電圧が 2.7V
5V 動作に対応する代わりに、最低動作電圧が高めです。 ADC を使う場合はさらに高く 2.8V になります。 電源に NiMH 電池を使う場合、何らかの昇圧回路が必要になるでしょう。
- DIP 版がない
今どきの製品なので、DIP 版はありません。SOP8 くらいなら手はんだできますが、TSOP20 はちょっと厳しいです。
大さっぱにいうと ATTiny85 とか ATMega328p などの 8bit マイコンの代わりに使える製品かと思います。 今どき ATMega328p 高いですし… STM32 系マイコンを使った経験がある人はすぐに使えると思いますが、 そうでない人にはちょっとハードルが高いかもしれません。
入手
最近では秋月電子などで買うこともできますが、できれば Aliexpress の WCH 公式サイト から開発キットを入手することをお勧めします。 デバッガ+開発ボード+マイコン5個で約800円です。 ついでに CH32V203 開発キットも一緒に買うとさらにお得です。
開発環境
現状の開発環境は主に3つに分類されます。 フルに機能をつかうなら、公式 SDK を使うか ch32v003fun でレジスタを直接操作することになると思います。 自分は MounRiverStudio で公式 SDK を使っています。
- WCH公式SDK
公式 IDE の MounRiverStudio や Platform IO で使える、公式ライブラリです。 PlatformIO 用はコミュニティ製パッケージを使います。 STM32 の Standard Peripheral Library とよく似ています。
- Arduino
いくつか実装がありますが、WCH 公式 Arduino Core for CH32V が一番完成度が高いです。 公式 SDK を Arduino で包んだものになります。 ただし、CH32V003 の機能はすべてサポートされているわけではありません。 またフットプリントが大きいので、凝ったことに使うには向かないかもしれないです。
コミュニティ製の軽量ライブラリです。 素の CLI 環境向けでです。 フットプリントが小さい代わりに、レジスタを直接操作するような形になります。
Tips
- 浮動小数点
CH32V003 に乗っている RISC-V コア(RV32E)には浮動小数点演算がありません。 したがって、浮動小数点演算はエミュレートで実行されます。 浮動小数点ライブラリが 6KiB くらい消費するのでフラッシュの3分の1を占有してしまいます。 また、printf ライブラリは浮動小数点を無視するようになっています。
なので、小数が必要な場合でも整数化するなど、できるだけ浮動小数点を使わないようにすると良いと思います。
- メモリ
2KiB のメモリがありますが、割り込みベクタやスタック領域で 0.5KiB ほど使われているので、実際には 1.5KiB くらいしか使えません。
- SystemCoreClock
MounRiverStudio や Arduino では外部クロックを使う設定になっているので、
外部クロックを使わない環境でそのまま実行すると、クロックの設定が狂います。
system_ch32v00x.c
で適切なクロックの設定を行う必要があります。
- GPIO
いくつかの Pin はそのままでは GPIO として使えないようになっています。 詳しくは、 https://github.com/shippoiincho/tk80_ch32v003 を見てください。
- Bootloader
ブートローダ用に 1920B の領域が存在して、出荷時にはユーザプログラムに切り替えるダミーコードが書かれています。 公式 SDK の中にシリアル書き込み用のプログラムが存在し、それを書き込むとシリアルポート経由でプログラムの書き込みが可能になります。
ユーザプログラムとブートローダの切り替えは NRST ではできません。コードで明示的に切り替える必要があります。 または Power Off/On でブートローダから起動します。
- 書き込みができなくなったら
スリープモード中や、 SWIO で使用しているピンを他のことで使用していると、SWIO 経由の書き込みができなくなります。 特に PD1 とほかの機能でピンを共有している小ピン版で発生しやすいです。
その時はMRS のメニューの “Flash” → “Configuration” で “Erase code flash by POWER OFF” などを選択すると書き込みできるようになります。 WCH-Link Utility でも同様の操作を行うことができます。
これが可能なのは先ほどのブートローダの仕様で、電源オン時には必ずブートローダが起動するため、 SWIO 経由で操作する余裕が発生するためです。