STM32C5をSTM32CubeMX2とVS Codeで動かす
はじめに
この記事は、GPT-6 Astraに手伝ってもらいながら執筆しています。
今回、STM32ユニバーシティ・プログラムを通じて、STM32C5シリーズの開発ボード「NUCLEO-C542RC」やマイコンチップなどをご提供いただくことになりました。ありがとうございます。
しかし、STM32C5シリーズは従来のSTM32CubeMXには対応しておらず、周辺機能の設定やコード生成には、新しい「STM32CubeMX2」を使う必要があります。
従来のSTM32CubeMXとは生成されるコードの構成や開発環境のセットアップ方法も異なり、実際に動かすまでに戸惑う点がありました。そこで本記事では、STM32CubeMX2でのプロジェクト作成から、VS Codeでのビルド・デバッグ、ADCの読み取り、値の確認までを、実際に試した手順に沿って紹介します。
1. 使用するボード・ソフトウェア・部品
検証環境とバージョン
- OS:macOS 27.0.1(ビルド 26A434)
- STM32CubeMX2:1.1.2
- VS Code:1.143.1
- STM32CubeIDE for Visual Studio Code拡張:3.11.0
- CMake:4.0.1(ST配布バンドル:4.0.1+st.3)
- GCC:Arm GNU Toolchain 13.3.1(ST配布バンドル:13.3.1+st.9)
- HAL2:STM32C5xx HAL Drivers 2.1.0
NUCLEO-C542RCとST-Linkの接続
書き込み・デバッグには、下の写真で上側にあるST-LINK用USBポート(CN1)を使用します。
このポートは、ボードに搭載された書き込み・デバッグ用の「STLINK-V3EC」につながっています。PCとUSBケーブルで接続することで、プログラムの書き込みやデバッグができます。
写真の右上の電源選択ジャンパーJP1を「STLK」の位置(1–2番ピン)に設定すると、このUSBポートからボードへ電源も供給できます。(多分最初から刺さっているので、変更は不要だと思います)
一方、写真で下側にあるUSBポート(CN13)は、STM32側のUSB機能を使うためのポートです。ST-LINKには接続されていないため、本記事で説明するST-LINK経由の書き込み・デバッグには使用しません。こちらからの給電には、先ほどのJP1を挿し替えるなど別途電源設定の確認が必要です。
2. STM32CubeMX2の使い方
STM32CubeMX2のダウンロード/インストール
プロジェクト作成
起動したらこんな画面になってると思います。今回は「NUCLEO-C542RC」を使用するので、中央上の「Board」をクリックしましょう。

「NUCLEO-C542RC」を選択して、「Continue」を押してプロジェクト名や保存場所を選択すれば、プロジェクトの作成が完了します。

プロジェクトを開く
プロジェクトを開くと、このようなPinoutの画面に切り替わります。
この画面から、各ピンに役割を割り当てることができます。

3. ADCを設定してみる
今回はアナログ出力の気圧センサを読み取るため、ADC機能を有効化していきます。
PA0をADCの入力に割り当てる
ここからは、PA0に入力された電圧をADC1で読み取る設定をしていきます。
Pinout画面で「PA0」を選択し、右側の「Detail view」から「Pin signals」を開きます。「Analog signals」にある「ADC1_IN0」を選択します。
ADC1の設定画面を開く
左側の「Peripherals」から「Analog」→「ADC1」を開きます。まだ有効になっていない場合は「Peripheral Not Configured」と表示されるので、「Activate」を押します。すでに有効になっている場合は、そのまま設定を確認します。
Channel 0を有効にする
「Main features」の「Resolution」は「12 bit」、「Sampling mode」は「Normal」にします。
続いて「Channels」を開き、「Channel 0(ADC1_IN0)」の「Use channel」を有効にします。今回は「Sampling time」を「289 ADC clock cycles」、「Input mode」を「Single-ended」にしました。
今回の操作では、ADC1側でChannel 0を有効にするとPA0への割り当ても反映されました。Pinoutから設定した場合も、ADC1側のChannelが有効になっていることを確認しましょう。
RegularグループのSequencerにChannel 0を追加する
「Groups conversions」→「Regular」を開き、次のように設定します。
| 項目 | 今回の設定 |
|---|---|
| Use group | Enabled |
| Trigger type | Software start |
| Continuous mode | Single |
| Sequencer discontinuous | Disabled |
| Overrun | Data overwritten |
次に「Sequencer」の右側の「+」を押して項目を1つ追加し、「Sequencer 1」の「Channel」を「ADC1_IN0」にします。
CMake/GCCを選んでコードを生成する
「Project settings」を開き、「IDE Project Generation」でCMake/GCC向けの生成設定と出力先を確認し、「Generate IDE project」を押します。
今回、CubeMX2のプロジェクト名は test、生成先は test_cmake にしました。
生成後、出力先フォルダーに CMakeLists.txt、CMakePresets.json、main.c などが作成されていれば、コード生成は完了です😄
4. VS Codeをセットアップする
拡張機能を入れて生成先を開く
VS Codeの拡張機能から、STMicroelectronicsの「STM32CubeIDE for Visual Studio Code」をインストールします。
「ファイル」→「フォルダーを開く」で、先ほど生成したプロジェクトを開きます。
STM32Cubeのセットアップを実行する
macOSでは ⌘ + Shift + P、Windows/Linuxでは Ctrl + Shift + P でコマンドパレットを開き、次を実行します。
STM32Cube: Setup STM32Cube project(s)
対象のプロジェクトを選び、セットアップ画面でボード/デバイス、ツールチェーンなどを確認します。今回はNUCLEO-C542RC/STM32C542RCT6とGCCを使用します。設定が済んだら保存します。
5. ST-Linkでデバッグできるか確認する
デバッグ構成を作成してF5で起動する
ボードのST-LINK用USBポート(CN1)をPCへ接続します。
VS Codeの「実行とデバッグ」を開き、構成がない場合は構成の追加などから「STM32Cube: Launch ST-Link GDB Server」を選びます。
書き込みに成功し、実際にデバッグ用の画面に切り替わったら成功です😁
6. ADCをポーリング読み取りする
最小の読み取り例
今回は以下のプログラムを動かしました。
詳しい気圧センサの説明は省略しますが、とりあえず純粋に値を読み取ることを目的としたものになります。
#include "main.h"
#include "mx_adc1.h"
volatile uint32_t adc_raw = 0U; // ADCの生データ
volatile float adc_voltage = 0.0f; // PA0の電圧[V]
volatile hal_status_t adc_status = HAL_ERROR; // 最後の処理結果
int main(void)
{
if (mx_system_init() != SYSTEM_OK) { // 生成済みのシステム・周辺機能を初期化
while (1) {} // 初期化失敗時は停止
}
hal_adc_handle_t *hadc = mx_adc1_gethandle(); // ADC1ハンドルを取得
adc_status = HAL_ADC_Start(hadc); // ADCを有効化
if (adc_status != HAL_OK) {
while (1) {}
}
adc_status = HAL_ADC_Calibrate(hadc); // ADC内部のキャリブレ
if (adc_status != HAL_OK) {
while (1) {}
}
while (1) {
adc_status = HAL_ADC_REG_StartConv(hadc); // Regular変換を開始
if (adc_status != HAL_OK) {
while (1) {}
}
adc_status = HAL_ADC_REG_PollForConv(hadc, 10U); // 最大10ms待つ
if (adc_status == HAL_OK) {
adc_raw = (uint32_t)HAL_ADC_REG_ReadConversionData(hadc);
adc_voltage = (float)adc_raw * 3.3f / 4095.0f;
}
// タイムアウトした場合も停止処理を行う
hal_status_t stop_status = HAL_ADC_REG_StopConv(hadc);
if (adc_status == HAL_OK) {
adc_status = stop_status; // 元の待機エラーがあれば、その値を残す
}
if (adc_status != HAL_OK) {
while (1) {} // この例では自動再試行せず停止する
}
HAL_Delay(100U); // 読み取り後に100ms待つ
}
}
(3年前はAI生成されたHALライブラリのコードなんてまともに動かなかったのにHAL2でさえ一発で動いて若干恐怖している)
7. Live Watchで実行中の値を見る
通常のWatchは、主にブレークポイントなどで停止したときの値を確認する機能です。Live Watchでは、プログラムを動かしたまま変数を周期的に読み出せます。
launch.jsonのconfigurations内に以下の設定を加えることで利用できます。
"liveWatch": {
"enabled": true,
"samplesPerSecond": 4
// 毎秒4回更新
}
デバッグを開始し、「実行とデバッグ」内のLive Watchビューから式を追加して、変数を登録すれば常時値が更新されていきます(グローバル変数に限った気がする)。
いちいち処理を止めないでいいので便利ですね!
使用感
STM32CubeIDE(CubeMXが統合されていた頃)はEclipse(Javaベース)で動作していたため、挙動がやや重いと感じる場面も多くありました。しかし、STM32CubeMX2はWeb技術をベースに開発されており、実際に使ってみてもストレスを感じない、非常に快適な操作感でした!
ピン設定をGUI上で直接変更できることがSTM32CubeIDEを利用していた理由の一つでしたが、バージョン2.0以降、ピン設定などを行う機能がCubeMXとして完全に独立したため、これを機に開発環境を完全にVS Codeへ移行してみようかなと思います!
終わりに
楽しくロボコン
(RoDEPでは九工大で一緒にロボットを作るメンバーや支援して下さる方を募集しています!興味がある方はぜひ 公式X(旧Twitter) まで連絡をお願いします🙇)







