初心者向け stm32 microcontroller 入門ガイド

初心者向け STM32マイクロコントローラー 入門ガイド:詳細な解説:環境構築、Lチカ、ペリフェラル活用、そして次へ

ものづくりに興味があり、特に電子工作や組み込みシステムの世界に足を踏み入入れたいと考えている皆さん、ようこそ!本ガイドでは、高機能かつ汎用性の高いマイクロコントローラー、STM32を題材に、全くの初心者でもマイコン開発を始められるよう、環境構築から基本的なプログラミング、そして様々な機能(ペリフェラル)の使い方までを、約5000語というボリュームで徹底的に解説します。

はじめに:STM32とは何か? なぜSTM32を選ぶのか?

マイクロコントローラー(マイコン)とは、CPU、メモリ、入出力機能などが一つのチップに収められた小さなコンピューターです。家電製品、自動車、産業機器、おもちゃ、そして最近ではIoTデバイスなど、身の回りのあらゆるものに使われています。マイコンをプログラムすることで、これらの機器の動作を制御したり、外部の情報を読み取ったり、他の機器と通信したりといった様々なことが可能になります。

数あるマイコンの中でも、特に人気が高く、広く使われているのがSTMicroelectronics(ST)社が開発・製造するSTM32シリーズです。STM32は、高性能なArm Cortex-Mコアを搭載し、豊富なペリフェラル(周辺機能)を備えています。

では、なぜ初心者がSTM32を選ぶと良いのでしょうか?

  1. 豊富なラインナップと高性能: STM32は、シンプルな機能を持つものから、DSP(デジタル信号処理)機能やFPU(浮動小数点演算ユニット)を持つ高性能なものまで、非常に幅広いラインナップがあります。これにより、簡単な電子工作から複雑な制御システムまで、目的に合ったマイコンを選ぶことができます。
  2. 優れたエコシステム: STは、STM32開発を強力にサポートするためのツールやソフトウェア、ライブラリ、開発ボードなどを豊富に提供しています。特に、統合開発環境であるSTM32CubeIDEや、GUIベースで設定ができるSTM32CubeMXは、開発効率を大幅に向上させ、初心者のハードルを下げてくれます。
  3. 充実したドキュメントとコミュニティ: 公式の技術資料が非常に充実しており、また世界中の開発者がSTM32を使用しているため、オンラインフォーラムやコミュニティでの情報交換も活発です。困ったときに助けを得やすい環境があります。
  4. 開発ボードの入手容易性とお手頃価格: STM32を搭載した開発ボード(Nucleo、Discoveryなど)が多数販売されており、比較的安価に入手できます。特にNucleoシリーズは、Arduino UNOなど他の開発ボードとの互換性も考慮されており、電子工作の経験がある方にも馴染みやすいでしょう。
  5. 学習の継続性: STM32シリーズ内での互換性が高いため、一度開発環境や基本的な使い方を覚えれば、より高性能なSTM32にステップアップする際も、これまでの知識や経験を活かすことができます。

このように、STM32は高性能でありながら、開発環境が整っており、学習リソースも豊富にあるため、初心者にとってマイコン開発の入り口として非常に適しています。

本ガイドでは、STM32開発の第一歩として、開発環境の準備から、最も基本的な「Lチカ」(LEDを点滅させること)を通して開発の流れを掴み、さらにいくつかの重要なペリフェラルの使い方を学ぶことを目標とします。最終的には、本ガイドを足がかりに、ご自身のアイデアを形にするための基礎を築いていただければ幸いです。

1. STM32の基本

マイコン開発を始める前に、まずはマイコンがどのような構成になっているのか、そしてSTM32のシリーズについて簡単に理解しておきましょう。

1.1 マイクロコントローラーの構成要素

一般的なマイコンは、以下の主要な要素で構成されています。

  • CPU (Central Processing Unit): マイコンの中核であり、プログラムを実行する演算装置です。STM32の多くは、Arm Cortex-Mという高性能かつ低消費電力なコアをCPUとして採用しています。
  • メモリ (Memory):
    • フラッシュメモリ (Flash Memory): プログラム(ファームウェア)を記録しておくための不揮発性メモリです。電源を切っても内容が消えません。
    • SRAM (Static Random-Access Memory): プログラム実行中に使用されるデータ(変数など)を一時的に保存しておくための揮発性メモリです。電源を切ると内容が消えます。フラッシュメモリよりも高速にアクセスできます。
  • ペリフェラル (Peripherals): CPUが外部とやり取りしたり、特定の機能を実現したりするための周辺回路です。STM32は非常に豊富なペリフェラルを内蔵しています。代表的なペリフェラルには以下のようなものがあります。
    • GPIO (General Purpose Input/Output): マイコンのピンを汎用的な入出力として使うための機能です。LEDを点灯させたり、ボタンの状態を読み取ったりするのに使います。
    • UART (Universal Asynchronous Receiver/Transmitter): シリアル通信を行うための機能です。PCや他のマイコンとデータを送受信するのに使います。
    • SPI (Serial Peripheral Interface) / I2C (Inter-Integrated Circuit): デジタルセンサーや他のチップと高速または低速で通信するためのシリアル通信規格です。
    • ADC (Analog-to-Digital Converter): アナログ信号(電圧など)をデジタル値に変換するための機能です。温度センサーや光センサーなどのアナログセンサーの値を読み取るのに使います。
    • DAC (Digital-to-Analog Converter): デジタル値をアナログ信号に変換するための機能です。音声出力などに使われることがあります。
    • Timer (タイマー): 時間を計測したり、特定の周期で処理を実行したり、PWM(Pulse Width Modulation)信号を生成したりするための機能です。モーター制御やLEDの明るさ調整などに使われます。
    • DMA (Direct Memory Access): CPUを介さずに、ペリフェラルとメモリの間でデータを高速に転送するための機能です。大量のデータ転送が必要な場合にCPUの負荷を軽減します。
    • RTC (Real-Time Clock): マイコンがオフになっている間も時間を記録し続けるための機能です。

これらの構成要素が、一つの小さなチップの中に集積されています。

1.2 STM32シリーズの簡単な紹介

STM32シリーズは、搭載しているArm Cortex-Mコアの種類や周波数、内蔵メモリ容量、ペリフェラルの機能などによって、非常に細かく分類されています。初心者の方は、最初は以下の代表的なシリーズを知っておけば十分です。

  • STM32G0 / L0 / F0: Cortex-M0またはM0+コアを搭載した、比較的小規模で低コスト、低消費電力なシリーズです。簡単な制御やセンサー読み取りなどに適しています。
  • STM32F1: Cortex-M3コアを搭載した、普及帯のシリーズです。比較的安価な開発ボードも多く、入門用としてよく使われます。(ただし、やや古いシリーズです。)
  • STM32F3 / L3: Cortex-M4コアを搭載し、FPUやDSP命令に対応したシリーズです。信号処理などが可能です。L3は低消費電力版です。
  • STM32F4 / L4: Cortex-M4またはM4F(FPU付き)コアを搭載した、高性能なシリーズです。より高い周波数で動作し、豊富なペリフェラルを備えています。L4は低消費電力版です。現在最もよく使われるシリーズの一つです。
  • STM32F7 / H7: Cortex-M7コアを搭載した、非常に高性能なシリーズです。高い周波数で動作し、大容量メモリや高度なペリフェラルを備え、グラフィカルインターフェースなどにも対応できます。H7はさらに高性能です。

初心者のうちは、STM32F4シリーズまたはSTM32G4シリーズあたりから始めるのがおすすめです。これらのシリーズは性能と機能のバランスが良く、情報も豊富です。特にF4シリーズは、入門用の開発ボードが多数出ています。

1.3 開発ボードの種類

マイコンチップ単体では開発が難しいため、通常はブレッドボードなどで回路を組むか、あらかじめ必要な最小限の回路やデバッガーが搭載された「開発ボード」を使います。STM32にはいくつかの種類の開発ボードがあります。

  • Nucleo (ヌクレオ) ボード:
    • 最も初心者におすすめの開発ボードシリーズです。
    • 様々なSTM32マイコンを搭載したモデルがあります(例: Nucleo-F401RE, Nucleo-G431RBなど)。
    • USBケーブル一本でPCと接続し、給電、デバッグ、プログラム書き込みが可能です。
    • ST-LINK/V2-1というデバッガー/プログラマーがオンボードで搭載されています。
    • Arduino UNOのピン配置と互換性のあるコネクタ(Arduinoコネクタ)を備えているため、Arduino用のシールド(拡張ボード)を接続できるものもあります。
    • STM32の全ピンを引き出したST morphoコネクタも搭載しており、様々な外部回路を接続できます。
    • 比較的安価で入手しやすいです。
  • Discovery (ディスカバリー) キット:
    • 特定のSTM32シリーズや、オーディオ、ディスプレイ、センサーなど、特定のペリフェラルの機能を評価することに特化したボードです。
    • Nucleoよりも高機能なセンサーやモジュールが搭載されていることが多いですが、価格は高めになります。
    • 入門用としても使えますが、最初はNucleoの方がシンプルで扱いやすいかもしれません。
  • Evaluation (評価) ボード:
    • 特定のSTM32シリーズの全機能や性能を最大限に評価するために作られた、最も高機能で高価なボードです。
    • 多数のインターフェースや機能が搭載されており、製品開発のプロトタイピングなどに使われます。
    • 初心者にはオーバースペックで高価なので、最初は検討する必要はありません。

本ガイドでは、最も一般的で初心者向けのNucleoボード(特にNucleo-F4シリーズやNucleo-G4シリーズを想定)を前提に解説を進めます。

2. 開発環境の準備

STM32の開発を行うためには、PC上に専用のソフトウェア開発環境を構築する必要があります。STM32開発では、STMicroelectronicsが提供する無償のSTM32CubeIDEを使用するのが最も一般的で推奨されています。

2.1 必要なもの

  • PC: Windows, macOS, または Linux オペレーティングシステムが動作するもの。それなりの処理能力と空き容量が必要です。
  • STM32開発ボード: 本ガイドではNucleoボードを推奨します。
  • USBケーブル (Type A to Mini-B または Micro-B): 開発ボードとPCを接続するために必要です。ボードによってコネクタの形状が異なりますので確認してください。
  • インターネット接続: 開発環境のダウンロードやインストール、情報収集に必要です。

2.2 開発ツールチェーンの紹介

マイコンのプログラムは通常C言語やC++言語で書かれます。書いたプログラムをマイコンが理解できる機械語に変換し、マイコンに書き込むためには、いくつかのツールが必要です。これらをまとめて「ツールチェーン」と呼びます。

STM32開発のツールチェーンは主に以下の要素から構成されます。

  • 統合開発環境 (IDE – Integrated Development Environment): プログラムの編集、ビルド(コンパイル・リンク)、デバッグ、書き込みといった開発作業を一元的に行うためのソフトウェアです。
  • コンパイラ (Compiler): C/C++などのソースコードをアセンブリ言語に変換します。
  • アセンブラ (Assembler): アセンブリ言語を機械語(オブジェクトコード)に変換します。
  • リンカー (Linker): オブジェクトコードやライブラリを結合し、実行可能なプログラムファイルを作成します。
  • デバッガー (Debugger): プログラムの実行を一時停止させたり、変数の値を確認したり、ステップ実行したりすることで、プログラムの誤り(バグ)を見つけて修正するためのツールです。
  • フラッシュプログラマー (Flash Programmer): 開発したプログラム(実行可能ファイル)をマイコンのフラッシュメモリに書き込むためのツールです。

かつてはこれらのツールを個別にインストールして設定する必要がありましたが、現在の主要なSTM32開発環境は、これらのツールが全て統合されたIDEとして提供されています。

代表的なSTM32向けIDEとしては、以下のものがあります。

  • STM32CubeIDE: STMicroelectronicsが提供する公式かつ無償のIDEです。Eclipseベースで、コンパイラ(GCC)、デバッガー、フラッシュプログラマー、そしてGUIでマイコン設定ができるSTM32CubeMXの機能が統合されています。現在、最も推奨される開発環境です。
  • Keil MDK-ARM: Arm社が提供する商用IDEです。高性能なコンパイラなどが特徴ですが、無償版はコードサイズに制限があります。
  • IAR Embedded Workbench for Arm: IAR Systems社が提供する商用IDEです。高性能なコンパイラやデバッガーが特徴ですが、高価です。

本ガイドでは、機能統合されており、無償で利用できるSTM32CubeIDEを使用します。

2.3 STM32CubeIDEのインストール方法

STM32CubeIDEは、STMicroelectronicsの公式ウェブサイトからダウンロードできます。

  1. ダウンロードページへアクセス: STMicroelectronicsのウェブサイト (www.st.com) にアクセスし、「STM32CubeIDE」と検索するか、開発ツール > ソフトウェア開発ツール > 組み込み開発ツール > STM32CubeIDE のページへ移動します。
  2. OSに合わせたバージョンを選択: ご使用のPCのOS(Windows, macOS, Linux)に合わせたダウンロードリンクをクリックします。通常は、最新バージョンを選べば問題ありません。
  3. ユーザー登録/ログイン: ダウンロードには、STのウェブサイトへのユーザー登録(無償)とログインが必要です。アカウントをお持ちでない場合は、「Register Now」から登録してください。
  4. ダウンロードと実行: ダウンロードしたインストーラーを実行します。
    • Windows: ダウンロードした.exeファイルを実行します。インストーラーの指示に従って進めます。インストール先フォルダやスタートメニューフォルダなどを選択します。特にこだわりがなければデフォルトのままで構いません。インストールには管理者権限が必要です。ST-LINKドライバーも同時にインストールするオプションがある場合は、必ずチェックを入れてインストールしてください。
    • macOS: ダウンロードした.dmgファイルを開き、インストーラーパッケージを実行します。指示に従って進めます。アプリケーションフォルダへのインストールが一般的です。
    • Linux: ダウンロードした.zipまたは.shファイルを使用します。.shファイルの場合は、ターミナルで実行権限を与えて実行します(chmod +x your_installer.sh -> ./your_installer.sh)。zipファイルの場合は展開後、readmeファイルに従ってインストールを行います。

インストールが完了したら、STM32CubeIDEを起動してみましょう。初回起動時には、作業スペース(Workspace)の場所を指定するダイアログが表示されます。これはプロジェクトファイルなどが保存されるフォルダです。任意の場所を指定し、OKをクリックします。

2.4 STM32CubeMXとは何か?

先ほど少し触れましたが、STM32CubeMXは、STM32マイコンの初期設定をGUI(グラフィカルユーザーインターフェース)で行うためのツールです。STM32は非常に多くのピンとペリフェラルを持っており、手作業でレジスタを設定して初期化するのは大変な労力と専門知識が必要です。

STM32CubeMXを使うと、以下のことが簡単に行えます。

  • ピン配置の設定: マイコンの各ピンを、GPIO入力/出力、特定のペリフェラルの機能(UARTのTX/RX、SPIのMOSI/MISO/SCK、ADC入力など)として割り当てます。
  • ペリフェラルの設定: UARTのボーレート、タイマーの周期、ADCのサンプリングレートなど、各ペリフェラルの詳細な動作パラメータを設定します。
  • クロック設定: マイコン全体の動作周波数や、各ペリフェラルに供給するクロックの周波数を設定します。
  • 電源管理設定: 低消費電力モードなどの設定を行います。
  • コード生成: 設定した内容に基づいて、マイコンを初期化するためのCコード(HALライブラリまたはLLライブラリを使用したコード)を自動生成します。

この自動生成されたコードを、自分で書くアプリケーションコードと組み合わせることで、開発効率が大幅に向上します。STM32CubeIDEにはこのSTM32CubeMXの機能が統合されているため、IDE内でシームレスに設定からコーディングまでを行うことができます。

2.5 STM32CubeIDEとCubeMXの関係

STM32CubeIDEは、文字通りSTM32CubeMXの機能を「IDEの中に統合」しています。

  • プロジェクト作成時に、マイコンや開発ボードを選択すると、自動的にSTM32CubeMXのグラフィカル設定画面が開きます。
  • 設定画面上でピン配置やペリフェラル設定、クロック設定などを行います。
  • 設定が完了したら、「コード生成」ボタンをクリックすると、IDEがプロジェクト内に初期化コードを生成します。
  • 生成されたコードは、IDEのコードエディタで開き、ユーザーが書くアプリケーションコードを追加・編集します。
  • 後から設定を変更したい場合も、IDE上からいつでもSTM32CubeMXの設定画面に戻り、再設定してコードを再生成できます。この際、ユーザーが追記したコードは特定のコメントブロック内に書かれていれば、自動的にマージされます。

このように、STM32CubeIDEを使えば、ツールを切り替えることなく、初期設定からコーディング、デバッグ、書き込みまで、全ての開発ステップを一つの環境で行うことができます。

3. 最初のプロジェクトを作成する:Lチカに挑戦!

開発環境の準備ができたので、いよいよ最初のプロジェクトを作成し、STM32を動かしてみましょう。組み込みシステム開発の「Hello World」にあたる、LEDを点滅させる通称「Lチカ」を行います。

使用するボードはNucleoボード(例: Nucleo-F401RE)を想定します。多くのNucleoボードには、ユーザーが自由に制御できるLEDが搭載されています。Nucleo-F401REの場合、LD2という緑色のLEDがPA5ピンに接続されています。今回はこのLEDを点滅させます。

3.1 プロジェクト作成ウィザードの使い方

  1. STM32CubeIDEを起動: インストールしたSTM32CubeIDEを起動します。
  2. 新しいプロジェクトの作成:
    • メニューバーから File > New > STM32 Project を選択します。
    • または、ウェルカム画面が表示されている場合は、「Start new STM32 project」をクリックします。
  3. ターゲットセレクタ:
    • 「Target Selection」ウィンドウが開きます。ここで使用するマイコンや開発ボードを選択します。
    • ボードを使用する場合は、「Board Selector」タブを選択し、Filter by Commercial Part Numberにボード名(例: Nucleo-F401RE)を入力して検索します。表示されたボードを選択し、「Next >」をクリックします。
    • 特定のマイコンチップを使用する場合は、「MCU Selector」タブを選択し、Part Numberにマイコン名(例: STM32F401RETx)を入力して検索・選択します。
    • 今回はボードを選択する方法が簡単です。ボードを選択したら、「Next >」をクリックします。
  4. プロジェクト設定:
    • 「Project Name」にプロジェクト名を入力します(例: MyFirstBlinky)。
    • 「Project Location」はデフォルトのWorkspace内で構いません。
    • 「Targeted Project Type」は「STM32Cube」を選択します。
    • その他の設定はデフォルトのままで構いません。
    • 「Finish」をクリックします。
  5. 初期化確認:
    • 新しいプロジェクトを作成すると、「Initialize all peripherals with their default Mode?」というダイアログが表示されることがあります。「Yes」を選択します。これは、STM32CubeMXがボードのデフォルト設定(デバッガーやクロック設定など)をロードするか尋ねています。
    • STM32CubeMXのグラフィカル設定画面が表示されるまで待ちます。

3.2 ピン配置の設定 (GPIO)

STM32CubeMXの設定画面が開くと、マイコンのピン配置図(Pinout & Configurationタブ)が表示されます。

  1. LEDピンの確認: Nucleo-F401REの場合、LD2 LEDはPA5ピンに接続されています。ピン配置図上で、PA5とラベル付けされたピンを探します。
  2. ピン機能の設定: PA5ピンをクリックします。ドロップダウンメニューが表示され、そのピンに割り当て可能な機能の一覧が表示されます。LEDを点灯/消灯させるには、このピンを汎用出力(GPIO Output)として設定する必要があります。リストから GPIO_Output を選択します。
    • ピンの色が緑色に変わり、設定が完了したことを示します。
  3. GPIO設定の詳細: 左側のカテゴリツリーから System Core > GPIO を選択します。
    • 右側にGPIOの設定画面が表示されます。Pin Settingsタブを選択し、PA5ピンの設定を確認します。
    • GPIO output levelLow (デフォルトで消灯) でOKです。
    • GPIO modeOutput Push Pull (デフォルト) でOKです。
    • GPIO Pull-up/Pull-downNo Pull-up, no Pull-down (デフォルト) でOKです。
    • User Label には、コード中でピンを識別しやすい名前を付けることができます。ここでは分かりやすく LED_LD2 と入力しておきましょう。

これで、PA5ピンがLED点灯/消灯用の出力ピンとして設定されました。

3.3 クロック設定

次に、マイコンの心臓部であるクロックの設定を行います。STM32CubeMXの「Clock Configuration」タブをクリックします。

Nucleoボードを使用している場合、外部水晶発振子(HSE)や内部発振子(HSI)を使った最適なクロック設定が既にロードされていることが多いです。通常、初心者であればデフォルト設定のままで問題ありません。STM32CubeMXは、設定可能なクロック周波数や、各ペリフェラルに供給されるクロック周波数を示してくれます。マイコンの最大動作周波数に近い設定になっていることを確認しておきましょう。

3.4 コード生成

ピン配置とクロックの設定が完了したら、設定に基づいた初期化コードを生成します。

  1. コード生成の実行:
    • STM32CubeMX設定画面の上部にある「Generate Code」ボタン(歯車のアイコン)をクリックします。
    • または、メニューバーから Project > Generate Code を選択します。
  2. 生成完了を待つ: コード生成が開始され、進捗が表示されます。完了すると、STM32CubeMXの設定画面が閉じ、IDEのソースコードエディタが表示されます。

これで、初期化コードが自動生成され、開発の準備が整いました。

3.5 生成されたコードの構造解説 (main.c)

自動生成されたコードは、プロジェクトフォルダ内のCore > Src > main.cファイルに保存されています。このファイルが、マイコンの起動時に最初に実行されるプログラムの入り口となります。

main.cファイルを開いて、その構造を見てみましょう。

“`c
/ Includes ——————————————————————/

include “main.h” // プロジェクト固有の定義などを含むヘッダーファイル

/ Private includes ———————————————————-/
/ USER CODE BEGIN Includes /
// ここに自分で追加したいインクルードファイルを記述できます
/ USER CODE END Includes /

/ Private typedef ———————————————————–/
/ USER CODE BEGIN PTD /
// ここに自分で定義したい型などを記述できます
/ USER CODE END PTD /

/ Private define ————————————————————/
/ USER CODE BEGIN PD /
// ここに自分で定義したいマクロ定数などを記述できます
/ USER CODE END PD /

/ Private macro ————————————————————-/
/ USER CODE BEGIN PM /
// ここに自分で定義したいマクロ関数などを記述できます
/ USER CODE END PM /

/ Private variables ———————————————————/
/ USER CODE BEGIN PV /
// ここに自分で定義したいグローバル変数や静的変数などを記述できます
/ USER CODE END PV /

/ Private function prototypes ———————————————–/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
// 他に設定したペリフェラルがあれば、それぞれの初期化関数がプロトタイプ宣言されます

/ USER CODE BEGIN PFP /
// ここに自分で定義したい関数のプロトタイプ宣言を記述できます
/ USER CODE END PFP /

/ Private user code ———————————————————/
/ USER CODE BEGIN 0 /
// ここに初期化処理の前に実行したいコードなどを記述できます
/ USER CODE END 0 /

/
* @brief The application entry point.
* @retval int
/
int main(void)
{
/
USER CODE BEGIN 1 /
// ここに初期化処理の前に実行したいコードなどを記述できます (別の場所)
/
USER CODE END 1 */

/ MCU Configuration——————————————————–/

/ Reset of all peripherals, Initializes the Flash interface and the Systick. /
HAL_Init(); // HALライブラリの初期化

/ USER CODE BEGIN Init /
// ここにHAL_Init()の後、SystemClock_Config()の前に実行したいコードなどを記述できます
/ USER CODE END Init /

/ Configure the system clock /
SystemClock_Config(); // クロック設定

/ USER CODE BEGIN SysInit /
// ここにSystemClock_Config()の後、MX__Init()関数の前に実行したいコードなどを記述できます
/
USER CODE END SysInit */

/ Initialize all configured peripherals /
MX_GPIO_Init(); // GPIOの初期化
// 他に設定したペリフェラルがあれば、それぞれの初期化関数が呼び出されます

/ USER CODE BEGIN 2 /
// ここに全ての初期化処理が完了した後、メインループの前に実行したいコードなどを記述できます
/ USER CODE END 2 /

/ Infinite loop /
/ USER CODE BEGIN WHILE /
while (1)
{
/ USER CODE END WHILE /

/* USER CODE BEGIN 3 */
// ここにメインループ内で繰り返し実行したいコードを記述します

}
/ USER CODE END 3 /
}

/*
* @brief System Clock Configuration
* @retval None
/
void SystemClock_Config(void)
{
// クロック設定に関する詳細なコードが自動生成されています
// … (省略) …
}

/*
* @brief GPIO Initialization Function
* @param None
* @retval None
/
static void MX_GPIO_Init(void)
{
// 設定したGPIOピンの初期化に関する詳細なコードが自動生成されています
// … (省略) …
}

// 他に設定したペリフェラルの初期化関数が続きます
// … (省略) …

/ USER CODE BEGIN 4 /
// ここに自分で定義した関数を記述できます
/ USER CODE END 4 /

/
* @brief This function is executed in case of error occurrence.
* @retval None
/
void Error_Handler(void)
{
/
USER CODE BEGIN Error_Handler_Debug /
// エラーが発生した場合に実行される関数です。
// ここにLED点灯などのエラー通知処理を記述することが多いです。
while (1)
{
}
/
USER CODE END Error_Handler_Debug */
}

ifdef USE_FULL_ASSERT

// … (省略) …

endif / USE_FULL_ASSERT /

/*** (C) COPYRIGHT STMicroelectronics END OF FILE**/
“`

生成されたコードには、USER CODE BEGIN ...USER CODE END ... というコメントブロックが多数含まれています。これらのブロックの中に、自分で書くアプリケーションコードを記述します。 STM32CubeMXで設定を変更してコードを再生成した場合、これらのブロック内のコードは保持され、他の生成されたコードと適切にマージされます。これらのブロックの外にコードを書くと、再生成時に上書きされて消えてしまう可能性があるため注意が必要です。

重要なのは以下の部分です。

  • main関数: プログラムのエントリーポイント。
    • HAL_Init(): HALライブラリ(STが提供するハードウェア抽象化レイヤーのライブラリ)の初期化。必須です。
    • SystemClock_Config(): クロック設定。STM32CubeMXが生成した関数です。
    • MX_GPIO_Init(): GPIOの初期化。STM32CubeMXが生成した関数です。他のペリフェラルも同様に初期化関数が呼び出されます。
    • while(1)ループ: メインループ。マイコンのプログラムは通常、電源が入っている間はこの無限ループの中で繰り返し処理を実行します。Lチカの点滅処理はこの中に記述します。
  • SystemClock_Config() / MX_GPIO_Init() など: STM32CubeMXが生成した、具体的な初期化処理を行う関数です。内容は自動生成されるため、通常は直接編集しません。
  • Error_Handler(): プログラム実行中に何らかの致命的なエラーが発生した場合に呼び出される関数です。デバッグ用にここに処理を追加することがあります。

3.6 Lチカのプログラムコード記述

いよいよ、LEDを点滅させるコードをmain.cファイルのwhile(1)ループ内に記述します。

STM32CubeIDEで生成されたコードは、HAL (Hardware Abstraction Layer) ライブラリというものを使用しています。HALライブラリは、異なるSTM32シリーズ間での記述の差を吸収し、共通の関数名でペリフェラルを操作できるようにするものです。初心者には、レジスタを直接操作するよりもHALライブラリを使う方が簡単です。

Lチカに必要なHALライブラリの関数は以下の2つです。

  • HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); : 指定したGPIOピンの出力状態(HIGH/LOW)を反転させます。
  • HAL_Delay(uint32_t Delay); : 指定した時間(ミリ秒単位)だけプログラムの実行を一時停止(待機)させます。

PA5ピンの名前をSTM32CubeMXでLED_LD2と設定したので、この名前をコード中で使用できます。この名前はmain.hで定義されています。

main.cを開き、while(1)ループ内の/* USER CODE BEGIN 3 *//* USER CODE END 3 */ブロックの間に以下のコードを記述します。

“`c
/ Infinite loop /
/ USER CODE BEGIN WHILE /
while (1)
{
/ USER CODE END WHILE /

/ USER CODE BEGIN 3 /
HAL_GPIO_TogglePin(LED_LD2_GPIO_Port, LED_LD2_Pin); // LEDの状態を反転 (点灯 <-> 消灯)
HAL_Delay(500); // 500ミリ秒 (0.5秒) 待機
/ USER CODE END 3 /
}
“`

LED_LD2_GPIO_PortLED_LD2_Pin は、STM32CubeMXでピンに付けたユーザーラベル名(LED_LD2)に基づいて、生成されたコード(具体的にはmain.hファイル)で定義されるマクロ定数です。これらを使うことで、ピンの名前(PA5)を意識せずにコードを書くことができます。

このコードは、ループが実行されるたびにLEDの状態を反転させ、0.5秒待機するという処理を繰り返します。結果として、LEDが0.5秒間隔で点滅することになります。

3.7 ビルド(コンパイルとリンク)

コードを書き終えたら、マイコンが実行できる形式(機械語)に変換する「ビルド」という作業を行います。

  1. ビルドの実行:
    • ツールバーの「Build」ボタン(ハンマーのアイコン)をクリックします。
    • または、メニューバーから Project > Build Project を選択します。
  2. ビルドの監視:
    • IDE下部の「Console」ビューまたは「Build Console」ビューにビルドのログが表示されます。
    • コンパイルやリンクにエラーがなければ、最後に「Build Finished」のようなメッセージが表示され、ビルドが成功したことが示されます。
    • エラーが発生した場合は、「Problems」ビューにエラー内容と発生したコードの場所が表示されます。エラーメッセージをよく読んで、コードを修正し、再度ビルドしてください。

ビルドが成功すると、プロジェクトフォルダ内のDebugまたはReleaseフォルダ(デフォルトはDebug)に、実行可能ファイル(.elf.hexファイルなど)が生成されます。

3.8 デバッグと書き込み

ビルドが成功したら、生成されたプログラムを開発ボードのSTM32マイコンに書き込み(フラッシュし)、実行します。通常、この作業はデバッガー機能を使って行います。NucleoボードにはST-LINK/V2-1デバッガーが搭載されているため、USBケーブル一本でPCと接続するだけで書き込みとデバッグが可能です。

  1. 開発ボードの接続: NucleoボードとPCをUSBケーブルで接続します。Windowsの場合、自動的にドライバーがインストールされるか、以前インストールしたドライバーが使用されます。
  2. デバッグセッションの開始:
    • ツールバーの「Debug」ボタン(虫のアイコン)をクリックします。
    • または、メニューバーから Run > Debug を選択します。
  3. デバッグ設定 (初回のみ):
    • 初めてデバッグを開始する場合、「Edit Configuration」ダイアログが表示されることがあります。ここでは、どのデバッガー(ST-LINKなど)を使うか、どのマイコンに接続するかといった設定を行います。
    • 通常、STM32CubeIDEは自動的に接続されているST-LINKデバッガーを検出します。
    • 左側のリストからプロジェクト名を選択し、右側の「Debugger」タブを選択します。
    • 「ST-LINK (OpenOCD)」が選択されていることを確認します。
    • 「Show generator options」のチェックを外し、「Apply」をクリックし、「Debug」をクリックします。
  4. プログラムの書き込み: デバッグセッションが開始されると、ビルドされたプログラムが自動的にマイコンのフラッシュメモリに書き込まれます。
  5. デバッグパースペクティブへの切り替え: 書き込みが完了すると、IDEの表示が「Debugパースペクティブ」に切り替えるか尋ねられます。「Switch」をクリックして切り替えます。Debugパースペクティブでは、ソースコード表示、変数監視、レジスタ表示などのデバッグに便利なビューが表示されます。
  6. プログラムの実行: Debugパースペクティブに切り替わると、プログラムは通常、main関数の先頭や、リセットハンドラーで一時停止しています。
    • ツールバーの「Resume (F8)」ボタン(緑色の再生アイコン)をクリックすると、プログラムが実行されます。

3.9 実行確認

プログラムが実行されると、開発ボード上のLD2 LEDが0.5秒間隔で点滅するはずです。

点滅しない場合は、以下の点を確認してください。

  • USBケーブルは正しく接続されていますか?
  • 開発ボードに電源は供給されていますか?(USB接続されていればOK)
  • STM32CubeIDEのコンソールにエラーメッセージは出ていませんか?
  • ビルドは成功しましたか?
  • デバッグセッションは開始され、プログラムは書き込まれましたか?
  • デバッグパースペクティブでプログラムを実行(Resume)しましたか?
  • STM32CubeMXでPA5ピンは正しくGPIO_Outputに設定されましたか?ユーザーラベルは正確ですか?
  • コード中のHAL_GPIO_TogglePinHAL_Delay関数は正しく記述されていますか?(USER CODEブロック内か?)
  • 使用しているボードのLEDがPA5以外のピンに接続されていないか、ボードのマニュアルを確認してみてください。(NucleoボードならほとんどがPA5です)

Lチカが成功すれば、STM32マイコンにプログラムを書き込んで実行するという一連の基本的な開発ワークフローを体験したことになります。これは大きな一歩です!

4. STM32CubeIDEの主要機能

Lチカを通して基本的な開発フローを経験しましたが、STM32CubeIDEには開発効率を上げるための様々な機能があります。ここでは、特に重要なものをいくつか紹介します。

4.1 デバッガーの使い方

プログラムに予期せぬ動作があった場合、デバッガーを使って問題箇所を特定します。Debugパースペクティブには、デバッグをサポートする多くのビューがあります。

  • ブレークポイント (Breakpoint): プログラムの実行を一時停止させたい行に設定します。行番号の左側をダブルクリックすることで設定/解除できます。設定した行には青丸が表示されます。デバッグセッションを開始すると、プログラムは最初のブレークポイントで一時停止します。
  • 実行制御 (Execution Control): ツールバーのボタンでプログラムの実行を制御します。
    • Resume (F8): 次のブレークポイントまで、またはプログラム終了まで実行を継続します。
    • Suspend: プログラムの実行を一時停止します。
    • Terminate (Ctrl+F2): デバッグセッションを終了します。
    • Step Over (F6): 現在の行を実行し、次の行に進みます。関数呼び出しの場合は、関数全体を実行して関数の直後に進みます。
    • Step Into (F5): 現在の行を実行し、次の行に進みます。関数呼び出しの場合は、呼び出された関数の内部に入ります。
    • Step Return (F7): 現在の関数から抜け出し、呼び出し元の関数の次の行に進みます。
  • 変数監視 (Variables View): プログラム実行中にスコープ内にあるローカル変数やグローバル変数の現在の値を表示します。プログラムが一時停止しているときに値を確認できます。
  • 式監視 (Expressions View): 変数だけでなく、任意の式(例: counter > 10)の値をリアルタイムに監視できます。変数の値を変更することも可能です。
  • レジスタ表示 (Registers View): CPUのレジスタや、ペリフェラルの制御レジスタの値を表示します。ハードウェアの低レベルな状態を確認するのに役立ちます。
  • メモリ表示 (Memory View): メモリ上の特定のアドレスの内容を表示します。配列の内容などをダンプしたい場合に便利です。

デバッガーを効果的に使うことで、プログラムのバグを効率的に見つけることができます。Lチカの例で、HAL_Delay(500); の行にブレークポイントを設定し、プログラムを実行してブレークポイントで一時停止させてみてください。そして、Step Overで次の行に進み、Variablesビューで変数の変化を観察してみましょう(Lチカの例では単純なのであまり変化はないですが、他のプロジェクトでは重要になります)。

4.2 STM32CubeMXの再利用

一度STM32CubeIDEでプロジェクトを作成した後でも、いつでもSTM32CubeMXの設定画面に戻って設定を変更し、コードを再生成できます。

  • 設定画面の再表示: Project Explorerビューでプロジェクトを展開し、.iocという拡張子のファイル(プロジェクト名と同じ名前が多い)をダブルクリックします。
  • STM32CubeMXの設定画面が表示されます。ピン配置やペリフェラルの設定、クロック設定などを変更します。
  • 変更後、「Generate Code」ボタンをクリックすると、差分が自動的に生成されたコードに反映されます。USER CODEブロック内のコードは保持されます。

この機能があることで、開発の途中で新しいペリフェラルを使いたくなった場合でも、簡単に初期設定を追加できます。

4.3 プロジェクトエクスプローラーの解説

IDE左側の「Project Explorer」ビューは、プロジェクトのファイル構成を表示します。重要なフォルダやファイルは以下の通りです。

  • Core:
    • Inc: ヘッダーファイル(.hファイル)が格納されます。main.hや、STM32CubeMXが生成したペリフェラル初期化関連のヘッダーファイルなどがあります。
    • Src: ソースファイル(.cファイル)が格納されます。main.cの他に、STM32CubeMXが生成したペリフェラル初期化関連のソースファイルなどがあります。
  • Drivers:
    • CMSIS: Arm Cortex-Mコア用のハードウェア抽象化レイヤーであるCMSIS (Cortex Microcontroller Software Interface Standard) 関連のファイルが格納されます。
    • STM32Hxx_HAL_Driver (または使用しているシリーズ名): STM32 HALライブラリのソースコードが格納されています。必要に応じて中身を参照することもありますが、通常は直接編集しません。
  • Debug / Release: ビルド設定(デバッグ用かリリース用か)に応じた出力ファイル(実行可能ファイルなど)が格納されるフォルダです。
  • .iocファイル: STM32CubeMXの設定情報が保存されているファイルです。これをダブルクリックすると設定画面が開きます。

4.4 ビルド設定の解説

通常はデフォルトのビルド設定(Debug)で開発を進めます。ビルド設定を変更したい場合は、メニューバーから Project > Build Settings を選択するか、Project Explorerでプロジェクトを右クリックし Properties を選択し、C/C++ Build の項目を操作します。

ここで、コンパイラの最適化レベル(Debugビルドでは通常最適化は最小、Releaseビルドではサイズや速度の最適化を有効にする)、インクルードパス、ライブラリのリンク設定など、詳細なビルドオプションを設定できます。初心者の方は、最初はデフォルト設定のままで問題ありません。

5. ペリフェラルの活用 (GPIO以外)

LチカでGPIO(General Purpose Input/Output)の基本的な使い方を学びましたが、STM32の真価は内蔵された豊富なペリフェラルにあります。ここでは、GPIO以外のよく使われるいくつかのペリフェラルの使い方を、STM32CubeMXでの設定方法とHALライブラリを使った基本的なコード例と共に紹介します。

5.1 GPIO (より詳細に)

Lチカで使ったGPIOについて、もう少し詳細を見てみましょう。GPIOはマイコンのピンの機能を設定するためのもので、最も基本的なペリフェラルです。

  • 入出力モード: GPIOピンは、入力(Input)または出力(Output)として設定できます。
    • Input: 外部から電圧レベル(HIGH/LOW)を読み取ります。ボタンが押されたかどうかの判定などに使います。
    • Output: マイコンから電圧レベルを出力します。LEDを点灯させたり、他の回路をON/OFFしたりするのに使います。
  • 出力タイプ: 出力モードにはPush-PullOpen-Drainがあります。通常はPush-Pullを使用します。Open-Drainは、複数のデバイスで共通の信号線を制御する場合などに使われます(例: I2C通信)。
  • 入力タイプ: 入力モードにはFloating, Pull-up, Pull-downがあります。
    • Floating: ピンが外部回路に接続されていない場合に、電圧が不安定になることがあります。通常はプルアップまたはプルダウンと組み合わせて使います。
    • Pull-up: ピンを内部抵抗で常にHIGHレベルに保ちます。外部でピンをLOWに引っ張る回路(例: ボタンを押すとGNDに接続される回路)と組み合わせて使います。ボタンが押されていないときはHIGH、押されたときにLOWとして読み取れます。
    • Pull-down: ピンを内部抵抗で常にLOWレベルに保ちます。外部でピンをHIGHに引っ張る回路と組み合わせて使います。ボタンが押されていないときはLOW、押されたときにHIGHとして読み取れます。
  • 割り込み (External Interrupt): GPIOピンの状態変化(立ち上がりエッジ、立ち下がりエッジ、両方のエッジ、またはレベル)を検出して、CPUの実行を一時停止させ、特定の処理(割り込みハンドラー)を実行させることができます。ボタンが押された瞬間に何か処理をしたい場合などに便利です。

HALライブラリによるGPIO操作:

  • 入力: HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 関数で、指定したピンの現在の入力状態(GPIO_PIN_SET または GPIO_PIN_RESET)を読み取ります。
  • 出力: HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinState); 関数で、指定したピンの出力状態を HIGH (GPIO_PIN_SET) または LOW (GPIO_PIN_RESET) に設定します。Lチカで使ったHAL_GPIO_TogglePinは、これらを組み合わせた便利な関数です。

例: ボタンの状態を読んでLEDを制御する

Nucleoボードには、ユーザーボタン(Blue button, B1)が搭載されています。Nucleo-F401REの場合、このボタンはPC13ピンに接続されています。このピンを入力として設定し、ボタンが押されている間だけLEDを点灯させてみましょう。

  1. STM32CubeMXでPC13ピンを設定:
    • .iocファイルをダブルクリックして設定画面を開きます。
    • ピン配置図でPC13ピンを探し、クリックして GPIO_Input を選択します。
    • 左側のGPIO設定で、PC13のUser LabelをBUTTON_B1とします。
    • PC13のGPIO Pull-up/Pull-downPull-upに設定します。これにより、ボタンが押されていないときはPC13ピンはHIGHになります。ボタンが押されると、GNDに接続されてLOWになります。
    • コードを生成します。
  2. main.cにコードを記述:

    • main.cを開き、while(1)ループ内の/* USER CODE BEGIN 3 */ブロックに以下のコードを記述します。

    “`c
    / Infinite loop /
    / USER CODE BEGIN WHILE /
    while (1)
    {
    / USER CODE END WHILE /

    / USER CODE BEGIN 3 /
    // ボタンの状態を読み取る
    if (HAL_GPIO_ReadPin(BUTTON_B1_GPIO_Port, BUTTON_B1_Pin) == GPIO_PIN_RESET) // ボタンが押されているか? (Pull-upなのでLOWが押されている状態)
    {
    // ボタンが押されていたらLEDを点灯
    HAL_GPIO_WritePin(LED_LD2_GPIO_Port, LED_LD2_Pin, GPIO_PIN_SET);
    }
    else
    {
    // ボタンが押されていなかったらLEDを消灯
    HAL_GPIO_WritePin(LED_LD2_GPIO_Port, LED_LD2_Pin, GPIO_PIN_RESET);
    }
    / USER CODE END 3 /
    }
    “`
    3. ビルドして書き込む: ビルドして開発ボードにプログラムを書き込みます。ボタンを押している間だけ緑色のLEDが点灯することを確認してください。

5.2 UART (シリアル通信)

UART(Universal Asynchronous Receiver/Transmitter)は、マイコンとPCや他のデバイス間でデータを送受信するための一般的なシリアル通信ペリフェラルです。デバッグ情報の出力や、GPSモジュール、Bluetoothモジュールなどの外部デバイスとの通信によく使われます。

シリアル通信では、データはビット単位で直列に送られます。通信の速度を示すのがボーレート (Baud Rate) です(ビット/秒)。送信側と受信側でボーレートやデータ形式(データビット数、パリティビット、ストップビット)を合わせる必要があります。

Nucleoボードには、PCとの間で仮想的なUART通信を行うための機能(ST-LINKのVCP – Virtual COM Port機能)が搭載されていることが多く、これを利用してPCのターミナルソフトと通信できます。Nucleo-F401REの場合、通常PA2 (USART2_TX) と PA3 (USART2_RX) ピンがST-LINKのVCPに接続されています。

STM32CubeMXでのUART設定 (USART2を使用する例):

  1. .iocファイルを開く: STM32CubeMX設定画面を開きます。
  2. USART2を有効化: 左側のカテゴリツリーから Connectivity > USART2 を選択します。
  3. Mode設定: Mode ドロップダウンから Asynchronous を選択します。これにより、USART2が非同期シリアル通信モード(通常のUART通信)として有効になります。この設定を行うと、ピン配置図上のPA2とPA3ピンが自動的に緑色になり、それぞれUSART2_TXとUSART2_RXとして設定されます。
  4. Configuration設定: 右側の設定画面で、Parameters Settingsタブを開きます。
    • Baud Rate: 通信速度を設定します。一般的には 115200 bpsがよく使われます。
    • Word Length: 1フレームのデータ長を設定します。通常は 8 Bits (+ Parity if enabled) を選択します。
    • Parity: パリティチェックを行うかどうかを設定します。通常は None を選択します。
    • Stop Bits: ストップビット数を設定します。通常は 1 を選択します。
    • Data Direction: 送受信両方を行う場合は Both を選択します(デフォルト)。
  5. コードを生成: 設定を完了し、コードを生成します。main.cに関数プロトタイプMX_USART2_UART_Init(void);が、Core/Srcusart.cusart.hが生成されます。main関数内でMX_USART2_UART_Init();が呼び出されます。

HALライブラリによるUART送受信:

UART通信を行うためのHALライブラリ関数には、大きく分けてポーリング方式割り込み方式DMA方式があります。初心者は、シンプルで分かりやすいポーリング方式から始めるのがおすすめです。

  • 送信 (Polling): HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    • huart: 使用するUARTペリフェラルのハンドル構造体へのポインター(例: &huart2)。
    • pData: 送信するデータの先頭アドレス。
    • Size: 送信するデータのバイト数。
    • Timeout: 送信が完了するまでのタイムアウト時間(ミリ秒)。HAL_MAX_DELAYを指定すると無限待機します。
  • 受信 (Polling): HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);
    • 引数はHAL_UART_Transmitと同様です。
    • 指定したサイズのデータを受信するまで待機します。

例: PCのターミナルソフトにメッセージを送信する

  1. STM32CubeMX設定: 上記の手順でUSART2をボーレート115200で設定し、コードを生成します。
  2. main.cにコードを記述: while(1)ループ内の/* USER CODE BEGIN 3 */ブロックに以下のコードを記述します。

    “`c
    / Infinite loop /
    / USER CODE BEGIN WHILE /
    while (1)
    {
    / USER CODE END WHILE /

    / USER CODE BEGIN 3 /
    char msg[] = “Hello STM32!\r\n”; // 送信する文字列 (\r\nは改行コード)
    HAL_UART_Transmit(&huart2, (uint8_t)msg, strlen(msg), HAL_MAX_DELAY); // 文字列を送信
    HAL_Delay(1000); // 1秒待機
    /
    USER CODE END 3 /
    }
    ``
    *
    &huart2は、USART2ペリフェラルのハンドル構造体へのポインターです。この構造体はusart.cで定義され、MX_USART2_UART_Initで初期化されます。main.hでextern宣言されています。
    * 送信する文字列は
    uint8_t
    型にキャストする必要があります。
    *
    strlen(msg)で文字列の長さを取得します(string.hをインクルードする必要があります。/ USER CODE BEGIN Includes /ブロックに#include を追加してください)。
    *
    HAL_MAX_DELAY`を指定すると、送信が完了するまで永久に待機します。
    3. ビルドして書き込む: ビルドしてプログラムを書き込みます。
    4. ターミナルソフトで確認: PCでTera TermやPuTTYなどのターミナルソフトを起動します。開発ボードが接続されているCOMポートを選択し、通信設定をボーレート115200、データビット8、パリティNone、ストップビット1に設定します。接続すると、1秒おきに「Hello STM32!」というメッセージが表示されるはずです。

5.3 タイマー

タイマーは、特定の時間間隔でイベントを発生させたり、周期的な信号を生成したり、外部信号の時間を計測したりするためのペリフェラルです。非常に多機能で、様々な用途に使われます。

STM32のタイマーにはいくつか種類がありますが、基本的な考え方は共通です。タイマーは、入力されたクロックをカウントするカウンタを持っています。

  • 基本タイマー: シンプルな機能(時間計測、周期割り込み)のみを持つタイマーです。
  • 汎用タイマー: 基本タイマーの機能に加え、PWM出力、入力キャプチャ、出力コンペアなどの機能を持つタイマーです。
  • 高度制御タイマー: モーター制御などの高度な用途に必要な複雑な機能を持つタイマーです。

STM32CubeMXでのタイマー設定 (汎用タイマーTIM3を使用する例):

ここでは、汎用タイマーTIM3を使って、特定の周期で割り込みを発生させる設定を例に説明します。これは、定期的にセンサー値を読み取るなど、周期的な処理を行いたい場合に便利です。

  1. .iocファイルを開く: STM32CubeMX設定画面を開きます。
  2. TIM3を有効化: 左側のカテゴリツリーから Timers > TIM3 を選択します。
  3. Mode設定: Clock SourceInternal Clock に、ModeInternal Clock に設定します。
  4. Configuration設定:
    • Parameter Settings タブで、カウンタの動作を設定します。重要なパラメータは以下の2つです。
      • Prescaler (PSC - 1): カウンタのクロックを分周する値です。タイマーの入力クロック周波数をPrescaler+1で割った値が、カウンタが1カウント進むときの周期になります。
      • Counter Period (ARR - 1): カウンタがこの値まで達すると、カウンタがリセットされるか、カウント方向が反転します。周期モードの場合、この値までカウントすると割り込みが発生し、カウンタがリセットされます。
    • タイマーの周期 (秒) = (Prescaler + 1) * (Counter Period + 1) / タイマー入力クロック周波数 (Hz)
    • 例として、タイマー入力クロックが84MHzで、100ミリ秒 (0.1秒) ごとに割り込みを発生させたい場合。
      • 周期 = 0.1秒
      • 0.1 = (PSC + 1) * (ARR + 1) / 84,000,000
      • (PSC + 1) * (ARR + 1) = 8,400,000
      • 例えば、PSC = 8399 (Prescaler+1 = 8400), ARR = 999 (Counter Period+1 = 1000) と設定すると、8400 * 1000 = 8,400,000 となり、周期は0.1秒になります。
      • Prescaler (PSC - 1) に 8399 を設定します。
      • Counter Period (ARR - 1) に 999 を設定します。
    • NVIC Settings タブで、タイマーの割り込みを有効化します。TIM3 global interrupt の Enabled チェックボックスにチェックを入れます。
  5. コードを生成: 設定を完了し、コードを生成します。main.cに関数プロトタイプMX_TIM3_Init(void);が、Core/Srctim.ctim.hが生成されます。main関数内でMX_TIM3_Init();が呼び出されます。

HALライブラリによるタイマー割り込み:

周期的な処理は、タイマー割り込み機能を使って実現するのが一般的です。

  1. タイマー割り込み開始: main.c/* USER CODE BEGIN 2 */ブロックなど、メインループに入る前に、タイマーのカウントを開始し、割り込みを有効にします。
    c
    /* USER CODE BEGIN 2 */
    HAL_TIM_Base_Start_IT(&htim3); // TIM3のカウントを開始し、割り込みを有効にする
    /* USER CODE END 2 */

    • &htim3は、TIM3ペリフェラルのハンドル構造体へのポインターです。
    • HAL_TIM_Base_Start_ITは、基本タイマー機能(この場合は周期割り込み)を開始する関数です。
  2. 割り込みコールバック関数: タイマーのカウンタが設定値に達して割り込みが発生すると、HALライブラリの共通のコールバック関数が呼び出されます。このコールバック関数の中で、具体的な周期処理を記述します。
    c
    /* USER CODE BEGIN 4 */
    // タイマーの周期割り込みが発生したときに呼び出されるコールバック関数
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    // TIM3からの割り込みか確認 (複数のタイマー割り込みを使う場合)
    if(htim->Instance == TIM3)
    {
    // ここに周期的に実行したい処理を記述
    HAL_GPIO_TogglePin(LED_LD2_GPIO_Port, LED_LD2_Pin); // 例: LEDを点滅させる
    }
    }
    /* USER CODE END 4 */

    • この関数はmain.c/* USER CODE BEGIN 4 */ブロックに記述します。
    • HAL_TIM_PeriodElapsedCallbackは、STM32 HALドライバのソースコード(stm32h7xx_hal_tim.cなど)で__weak属性付きで定義されているため、同じ名前でユーザーコード側で定義することで、割り込み発生時にユーザー定義の関数が呼び出されるようになります。
    • htim->Instance == TIM3 のチェックは、複数のタイマーで同じコールバック関数を使う場合に、どのタイマーからの割り込みかを判断するために必要です。TIM3のみを使う場合は省略しても構いませんが、書いておくとより安全です。

このコードをビルドして書き込むと、100ミリ秒ごとにLEDの状態が反転し、0.1秒間隔で点滅することになります。メインループ(while(1))は空のままでも、バックグラウンドでタイマー割り込みが発生して処理が実行されます。

5.4 ADC (アナログ-デジタル変換)

ADC(Analog-to-Digital Converter)は、外部からのアナログ電圧値を、マイコンが扱えるデジタル値に変換するためのペリフェラルです。温度センサー、光センサー、可変抵抗(ボリューム)など、アナログ信号を出力するセンサーの値を読み取るのに使われます。

ADCの性能は、分解能(アナログ値をいくつの段階で表現できるか、例: 12ビットADCなら0〜4095の4096段階)や変換速度などで表されます。

STM32CubeMXでのADC設定 (ADC1を使用する例):

Nucleoボードには、いくつかのピンがADC入力として使用可能です。例えば、Nucleo-F401REの場合、PA0, PA1, PC0などがADC1の入力として利用できます。ここではPA0ピンに接続されたアナログ信号を読み取る例を考えます。

  1. .iocファイルを開く: STM32CubeMX設定画面を開きます。
  2. ADC1を有効化: 左側のカテゴリツリーから Analog > ADC1 を選択します。
  3. Mode設定: ModeIndependent Mode に設定します。
  4. Configuration設定:
    • Parameter Settings タブを開きます。
    • Injected Conversion Mode, Regular Conversion Mode の項目があります。通常は、定期的に複数チャンネルを順番に変換する Regular Conversion Mode を使います。
    • Regular Conversion Mode の設定項目で、以下の点を確認または設定します。
      • Number of Conversions: 変換するチャンネル数。最初は1に設定します。
      • External Trigger Conversion Source: 外部トリガーを使用するかどうか。通常はDisable(ソフトウェアトリガー、つまりプログラムから変換開始を指示)に設定します。
      • Rank設定: どのピンを何番目に変換するかを設定します。Rank 1Channel ドロップダウンから Channel 0 (PA0) を選択します。
      • Sampling Time: 各チャンネルのアナログ信号をどのくらいの時間サンプリングするかを設定します。長いほどノイズの影響を受けにくくなりますが、変換時間は長くなります。最初はデフォルト値で問題ないことが多いです。
    • NVIC Settings タブで、必要に応じてADC割り込みを有効化します。(ここではポーリング方式を使うので割り込みは有効にしません)
  5. ピン配置: ピン配置図でPA0ピンが自動的に ADC1_IN0 として緑色に設定されていることを確認します。
  6. コードを生成: 設定を完了し、コードを生成します。main.cに関数プロトタイプMX_ADC1_Init(void);が、Core/Srcadc.cadc.hが生成されます。main関数内でMX_ADC1_Init();が呼び出されます。

HALライブラリによるADC変換:

ADC変換を行うためのHALライブラリ関数にも、ポーリング方式、割り込み方式、DMA方式があります。

  • ADC開始: HAL_ADC_Start(&hadc1); // ADC変換を開始(連続変換ではない場合は、変換ごとに呼び出す必要あり)
  • 変換完了待ち: HAL_ADC_PollForConversion(&hadc1, Timeout); // ADC変換が完了するまで待機(ポーリング)
  • 値取得: HAL_ADC_GetValue(&hadc1); // 変換結果(デジタル値)を取得

例: PA0ピンのアナログ電圧を読み取り、デジタル値として取得する

  1. STM32CubeMX設定: 上記の手順でADC1をPA0ピンに設定し、コードを生成します。
  2. main.cにコードを記述: while(1)ループ内の/* USER CODE BEGIN 3 */ブロックに以下のコードを記述します。

    “`c
    / Infinite loop /
    / USER CODE BEGIN WHILE /
    while (1)
    {
    / USER CODE END WHILE /

    / USER CODE BEGIN 3 /
    uint32_t adc_value;

    // ADC変換を開始
    HAL_ADC_Start(&hadc1);

    // 変換完了を待機 (ポーリング)
    if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)
    {
    // 変換結果を取得
    adc_value = HAL_ADC_GetValue(&hadc1);

    // 取得したadc_valueを使う処理 (例: UARTでPCに送信するなど)
    // printf("ADC Value: %lu\r\n", adc_value); // printfを使えるように設定すればこれも可能
    // 例: デジタル値に応じてLEDを点灯させる閾値を設けるなど
    if (adc_value > 2048) // 12ビットADCなら最大4095の約半分
    {
        HAL_GPIO_WritePin(LED_LD2_GPIO_Port, LED_LD2_Pin, GPIO_PIN_SET); // 明るければ点灯
    }
    else
    {
        HAL_GPIO_WritePin(LED_LD2_GPIO_Port, LED_LD2_Pin, GPIO_PIN_RESET); // 暗ければ消灯
    }
    

    }

    // ADCを停止 (ポーリングで単発変換の場合は停止した方が良い場合がある)
    HAL_ADC_Stop(&hadc1);

    HAL_Delay(100); // 100ミリ秒待機
    / USER CODE END 3 /
    }
    ``
    *
    &hadc1は、ADC1ペリフェラルのハンドル構造体へのポインターです。
    * この例では、PA0ピンに接続されたアナログ信号の電圧が高いか低いかでLEDを制御しています。
    * 実際のアプリケーションでは、取得したデジタル値を電圧値に換算したり、センサーの特性に合わせて物理量に変換したりします。
    * 連続的に変換を行いたい場合は、
    HAL_ADC_Startを一度呼び出し、ループ内でHAL_ADC_PollForConversionHAL_ADC_GetValue`を呼び出す、または連続変換モードやスキャンモード、DMA転送などを使用します。

このコードをビルドして書き込み、PA0ピンに可変抵抗などを接続して電圧を変化させてみると、LEDの点灯/消灯が変わることを確認できるはずです。(NucleoボードによってはPA0ピンに外部から簡単に接続できるピンヘッダーが出ています)

5.5 その他のペリフェラル (簡単紹介)

STM32には、上記以外にも様々なペリフェラルが搭載されています。ここでは名前と簡単な機能だけ紹介します。

  • SPI (Serial Peripheral Interface): 高速な同期式シリアル通信プロトコルです。SDカード、液晶ディスプレイ、センサーなどとの通信によく使われます。マスターとスレーブの関係で通信します。
  • I2C (Inter-Integrated Circuit): 比較的低速な同期式シリアル通信プロトコルです。多くの種類のセンサーやEEPROM、リアルタイムクロック(RTC)などとの通信に使われます。マスターとスレーブの関係で、複数のスレーブデバイスを同じバスに接続できます。
  • DMA (Direct Memory Access): CPUを介さずに、ペリフェラルとメモリの間で直接データを高速に転送する機能です。大量のデータ転送(例: ADCで連続的に大量の値を読み取る、UARTで長い文字列を送受信する)が必要な場合に、CPUの負荷を大幅に軽減できます。
  • RTC (Real-Time Clock): マイコンに電源が供給されていない状態でも、バックアップ電池などによって正確な時間を保持し続けるための機能です。カレンダー機能も持ちます。
  • Watchdog Timers: プログラムが無限ループに陥るなどして応答しなくなった場合に、マイコンを強制的にリセットするための安全機能です。システムの信頼性を向上させます。
  • CRC Calculation Unit: データの誤りを検出するためのCRC(Cyclic Redundancy Check)値を計算するためのハードウェアアクセラレーターです。
  • RNG (Random Number Generator): 乱数を生成するためのハードウェアモジュールです。暗号化などに使われます。
  • USB Controller: USB通信機能を実現するためのコントローラーです。USBデバイスやUSBホストとして振る舞うことができます。
  • CAN Controller: 自動車などで使われる通信プロトコルCAN (Controller Area Network) を扱うためのコントローラーです。
  • Ethernet Controller: イーサネット通信機能を実現するためのコントローラーです。(一部の高性能シリーズ)

これらのペリフェラルも、STM32CubeMXで設定し、HALライブラリを使ってプログラムから制御します。それぞれのペリフェラルにはさらに多くの設定項目や機能がありますが、まずはGPIO, UART, タイマー, ADCといった基本的なものから習得していくのが良いでしょう。

6. ソフトウェア開発のヒント

STM32のプログラミングを効率的かつ正確に行うためのヒントをいくつか紹介します。

6.1 HALライブラリとLLライブラリの違い

STM32CubeIDEでコードを生成する際、HALライブラリまたはLLライブラリのどちらを使用するか選択できます(デフォルトはHAL)。

  • HAL (Hardware Abstraction Layer) ライブラリ:
    • 異なるSTM32シリーズ間でのハードウェアの違いを抽象化し、共通の関数名でペリフェラルを操作できるようにしたライブラリです。
    • 関数名や使い方が直感的で分かりやすく、初心者でも比較的簡単にペリフェラルを使えます。
    • 欠点としては、抽象化の層があるため、レジスタを直接操作する場合に比べてわずかにオーバーヘッドがあり、実行速度やコードサイズに影響を与える可能性があります。
  • LL (Low-Layer) ライブラリ:
    • HALよりも低レベルなライブラリで、各ペリフェラルのレジスタに非常に近い操作を提供します。
    • ハードウェアの機能に直接アクセスするため、より高速で効率的なコードを作成できる可能性があります。
    • しかし、マイコンやペリフェラルの詳細なレジスタ構成を理解している必要があり、HALに比べて習得難易度が高いです。異なるシリーズ間で互換性がない場合が多いです。

初心者の方は、まずはHALライブラリを使うことを強くお勧めします。 ほとんどのアプリケーションではHALで十分な性能が得られます。より高度な性能や、特定のレジスタ設定が必要になった場合にLLライブラリを検討すれば良いでしょう。

6.2 HALライブラリの便利な関数

HALライブラリには、各ペリフェラルの基本的な初期化やデータ送受信だけでなく、様々な便利な関数が用意されています。ドキュメントを参照することで、目的に合った関数を見つけることができます。

例えば、タイマー関連の関数だけでも、PWM出力、入力キャプチャ、ワンパルスモードなど、多岐にわたります。UARTも、ポーリング以外に割り込みやDMAを使った送受信関数があります。これらの関数を使いこなすことで、より複雑な機能も効率的に実装できます。

6.3 エラーハンドリング

組み込みシステムでは、予期せぬエラーが発生した場合の対処が重要です。HALライブラリの多くの関数は、実行結果としてHAL_StatusTypeDefという列挙型を返します。この型にはHAL_OK(成功)、HAL_ERROR(エラー)、HAL_BUSY(ビジー)、HAL_TIMEOUT(タイムアウト)といった値があります。

関数の戻り値をチェックし、HAL_OK以外の場合はエラーが発生したと判断して、事前に定義しておいたError_Handler()関数を呼び出すようにします。

c
if (HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY) != HAL_OK)
{
Error_Handler(); // 送信に失敗したらエラーハンドラーを呼び出す
}

Error_Handler()関数の中には、例えばLEDを点滅させてエラーを視覚的に通知する、外部にエラーメッセージを出力する、といった処理を記述します。これにより、問題発生時に原因特定の手がかりを得やすくなります。

6.4 デバッグ手法

デバッガーは強力なツールですが、常にデバッガーを使えるとは限りません(例えば、デバッガーを接続できない製品版の基板など)。また、リアルタイム性を損なわずにデバッグしたい場合もあります。

  • printfデバッグ: プログラムの特定の箇所で、変数の値や処理の通過を示す文字列をUART経由でPCのターミナルに送信する方法です。シンプルですが、非破壊的にプログラムの動作を追跡するのに非常に有効です。STM32CubeIDEでUARTを有効化し、printf関数をUART送信にリダイレクトする設定を行うことで実現できます(設定方法は少し複雑なため、別途情報を探してみてください)。
  • GPIOによる状態表示: 特定の処理に入った/抜けた、条件が成立した、といった状態を、デバッグ用のLEDを点灯/消灯させたり、オシロスコープで波形を確認したりすることで確認する方法です。リアルタイム性が重要な処理のデバッグに有効です。

6.5 コードの可読性と保守性

初心者向けのガイドとしては少し先の内容かもしれませんが、規模が大きくなるにつれて重要になるのが、コードの可読性と保守性です。

  • 適切な変数名・関数名: 変数や関数が何を表しているか、何をするものか、一目で分かるような名前を付けましょう。
  • コメント: コードが何をしているのか、なぜそう書かれているのかなど、後から見た人が理解しやすいようにコメントを記述しましょう。特に複雑な処理や、トリッキーな実装には丁寧なコメントが必要です。
  • 関数の分割: 一つの関数に多くの処理を詰め込まず、機能ごとに小さな関数に分割しましょう。これにより、コードの見通しが良くなり、再利用性も高まります。
  • マジックナンバーを避ける: コード中に突然現れる数値(例: HAL_Delay(100);100)は、その意味が分かりにくい場合があります。これらの値には、意味が明確な定数名(例: #define BLINK_INTERVAL_MS 100)を付けましょう。

6.6 バージョン管理システム (Git) の活用

Gitのようなバージョン管理システムを使うと、コードの変更履歴を記録したり、いつでも過去の状態に戻したり、複数人で開発したりするのが容易になります。一人で開発する場合でも、変更履歴を管理し、バックアップを取るツールとして非常に有用です。

STM32CubeIDEはEGit(EclipseのGitプラグイン)を統合しており、IDE上でGit操作を行うことができます。最初からGitを使う習慣をつけておくと、後々の開発が楽になります。

7. より進んだトピックへの道しるべ

基本的なSTM32開発のフローといくつかのペリフェラルの使い方を学んだら、さらに様々なことに挑戦できます。ここでは、次に学ぶと良い応用的なトピックを紹介します。

  • 割り込み処理 (Interrupts): GPIO外部割り込み、タイマー割り込み、UART受信割り込みなど、様々なペリフェラルからの割り込みを処理する方法を深く理解することは、効率的な組み込みシステム開発に不可欠です。メインループでポーリングするのではなく、イベントが発生したときだけ特定の処理を実行することで、CPUリソースを有効活用できます。
  • DMA (Direct Memory Access): 大量のデータ転送が必要なUART通信やADC変換などでDMAを使うと、CPUの負荷を大幅に軽減できます。DMAの設定方法と、HALライブラリでの使い方を習得しましょう。
  • RTOS (Real-Time Operating System): 複数のタスク(異なる処理のまとまり)を同時に実行したい場合にRTOSを導入します。STM32CubeIDEはFreeRTOSというRTOSのポーティングをサポートしており、GUIで設定できます。RTOSを使うことで、複雑な処理を構造化し、システムの応答性を向上させることができます。
  • 低消費電力設計: バッテリー駆動のデバイスを開発する場合、マイコンの消費電力を抑えることが非常に重要です。STM32の様々な低消費電力モード(Sleep, Stop, Standbyなど)の使い方を習得し、電力消費を最適化する方法を学びましょう。
  • ブートローダー (Bootloader): マイコンが起動時に最初に実行するプログラムです。自分でカスタマイズしたブートローダーを作成することで、独自の書き込み方法(例えば、USBメモリからファームウェアをアップデートするなど)を実現できます。
  • ファイルシステム: SDカードや内蔵フラッシュメモリにファイルを保存・読み込みたい場合は、FATFSなどのファイルシステムライブラリを導入します。
  • 通信プロトコル: TCP/IP (Ethernet/Wi-Fi)、Bluetooth Low Energy (BLE) など、様々な通信プロトコルを実装することで、ネットワーク接続されたデバイスを開発できます。STはこれらのプロトコルスタックや関連ライブラリも提供しています。
  • モーター制御、PID制御: DCモーターやステッピングモーター、サーボモーターなどの制御方法、センサーからのフィードバックを使ったフィードバック制御(PID制御など)について学ぶと、ロボットや産業機器などの開発に応用できます。

これらのトピックはそれぞれ奥が深く、一つずつ習得していくことで、開発できるものの幅が大きく広がります。

8. よくある質問 (FAQ)

初心者の方がよく疑問に思うであろう質問とその回答をまとめました。

Q1: どのNucleoボードを選べば良いですか?

A1: 最初は、Nucleo-F401REやNucleo-F446RE、あるいは比較的新しいNucleo-G431RBなど、Cortex-M4コアを搭載したボードがおすすめです。これらは性能と機能のバランスが良く、情報も豊富です。価格も手頃です。開発したいものが決まっている場合は、その機能(例: 特定の通信インターフェースが必要など)に合わせてボードを選ぶと良いでしょう。迷ったら、入手しやすくて情報が多いNucleo-F401REを選んでおけば間違いないでしょう。

Q2: STM32CubeIDEでエラーが出ました。どうすれば良いですか?

A2: エラーには大きく分けて「コンパイルエラー」と「実行時エラー」があります。
* コンパイルエラー: コードの文法間違いなどにより、ビルドが完了しないエラーです。IDEの「Problems」ビューにエラーメッセージが表示されます。メッセージの内容(どのファイル、何行目、どんな種類のエラーか)をよく読み、エラーの原因となっているコードを修正してください。英語のエラーメッセージでも、重要なキーワードを頼りにインターネットで検索すると解決策が見つかることが多いです。
* 実行時エラー: プログラムはビルド・書き込みできたが、思った通りに動かない、または途中で停止するといったエラーです。これはデバッガーを使って原因を特定します。疑わしい箇所にブレークポイントを設定し、変数の値や実行の流れを追跡して問題を見つけます。Error_Handler関数に飛んでいないかも確認しましょう。

Q3: HALライブラリの関数がたくさんあって、どれを使えば良いか分かりません。

A3: 最初から全ての関数を覚える必要はありません。まずは、Lチカ(GPIO)、UART送受信、タイマー(遅延、周期処理)、ADC変換といった、必要になった機能に関連する基本的な関数から一つずつ覚えていきましょう。STM32CubeMXで設定したペリフェラルに対応する関数名(例: UARTならHAL_UART_...)を検索すると、関連関数が見つかりやすいです。HALライブラリのリファレンスマニュアル(STのウェブサイトからダウンロードできます)で関数の詳細な説明や引数を確認できます。最初はサンプルコードを参考にしながら進めるのが良いでしょう。

Q4: STM32CubeMXが生成するコードが多すぎて、どこに自分のコードを書けば良いか分かりません。

A4: ユーザーがコードを書くべき場所は、繰り返しになりますが/* USER CODE BEGIN ... *//* USER CODE END ... */のコメントブロック内です。特に、メインループの処理はmain関数内の/* USER CODE BEGIN 3 */ブロックに記述します。初期化後のワンタイム処理は/* USER CODE BEGIN 2 */に、自分で定義した関数は/* USER CODE BEGIN 4 */に書くのが一般的です。生成されたコードの大部分はペリフェラルの初期化設定なので、最初は中身を全て理解しようとせず、これらのUSER CODEブロックを探して、そこに自分のロジックを記述することに集中しましょう。

9. 学習リソース

STM32開発をさらに深く学ぶために役立つリソースを紹介します。

  • STMicroelectronics公式ウェブサイト (www.st.com):
    • データシート (Datasheet): 特定のマイコンチップの電気的特性、ピン配置、メモリマップなどの仕様が記載されています。
    • リファレンスマニュアル (Reference Manual): マイコンに内蔵されている各ペリフェラルの詳細な機能、レジスタ構成、動作モードなどが詳細に説明されています。非常に詳細ですが、必ず参照することになる重要なドキュメントです。
    • アプリケーションノート (Application Note): 特定の機能(例: PWM制御、ADCのDMA転送など)や用途に特化した実装例や解説が記載されています。具体的なコード例も含まれていることが多く、非常に参考になります。
    • HAL/LLドライバ リファレンスマニュアル: HAL/LLライブラリの各関数の使い方や引数、戻り値などが詳細に説明されています。
    • ST Community / フォーラム: 世界中のSTM開発者が質問したり情報交換したりしています。困ったときに検索したり、質問したりするのに役立ちます。
  • 書籍: STM32や組み込みシステム開発に関する多くの書籍が出版されています。日本語で体系的に学びたい場合に役立ちます。
  • オンラインチュートリアル/コース: YouTubeやUdemyなどのプラットフォームで、STM32開発に関する動画チュートリアルやオンラインコースが多数提供されています。実際に開発環境を操作しながら学ぶのに適しています。
  • GitHubなどのコードリポジトリ: 他の開発者が公開しているSTM32プロジェクトのソースコードを参考にすることで、具体的な実装方法を学ぶことができます。

最初は公式ドキュメントは難しく感じるかもしれませんが、開発を進める上で必ず参照することになります。まずはアプリケーションノートから読み始めて、具体的な実装例を参考にしながら、必要に応じてリファレンスマニュアルで詳細を確認するという進め方がおすすめです。

10. まとめ:STM32学習の次なるステップへ

本ガイドでは、STM32マイクロコントローラー開発の第一歩として、開発環境STM32CubeIDEの準備、最初のプロジェクト「Lチカ」による開発フローの習得、そしてGPIO、UART、タイマー、ADCといった基本的なペリフェラルの使い方を詳細に解説しました。

STM32は非常に多機能で奥深いマイコンですが、STM32CubeIDEとHALライブラリを使えば、初心者でも比較的容易にプログラミングを開始できます。STM32CubeMXで設定をグラフィカルに行い、生成されたコードにアプリケーションロジックを付け加えるという開発スタイルは、効率的でエラーも少なく、現代的な組み込み開発の主流となっています。

今回の内容をマスターしたら、ぜひ様々なペリフェラルを組み合わせて、より複雑なものづくりに挑戦してみてください。例えば:

  • ADCでセンサーの値を読み取り、UARTでPCに送信して表示するデータロガー。
  • タイマーとGPIOで、ボタンを押すと様々な点灯パターンでLEDが光るイルミネーション。
  • UARTでPCからコマンドを受信し、モーターを制御したりセンサー値を送信したりする遠隔制御システム。

最初は小さなプロジェクトから始め、徐々に機能を付け加えていくのが継続して学習するコツです。開発中に必ず壁にぶつかることもありますが、充実した公式ドキュメントや活発なコミュニティを活用すれば、乗り越えることができるはずです。

STM32を使ったマイコン開発は、ハードウェアとソフトウェアの両方を組み合わせることで、アイデアを物理的な「もの」として実現できる非常に魅力的な分野です。このガイドが、皆さんのSTM32開発への素晴らしい第一歩となることを願っています。ものづくりの世界を存分に楽しんでください!


付記: 本記事は、執筆時点でのSTM32CubeIDEの一般的な使い方に基づいています。ソフトウェアのバージョンアップにより、画面構成や手順が若干変更される可能性があります。最新の情報はSTMicroelectronicsの公式ウェブサイトやドキュメントを参照してください。また、開発ボードの具体的なピン配置や搭載ペリフェラルはモデルによって異なりますので、使用されるボードのユーザーマニュアルやデータシートも合わせてご確認ください。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール