Web制作、Web開発の歩き方

STM32入門(組み込み開発)

■第3話:STM32の基本操作2 -GPIO, UART-

(最終更新日:2025.01.13)

C言語のイメージ
この記事は6分で読めます!
(絵が小さい場合はスマホを横に)

「基本的な使い方を学ぼう」

第2話では、STM32CubeMXを活用した基本的なプロジェクト作成方法を学んだ。 GUIを使ったピン設定やクロック設定の流れを解説し、STM32マイクロコントローラーの初期設定を理解した。 今回は、さらにLED点滅を例にHAL関数を用いたGPIO制御を解説する。 加えて、UART通信の仕組み、STM32での設定方法、PCとの通信方法についても学ぶ。


1.GPIOの解説

前回、クロックやピンの設定を行い、初期化コードを生成し、GPIOでLEDを点滅させることができた。 今回は、前回のコード、HAL(Hardware Abstarct Layer)関数について解説を行う。

生成した初期化コード

「HAL_GPIO_WritePin」は指定したGPIOピンの状態を設定する。 下記コードでは、Aポートの5番ピンをHIGHの状態に設定している。 GPIO_PIN_SETはHIGHを意味する。GPIO_PIN_RESETであれば、LOWになる。

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);

GPIOピンの設定

上記のコードをHALを使わないで書くと、下記のようになる。

HAL関数を使わない書き方

HALを使うと何が良いかというと、端的で直観的なコードしてくれることである。 そして、シリーズ(異なるボード)間で内部の構成が変わったとしても、HALを使えば同じ書き方をすることができる。 HAL関数を生成する段階で、違いを吸収してくれる。 ただし、直接記述した場合に比べ、処理速度はやや劣るので、その点は注意しよう。

HALとレジスタ直接操作の比較

項目 HALを使用 レジスタ直接操作
可読性 高い 低い(レジスタ名やビット演算を理解する必要あり)
移植性 高い(全STM32シリーズ対応) 低い(シリーズ間でレジスタ構造が異なる場合がある)
コードの簡潔さ シンプル(CubeMX自動生成コードと連携) 詳細なレジスタ操作が必要
パフォーマンス やや劣る(抽象化のオーバーヘッドあり) 高い(直接操作のためオーバーヘッドなし)
保守性 高い(APIが統一されている) 低い(すべてのレジスタ操作を把握する必要がある)

「HAL_DELAY」は指定した時間(ms単位)処理を停止する。 ms以下の高精度なタイミングが必要な場合はタイマーを用いた方が良いが、それほど厳密でない場合はこれで充分である。 下記は0.5秒処理を停止する。

HAL_Delay(500);

処理停止の設定

これらを応用すると、複数のLEDを点滅させたり、ボタンでLEDを制御することができる。 複数LED点滅のコードではHAL_DELAY(処理停止)を上手く活用している。 このWritePinとDelayを使うと、前回用いたToggleを使わなくても、下記のように書くことでLEDを点滅させることができる。 Delayの時間を調節することで、点滅のタイミングも決められる。

複数LED点滅(上)とボタン制御(下)

注意点としては、LEDは電流を流しすぎると壊れてしまうため、必要に応じて抵抗を入れるようにしよう。 また、GPIOのクロックを有効化することも忘れない。 今回のような、時間にシビアでない場合はHAL_DELAYで充分だが、リアルタイム性を追求する場合はタイマーを使用する。

2.UARTの仕組みとSTM32での設定方法

■UARTの概要
UART(Universal Asynchronous Receiver/Transmitter)は、シリアル通信を実現するための一般的なプロトコルだ。 本項では、UARTの仕組みとSTM32での設定方法、PCとの通信を実現する具体的な手順を詳しく解説する。

UARTは、データを1ビットずつ逐次的に送受信する通信方式だ。 スタートビット、データビット、パリティビット(オプション)、ストップビットから構成される。 送信側はデータをフレーム化し、ビットを1つずつ送信する。受信側はフレームを解析して元のデータに復元する。

UARTのフレーム内容

フレーム内容 ビット数 説明
スタートビット 1ビット データの開始を示す
データビット 8ビット 実際のデータ
パリティビット 0 or 1ビット エラー検出用
ストップビット 1ビット データの終了を示す

UART通信は非同期通信で、クロック信号を使用せず、送受信者がボーレート(通信速度)を共有する。 それぞれ独立した回路、バッファを持つため、同時にデータを送受信可能である。短い距離の通信に適している。

■STM32での設定
STM32ボード(評価用ならNucleoボード)、USBシリアルアダプタ(PCとUARTを接続)、ST-LINK経由の仮想COMポートを用意する。 STM32CubeMXを起動し、新しいプロジェクトを作成、使用する評価ボードを選択する。 ペリフェラルタブまたはチップ図で、USART1をクリックして有効化する。 これにより、TXピン(PA9、送信)とRXピン(PA10、受信)が自動割り当てられる。 ボーレートを9600など適切な値に設定、データ長8bit、パリティNone、ストップビット1bitなどを設定する。 RCC設定で外部クロック(HSE)または内部クロック(HSTM32CubeIDEを選択してコードを生成SI)を有効化し、クロックツリーでUSART1のクロックが有効になっていることを確認する。 プロジェクト名と保存場所を指定し、例えばSTM32CubeIDEを選択してコードを生成する。

■生成されたプロジェクトの確認
main.c(メインプログラム)とusart.c(UART初期化コード)が生成されている。 UART初期化コードは以下の通りになる。CubeMXで自動生成される。

UART初期化コード

■送信プログラム
生成されたmain.cに「Hello UART!」が送信できるようにしてある。 1秒間隔でデータを送信できるようになっている。

初期化コードから送信可能に

■送受信プログラム
UART受信データを処理するように、下記のように編集する。 これで、送受信が可能になる。

送受信可能に

3.PCとの通信を実現する

PCと接続するには、USBケーブルを利用する。 評価用のNucleoボードの場合は、仮想COMポート(ST-LINK経由)を使用するだけでよい。 開発用のボードの場合は、USBシリアルアダプタを使用し、UARTピンをPCに接続し、TX(STM32)→RX(アダプタ)、RX(STM32)→TX(アダプタ)を設定する。 GNDを共有する。 WindowsからTeraTermなどの通信を確認できるソフトを起動し、 ボード側で設定した、ボーレート:9600bps、データ長:8ビット、パリティ:None、ストップビット:1ビットと合わせる。 これにより、STM32から送信されたデータがシリアルモニタに表示される。 シリアルモニタから入力したデータがSTM32に届き、エコーバック(返信)される。

TeraTermでCPUボードと接続する

■応用例(非同期通信プログラム)
UARTの割り込みを使用して非同期でデータを送受信する。 下記のようなプログラムになる。

UARTの割り込み

4.まとめ

このセクションでは、UART通信の仕組み、STM32での設定方法、PCとの通信実現を学んだ。 UARTはデバッグや外部デバイスとのデータ交換に非常に有用だ。 DMAや割り込みを活用すれば、さらに効率的な通信が可能になる。 必要に応じて応用例に挑戦し、UART通信の理解を深めよう。

▼参考図書、サイト

STM32マイコン公式日本語サイト  STマイクロエレクトロニクス
 「WindowsではじめるSTM32」 インプレスR&D 山本 小鉄
Q&Aで学ぶマイコン講座(64) HAL(ハードウェア抽象化レイヤー)って何?   EDN Japan