9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RustでSTM32ベアメタル [4桁7セグメントLED](概要編)

Last updated at Posted at 2020-04-30

Rustという言語でSTM32F3Discoveryというマイコンを動かし,4桁7セグメントLEDダイナミック点灯方式で光らせるっていう記事です.

成果物はこちら.↓

はじめに

Rustで組み込みをやってみよう!そう思ったきっかけは,Googleのセキュリティキー
これについて調べていくうちに,TockというRustで書かれた組み込みOSの存在を知りました.
最近趣味でRustを使うようになった私は,このTockにとても興味を持ちました.
そして,とりあえずRustで簡単な自作組み込みOSを作ることと,Tockの中身の理解を最終目的として,Rustでベアメタルを始めることにしました.

しかし組み込み初心者の私には,どうやって始めればいいのかさっぱりわかりませんでした.

そんな時に出会ったのがこちらの記事

というわけでこの方が和訳してくださったDiscovery(日本語版)というドキュメントを手を動かしながら読み進めることにしました.
これが本当に神資料!

このドキュメントではf3という高レベルなクレートを使いますが,初心者にとって,これが勉強にならないなんてことは全くありません.
時々ちょっと細かく説明してくれたりする部分があり,かなり感覚が掴みやすくなります.

ちょっと掴めてきたら,今使ってるモジュールのソース読んだり,試しにそのモジュールを使わずに書いてみたりして,またわからなくなったらちょっと立ち止まって調べる.

自分はこれを繰り返してちょっとずつ下に降りていくという勉強方法をとりました.

はい,ここら辺でまえおきは終わりにして,本題に入ります.

7セグメントLED(ダイナミック接続)

ここからはカソードコモンの7セグメントLEDを使用してる前提で話します.

7セグメントLED(4桁)って,(ドット入れて)$8\times4=32$個のLEDからできてるのに,一般的な4桁の7セグメントLED(ダイナミック接続)はピンが12個しかついていない.
なので,まずはどうやって32個のLEDを制御するのかについて説明します.

まず12本のうち4本(図の$\rm {D1}$~$\rm {D4}$)が,どこの桁を表示させるかっていう信号を入力するためのピン.それぞれの桁に接続されているコモン端子を*Low*にすると,その桁を光らせることができる.
残りの8本(図の$\rm {A}$~$\rm {F}$と$\rm {decimal}$)は,その桁の,どのLEDを光らせるかっていうピンです.光らせたいLEDに接続されているピンに電圧を与えれば,LEDが光る.

え,でも待って,この方法だと4桁いっぺんに表示できなくない?

その通り.なので,表示させる桁と表示させるLEDの信号を高速に切り替えることで,人間の目には同時に光ってるように見えるようにする.
だからダイナミックっていうんですね.

この方式を使うことによって,LEDを制御するために使わないといけないマイコンのピンを32ピンから12ピンに節約できるというわけですね!

8ビットシフトレジスタ(74HC595)

上記の説明で,このダイナミック点灯方式によってすでに20ピンくらい節約できてるということがわかったと思います.

ここからは,もっとピンを節約する方法について話します.

使うのは***8ビットシフトレジスタ
どこを節約するかというと,どのLEDを光らせるかっていう8本のピン.
8ビットの
シフトレジスタ***を使うのは,光らせるLEDがドット入れて8個だからですね.

8本のピンから別々に信号を送るんじゃなくて,1本のピンから8ビットのデータを送信して,その各ビットでLEDを制御できたら便利だと思いませんか?
それを可能にするのがこのシフトレジスタ

仕組みはおいといて,とりあえずこのシフトレジスタがどんなことをしてくれるかについて説明します.

シフトレジスタの主な役割は,***シリアルな信号をパラレル***に変換するということ.
もう少しわかりやすくいうと,順番に直列に受け取った複数のデータを,同時に並列に送信する形に変換するということ.
つまり,1本のピンから8ビットのデータを受信したら,その各ビットの値を,それぞれ8本の違うピンから同時に出力するわけです.

マイコンの1ピンを,8ピン分として拡張して使えるってことです!

使い方

え,じゃあマイコンに割り当てるのは桁選択の4ピンと,あとLEDの情報を送信する1ピンの,合計5本だけでいいの?

っていうと,残念ながらそういう訳ではない.

シフトレジスタは内部で8個の***Dフリップフロップを使っていて,クロック信号の立ち上がりで次のフリップフロップ***に論理信号が移動するっていう仕組みになっているので,そのためのクロック信号を送る必要がある.

また,フリップフロップに記憶された値を常時出力していては出力が乱れてしまうので,シフトレジスタの内部では,フリップフロップと出力の間に***ラッチ回路をかませてある.なので,このラッチ回路***用のクロック信号も送る必要がある.

回路図は[こちらの記事](http://hello.world.coocan.jp/ARDUINO/arduino_4.html)がわかりやすい.

という訳で,使うのは$4+3=7$ピン.

SPIモジュールの利用

stm32f3Discoveryボードには,***SPI***モジュールというものが搭載されています.
前項の内容を,そのまま自分で実装しても良いのですが,SPIモジュールを利用すると,実装をより容易に行うことができます.

SPI(Serial Peripheral Interface)

SPIとは,コンピュータ内部で使われるデバイス同士を接続するバスである.
SPIバスは、単一のマスタと、1つ以上のスレーブの装置で操作することができる.
Wikibedia

ここではSPIについてこれ以上詳しくは述べません.
マスタは,該当するスレーブの*SS線をLowにすることで、通信するスレーブ*を選択する.

どう使うのか

MISO線は,スレーブからデータを送るためのものなので,今回は使わない.
残りの3線を,以下の表のように割り当てれば,SPIを使って
シフトレジスタ**を制御することができる.

シフトレジスタ SPI
SER MOSI
SCK SCLK
RCK SS

SPIモード

SPIには4つのモードがある.
それらを表と図で示します.(図はリファレンスマニュアルから)
図の*MISO*線の部分は今回は関係ありません.

SPIモード CPOL アイドル状態の
クロックの極性
CPHA データのサンプリングに
使われるクロックの位相
0 0 LOW 0 立上がり
1 0 LOW 1 立下がり
2 1 HIGH 1 立下がり
3 1 HIGH 0 立上がり
スクリーンショット 2020-04-30 18.38.11.png さて,***シフトレジスタ***を制御する上では,これら4つのモードのうち,どれを使えばいいのでしょうか.

シフトレジスタのタイミングチャート

ここでシフトレジスタのデータシートを見てみましょう.
スクリーンショット 2020-04-30 20.02.08.png
CPOL=0CPHA=0の時の図が書いてありますね.
SPI
モード0を使えば
シフトレジスタ**が制御できるということがわかりました.

実装編へ続く

実装編では,実際のRustのコードとかも載せながら説明していきます.

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?