STM32 LLでSPI通信してみる 前編

  • 2021.01.15
  • LL
STM32 LLでSPI通信してみる 前編

皆さま こんにちは。

今回は LL SPI通信の前編です。

LLってな~に?という方は HALとLL の記事をご覧ください。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.5.0
Configurator: STM32CubeMX Version6.1.0
Board: STM32Nucleo-F401RE

SPI通信の概要

SPIはシリアル・ペリフェラル・インターフェースの略です。
I2Cと同じようにマイコンと周辺デバイスを(一般的には)プリント基板上で通信するための手段です。

I2Cではデータバスが1本で送信と受信が兼用になっていますが、SPIは別々です。
別ということは全2重通信が可能なので、一般的にその分通信速度は速くなります。

・モトローラが開発した通信方式
・SCK, MISO, MOSI, SSの4本の通信ラインを使って双方向で通信が可能
・通信速度はI2Cに比べて高速
・マスタとスレーブが存在する

SPIについては こちら を見て頂ければと思います。

スレーブとなるターゲット

STM32(をマスタ)で制御し、スレーブのデバイスは以下のものを使ってみました。

気圧センサーモジュール

価格は600円でネットを使って購入しました。

メーカーはSTマイクロです。デバイスのデータシートは こちら です。

接続

下表のとおりに接続します。

このモジュールは I2C か SPI のどちらで接続するのか選択することができます。
今回はSPIで接続するので5番ピンをチップセレクトの信号とつなぎます。
割り込みは使わないのでINT端子は接続していません。

なおSPIで通信する場合、裏面のJ1, J2の半田ジャンパーはオープンにする必要があります。

プロジェクトを作成する

IDEを起動し、File- New – STM32 Project を選択し、Target Selection ウィンドウが出たら Board Selector タブを選択し Boards List から NUCLEO-F401RE を選択し Next ボタンを押します。

Project 名に F401SpiLL と入力し、Finishボタンを押します。
Initialize all peripherals with their default Mode ? と聞いてくるので Yesを押します。
This kind of project is associated with the STM32CubeMx perspective. Do you want to open this perspective now ? と聞いてくるので Yesを押します。

気圧センサーのプロトコル

気圧センサーの読み書きプロトコルの図です。

クロックのアイドル状態は H (CPOL=1) です。
またデータのサンプリングは2番目のエッジ(立ち上がりエッジ)を使います。(CPHA=1)

また、送受信のラインが別になっているので一般的なモトローラ形式のSPIフォーマットになります。

コンフィグレーターでSPIインターフェースを追加する

今回使うSPIの端子はPA4, 5, 6, 7です。(画像の赤枠で囲った部分)

PA4を右クリックして選択し、GPIO_Output を選択します。(端子は緑色)
PA5を右クリックして選択し、SPI1_SCK を選択します。(この時点で端子は黄色にかわる)
PA6を右クリックして選択し、SPI1_MISO を選択します。(この時点で端子は黄色にかわる)
PA7を右クリックして選択し、SPI1_MOSI を選択します。(この時点で端子は黄色にかわる)

そして Pinout & Configuration – Categories – Connectivity – SPI1 を選択し、
SPI1 Mode and Configuration – Mode のリストから Full Duplex Master を選択します。

GPIO(PA4)を使ってスレーブのCS(チップセレクト)を制御するので、Hardware NSS Signal は Disable のままにしておきます。

Parameter Settings の内容は以下の通りにしてください。

SPI1のクロックはAPB1になります。APB1=84MHzですから、プリスケーラーを8にするとクロックが10.5MHzとなり気圧センサーの最大周波数10を超えてしまいます。

そこでプリスケーラーは 16 に設定し、クロックを5.25MHzとしました。

ついでと言ってはなんですけど、レジスタの設定も併せて確認してみましょう。
まず制御レジスタ1です。

私が理解している範囲で説明していきます。

ビット15:双方向データモードイネーブル

送受信の信号があるので0

ビット14:双方向モードでの出力イネーブル

使わないので0

ビット13:ハードウェアCRC計算イネーブル

使わないので0

ビット12:CRC転送指示

CRCフェーズなしなので0

ビット11:データフレームフォーマット

8ビットなので0

ビット10:受信専用

全二重(送受信)なので0

ビット9:ソフトウェアスレーブ管理

使わないが、Hardware NSS Signal を Disable にするので、このビットは 1 になる。

ビット8:内部スレーブ選択

使わないが、Hardware NSS Signal を Disable にするので、このビットは 1 になる。

※スレーブデバイス(気圧センサー)のCSはGPIOで制御するため、ビット9,8 の値は意識する必要はない。

ビット7:フレームフォーマット

MSBファーストだから(位の高いビットから送られるから)0

ビット6:SPIイネーブル

状況によって0になるが、送受信する際に0になっていたら1にする必要がある。

ビット5-3:ボーレート制御

1/16 だから 011

ビット2:マスタ選択

マスタなので1

ビット1:クロック極性 CPOL

アイドル時に1なので1

ビット0:クロック位相

2番目のクロック遷移が最初のデータキャプチャエッジなので1

次に制御レジスタ2

ビット7:Txバッファエンプティ割り込みイネーブル

使わないので0

ビット6:Rxバッファノットエンプティ割り込みイネーブル

使わないので0

ビット5:エラー割り込みイネーブル

使わないので0

ビット4:フレームフォーマット

モトローラ形式なので0

ビット3:予約 0

ビット2:SS出力有効

使わないので0

ビット1:TxバッファDMAイネーブル

使わないので0

ビット0:RxバッファDMAイネーブル

使わないので0

まとめると、初期設定が終わったところで

制御レジスタ1(CR1)は 0x031f
制御レジスタ2(CR2)は 0x0000

これらの値はデバッグ時に設定が完了したところで確認します。

使用するライブラリを HAL から LL に変更する

ここまで設定するとSPIでLLを選択することができるようになります。

Project Managerタブを選択し Advanced Settings の SPI を HAL (初期値)から LL に変更します。(コンボボックスで選択する)

HALの部分をクリックするとコンボボックスのリストが表示されるので、LLを選択します。

Project Explorer で F401SpiLL を選択し、Project – Build Project でビルドします。

main.cに MX_SPI1_Init()が生成されてエラーがないことを確認します。

MX_SPI1_Init()の中は LL を使ったコードで書かれていることが確認できます。

少々長くなりましたので、このつづきは次回にします。

お疲れさまでした。

続きを読むには こちら からどうぞ。

LLカテゴリの最新記事