Site icon rpine lab Tech Blog

趣味のプログラミング(Web系・バックエンド)や自宅ラボ(Homelab)構築・マイコンを使った電子工作などを雑多に扱った技術ブログです。

🧰 格安RISC-VマイコンCH32V003をMounRiver Studio 2 (Ⅱ)で開発してみる

はじめに

秋月で40~50円で入手できる格安マイコンのCH32V003を使ったマイコン開発環境の構築とプログラミングをやっていきます。

最近アップデートされたVSCodeベースの新しい開発環境(MounRiver Studio Ⅱ)を使用し、実際にテスト回路を作ってデバッグやLチカをやってみたいと思います。

必要な機材

  • マイコン:CH32V003F4P6秋月:50円)
  • デバッガー:WCH-LinkE秋月
  • 変換基板:SSOP20(0.65mm)→DIP変換基板(秋月
  • その他部品
    • 積層セラミックコンデンサ 0.1 μF(パスコン用)
    • ジャンパーワイヤー
    • ブレッドボード
    • LED・電流制限抵抗

CH32V003マイコンの概要

CH32Vは中国のNanjing Qinheng Microelectronics社 (WCH)から発売されているRISC-Vマイコンです。その中でもCH32V003は安価に入手できるエントリーモデルになります。

CH32V003シリーズの特徴

  • コア: QingKe 32-bit RISC-V2A
  • 動作周波数: 最大 48 MHz (内蔵クロックを利用可能)
  • SRAM: 2 KB
  • Flash: 16 KB
  • タイマー: 2個
    • 16 bit高機能タイマー×1
    • 16 bit汎用タイマー×1
  • 主要ペリフェラル: ADC・I2C・SPI・UART

機能が豊富とまでは言えないものの基本的なペリフェラルは搭載されていて、32bitコアかつ48 MHzの動作周波数と、8bitマイコンと比べると高い性能を持っているので色々使い途がありそうです。

他にも上位のCH32V203シリーズなどがあり、そちらにはUSBやCANなどのペリフェラルがあります。

入手方法

秋月でチップがバラ売りされている他、AliExpressでまとめて購入すればより安く入手できます。

開発環境

RISC-V向けの汎用のGCCクロスコンパイラーが使えるので、公式の開発環境以外にも色々な開発手段があります。

今回は公式開発環境のMounRiver Studioを採用します。

このMounRiver Studioですが、最近MounRiver Studio Ⅱ (MRS2) がリリースされました。元々MRSはEclipseベースでWindowsのみの対応だったのですが、MRS2はVSCodeベースに一新されてWindows/macOS/Linuxのマルチプラットフォーム対応になっています。

今回はこの新しくなったMounRiver Studio 2を使って開発していって、その使用感も見ていきたいと思います。

WCH-LinkE(ライター・デバッガー)

WCH-LinkE(表)
WCH-LinkE(表)
WCH-LinkE(裏)
WCH-LinkE(裏)

マイコンへの書き込みに利用します。WCH-LinkEはデバッガーとしても使え、開発環境のデバッグ機能を利用してプログラムを実行しながら変数やレジスタの値などを直接確認することが可能です。また、UARTや3.3V/5V電源の供給機能も搭載しているので、これ1つでCH32Vマイコン開発が始められます。

マイコンへの接続は1-Wire Serial Debug Interface (SDI)方式を採用しており、マイコンのSWIOピンへの1線だけの接続で済みます。ARMマイコンのSWD方式(2線:SWDIO/SWCLK)と比べてよりシンプルになっています。

MounRiver Studio Ⅱのセットアップ

インストール

  1. MounRiverの公式サイトにアクセス
    (サーバーが強くないのかアクセス制限があるのか、サイトへのアクセスの際に↓の待機画面で待たされることがあります。その際はしばらく待ってからリロードしてみましょう。)
    MounRiverのサイトの読み込み待機画面
    MounRiverのサイトの読み込み待機画面
  2. MounRiver Studio Ⅱ(MRS2)のインストーラーをダウンロード
    MounRiver Studioのダウンロードページ
    MounRiver Studioのダウンロードページ
  3. インストーラーを実行し、指示に従いインストール

起動・VSCodeベースになった新しいMRS2を見てみる

デスクトップやスタートメニューのショートカットからMounRiver Studio Ⅱを起動します。ベースがEclipseからVSCodeに変わったおかげか、EclipseベースIDEでありがちなスプラッシュ画面で待たされるようなこともなく高速に起動します。

以下が起動した際の初期画面です。MRS2はVSCodeをベースとしてカスタマイズが加わっており、ノーマルのVSCodeと比較すると上側にツールボタンが追加されているなどの違いがあります。

MounRiver Studio Ⅱ 初期画面
MounRiver Studio Ⅱ 初期画面

右上にあるレイアウト切り替えボタンなんかはEclipseのPerspectiveの概念を持ち込んだ形でしょうか。

右上のボタン
右上のボタン

新規プロジェクトの作成

  1. 初期画面の「Create MounRiver Project」か、メニューのFile→New→MounRiver Projectをクリックしてプロジェクト作成画面を表示
  2. プロジェクト作成画面で以下のように設定
    • マイコン選択:CH32V003F4P6
    • Location:プロジェクトの保存先
    • Project Name:任意のプロジェクト名
    • Template Type:NoneOS(デフォルト)
    Image in a image block
  3. Createをクリックしてプロジェクトを作成
    Image in a image block

プロジェクトの初期設定

クロック設定

User/system_ch32v00x.cを開き、以下のようにクロック設定の定義をSYSCLK_FREQ_48MHZ_HSI(内部発振器HSI利用・システム周波数48 MHz)に変更します。

#define SYSCLK_FREQ_48MHZ_HSI   48000000 // コメントを外す(行頭の//を外す)
// #define SYSCLK_FREQ_48MHz_HSE   48000000 // コメントアウトする(行頭に//を付ける)
User/system_ch32v00x.cの変更点(クロック設定)

デバッグ設定 (SDI printf)

デバッグ中に便利な機能として、デバッガー経由で直接デバッグコンソールに文字出力できる機能であるSDI printf機能を有効化しておきます。(ドキュメントが見当たらないので正しい手順か不明)

  1. メニューのProject→Propertyを開く
  2. C/C++ Build→Build Settings→Tool Settings→GNU RISC-V Cross C Compiler→Preprocessorを開き、Defined symbolsにSDI_PRINT=SDI_PR_OPENを追加(必須じゃない?要検証)
    Image in a image block
  3. Download→Download Settingsを開き、Enable SDI Printfにチェック

    次にダウンロード(書き込み)を実施した際にSDI Printf機能が有効化されます。

    Image in a image block
  4. Debug→Debug Settings→Startupタブを開き、Enable Semihostingにチェック
    Image in a image block
  5. Applyボタンで設定を保存

    Closeボタンをクリックすると確認画面も出ずに設定が破棄されてしまうので注意してください。

テスト回路の制作

今回はマイコンとして秋月で50円で買えるCH32V003F4P6を使います。

このマイコンは表面実装パッケージ(SSOP20)となので、秋月に売っているDIP変換基板に実装してピンヘッダーでブレッドボードに差せる形に変換して使います。

また、一応パスコンとして電源ピンのVDD-VSS間に0.1 μFの積セラを変換基盤に直接追加します。

DIP変換基板に実装した
DIP変換基板に実装した

ブレッドボードに組む回路図は次のとおりです。

回路図(2025/3/22修正)
回路図(2025/3/22修正)
古い回路図(ピンの接続先に誤り)
テスト回路図(SWIOの接続先に誤り)
テスト回路図(SWIOの接続先に誤り)

マイコンのピンとその接続の対応表は次のとおりです。

ピン番号機能接続先用途
7VSSWCH-LinkE: GNDピンGND
9VDDWCH-LinkE: 3.3Vピン電源供給
11PC1 (GPIOピン)LED(緑)+抵抗Lチカ
18SWIOWCH-LinkE: SWDIOピンデバッグ通信

DIP変換基板に実装したマイコンを使ってブレッドボードに回路を組んで、WCH-LinkEと接続します。ブレッドボードの下側の黄色LEDは電源供給確認用、上側の緑色LEDは動作確認(Lチカ)用です。

ブレッドボードと全体の配線
ブレッドボードと全体の配線

動作確認

初期プログラムのチェック

User/main.cを開くと、main関数にサンプルプログラムが書かれています。まずはこのプログラムをそのまま実行してみることにします。USARTを使ったサンプルプログラムになっていますがそれは一旦無視して、デバッガーでprintfの出力を表示できるかだけ確認します。

初期プロジェクトのUser/main.c
初期プロジェクトのUser/main.c

プログラムのビルドと書き込み

  1. (初回のみ)WCH-LinkEをARMマイコンの開発モードからRISC-Vモードに変更

    プロジェクトのプロパティーからDownload→Download Settingsを選び、Debugger Target ModeをRISC-VにしてApplyボタンをクリックします。
    どこかの手順でWCH-LinkEのファームウェアのアップグレードが求められると思うので、その際はアップグレードしてください。

    Image in a image block
  2. 画面上部のツールアイコンの中からBuild Projectをクリックしてプログラムをビルド
  3. ツールアイコンの中からDownloadをクリックして、マイコンにプログラムを書き込む
    ⚠️
    Downloadボタンを押す前に、プログラムのビルドを必ず実行してください。自動ビルドは行われないため、場合によっては古いプログラムを書き込んでしまうことがあります。
  4. この時点で書き込んだプログラムが動作しているはずですが、USARTに何も繋げていないので動いているか分からないと思います。

デバッグ出力の確認

WCH-LinkEのデバッガー機能を利用してリアルタイムでデバッグを行います。

  1. ツールアイコンの中からStart Debugをクリックしてデバッグを開始

    初期設定ではスタートアップアセンブリの初期段階でプログラムが一時停止します。

    Image in a image block
  2. Continueボタンを押すとプログラムが実行されます。設定がうまく行ってれば図のように、下のDebug ConsoleにシステムクロックとチップIDが出力されているはずです。
    printf出力の確認
    printf出力の確認
    ⚠️
    printfの出力が出ない場合
    前述の「プロジェクトの初期設定」の設定項目を全て確認してください。クロックの設定も必須です。

Lチカ

マイコン最初のプログラムとして定番のLチカ(LEDの点滅)をやりたいと思います。今回の回路ではマイコンのPC1ピンにLEDを接続しています。

GPIOの初期化をする必要があるため、main.cのmain関数の上に次の関数を追加します。

void LED_Init() {
    // GPIOCにクロックを供給
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    // GPIO設定用構造体を用意
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // PC1を利用
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_30MHz; // 出力速度
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // プッシュプル出力モード
    // GPIOに設定を適用
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}
LED初期化関数

LEDの点灯・非点灯を制御する関数も作成します。

void LED_Write(BitAction BitVal) {
    GPIO_WriteBit(GPIOC, GPIO_Pin_1, BitVal);
}
LED制御関数

これらを使ってmain関数を書き換えてLチカプログラムを作成します。

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();

    // デバッグ出力 (SDI Printf)
    // デバッガーを使わない際は以下のブロックを全てコメントアウトする
#if (SDI_PRINT == SDI_PR_OPEN)
    SDI_Printf_Enable();
#else
    USART_Printf_Init(115200);
#endif
    printf("SystemClk:%d\r\n",SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );

    // GPIO初期化
    LED_Init();

    // メインループ
    while(1)
    {
        LED_Write(Bit_SET); // LED点灯
        Delay_Ms(500); // 500 ms待機
        LED_Write(Bit_RESET); // LED消灯
        Delay_Ms(500); // 500 ms待機
    }
}
Lチカプログラム main関数

デバッグして実行すると接続したLEDが0.5秒おきに点滅して無事Lチカができました。

Lチカの様子
Lチカの様子

まとめ

新しくリリースされたMounRiver Studio Ⅱを使い、CH32V003マイコンの開発環境構築から実際のLチカプログラムの実装までやってみました。VSCodeベースになったIDEの動作は高速で快適に開発できます。また、デバッグなどの高度な機能もきちんと利用することが可能です。今までのEclipseベースMRSをそこまで使ったことがないので細かい違いなどは分からないのですが、全体的に完成度は高いように思えます。

CH32V003マイコンは安い割には色々と活用できそうそうなので、このマイコンで色々作ってみたいと思います。

参考サイト