ARMマイコンSTM32レジスタマップの見方【上級者向け】

レジスタマップ

めかのとろ

ペリフェラルライブラリだけを使用する場合はレジスタマップを意識する必要はありませんが、マイコンのレジスタがライブラリ内でどのように操作されているか理解することはマイコンのスキルアップにつながります。

めかのとろ

見方を変えると、ライブラリを使用しないでレジスタを操作できるようなレベルになると、各マイコンメーカーの提供するライブラリやツールに頼ることなしに開発ができるので最強です。

めかのとろ

ここではペリフェラルライブラリがどのようにペリフェラルの制御レジスタを操作しているかを見てみましょう。ペリフェラルライブラリをブラックボックスとして仕組みを理解しなくてもマイコン開発は可能です。しかもレジスタの操作を理解することは入門者とくにプログラミングにあまり慣れていない人にはとても難解と思われるのでとばしてもらってもかまいません。

めかのとろ

マイコン上級者ともなりメーカー作成のライブラリに頼らず直接レジスタを操作できるとプログラムコードも小さく処理速度を向上させたアプリケーションを作成できるようになります。必須のスキルではありませんが必要に応じて使えるようになればより応用力がつき強力なスキルとなるでしょう。

めかのとろ

前章において汎用入出力GPIOA_1ピンペリフェラルライブラリによりプッシュプル出力に設定した仕組みをたどっていきましょう。

めかのとろ

ペリフェラルのメモリマップを示します。この中でGPIOポートAのメモリ上のベースアドレスは32bit表記の0x40010800です。

メモリマップ

次にGPIO制御レジスタの内容を確認しますと、下記7種類の制御レジスタがあります(x=A…G)。

  • ポート設定レジスタ下位(GPIOx_CRL)ポート0から7
  • ポート設定レジスタ上位(GPIOx_CRH)ポート8から15 
  • ポート入力データレジスタ(GPIOx_IDR)
  • ポート出力データレジスタ(GPIOx_ODR)
  • ポートビットセット/リセットレジスタ(GPIOx_BSRR)
  • ポートビットリセットレジスタ(GPIOx_BRR)
  • ポート設定ロックレジスタ(GPIOx_LCKR)

ポート仕様を設定するレジスタはGPIOA_1ピンの場合は下位(0 – 7)ですので制御レジスタGPIOA_CRLを操作して設定します。レジスタGPIOA_CRLのアドレスはオフセットが0x00なので0x40010800です。

GPIOレジスタ
ポート設定レジスタ

ライブラリを使った本体プログラム内での記述

めかのとろ

実際のプログラムでライブラリがどのような機能をしているかを確認していきましょう。

プログラム内でのライブラリによる初期化設定
めかのとろ

構造体でまとめられている部分の詳細を確認してみましょう。パラメータは分類ごとに構造体によりまとめられています。

初期化関数 xx_Init()について

めかのとろ

それではレジスタアドレスと設定パラメータが初期化関数GPIO_Init(GPIOx, &GPIO_InitStructure)でどのような処理が行われてレジスタを操作しているかを解説してみます。

めかのとろ

実際のプログラムはGPIOライブラリ本体stm32f10x_gpio.c内のGPIO_init()関数の部分ですので余力のあるひとは確認してみてください。

  1. 構造体メンバGPIO_Modeの下位4ビット分にマスクをかけ(&0x0F), currentmodeに値を代入。
    次に上位1ビット目にマスクをかけ(&0x10)入力か出力かの判別。
    出力である場合は下位2ビット分にGPIO_Speed設定値(0bxx)をセット。
  1. GPIO_CRLレジスタ(下位8ビット) pinすべてが0でないことを調べ(すべてが0の場合はGPIOが無効であることを意味するため)、各GPIOピンの0から7ピンに割り当てた4ビットにCNFn(2ビット)とMODEn(2ビット)の設定値をレジスタに書き込み、GPIOポートの各ピンの使用方法を設定する。(nは0~7のピン番)
    8ピン全部に同じ処理を繰り返す。
  1. 設定されたモードがGPIO_Mode_IPDの場合GPIOx_BRR(GPIOx)ビットリセット・レジスタ)の該当ビット1にセットする(該当ビットリセット:入力プルダウン抵抗設定)。
    設定されたモードがGPIO_Mode_IPUの場合GPIOx_BSRR(GPIOxビットセット/リセット・レジスタ)のセットの該当ビット1にする(該当ビットセット:入力プルアップ抵抗設定)。
    これも8ピン全部に同じ処理を繰り返し、GPIOx_CRL(下位のGPIOxコンフィグレーション・レジスタ)に書き込む。
  1. 同様にGPIOx_CRH (上位のGPIOxコンフィグレーション・レジスタ)の処理を行い、関数GPIO_Init(GPIOA, &GPIO_InitStructure);の処理を終える。そのあとGPIOBからGPIOEポートについて同様な処理を行う。
めかのとろ

以上が初期化関数GPIO_Init(GPIOx, &GPIO_InitStructure)で行われる処理です。

めかのとろ

ペリフェラルの初期設定ではGPIOに限らず該当する制御レジスタのアドレスを特定して、設定したいパラメータを書き込むことをペリフェラルライブラリ(デバイスドライバ)を使ったり、レジスタに直接書き込んだりして設定するわけです。

めかのとろ

ペリフェラルライブラリは制御レジスタを知らなくても簡単に使いこなせてしまう便利な反面冗長な部分もありますので、プログラムコードサイズを小さくし、より処理速度の向上を追求する場合には直接レジスタを操作する必要がでてくる場合があります。

めかのとろ

処理速度もプログラム格納のメモリサイズも十分な高性能なマイコンを使うのであればより便利なペリフェラルライブラリだけを使って開発はアプリケーションに集中するのもいいかもしれません。