|
|
пре 2 дана | |
|---|---|---|
| .. | ||
| .vscode | пре 5 дана | |
| micropython | пре 2 дана | |
| tm1637_lib | пре 3 дана | |
| .gitignore | пре 5 дана | |
| CMakeLists.txt | пре 5 дана | |
| LICENSE.md | пре 5 дана | |
| README.md | пре 3 дана | |
| TM1637_pio.c | пре 5 дана | |
| pico_sdk_import.cmake | пре 5 дана | |
Raspberry Pi Pico (RP2040/RP2350) の PIO (Programmable I/O) でTM1637を使った7セグメントディスプレイを制御するライブラリです。TM1637は単体で秋月電子通商から買えるほか、AmazonやAliexpressからTM1637を使った7セグメントLEDディスプレイモジュールが安価に入手できます。
TM1637の詳細に関しては秋月にあるデータシートや、ネット上の参考資料を見てもらえばいいと思いますが、I2Cもどきの2線式シリアルで複数桁の7セグメントLEDを制御できるICです。GPIOで制御している作例が多いですが、PIOで制御することでCPUを低速なシリアル通信から解放できます。このライブラリでは、PIOのFIFOを連結して8エントリとしているので、よくある4桁モジュールならCPUがブロックされずに表示を行うことができます。
add_subdirectory するだけで簡単にプロジェクトに組み込めます。TM1637はI2C風のインタフェースを通じてホストと通信します。Start Conditionでトランザクションを開始し、Stop Conditionでトランザクションを終了する点や、1バイトごとのACKはI2Cと同じです。I2Cとのおもな違いは次の2点です。
このライブラリでは、I2CライクなTM1637のホスト→TM1637のプロトコルをPIOで実装しています。次のように値bをpushするとStart Conditionに続いて1バイトをTM1637に送信します。
pio_sm_put_blocking(pio, sm, b);
値の9bit目をオンにすると、送信後にStop Conditionにバスを遷移させ、バスを解放します。
pio_sm_put_blocking(pio, sm, b | STOP_COND);
SCLKをSDA(TM1637の端子名はDIO)の隣のGPIOに固定しているのは、PIO命令setを使って2つのGPIOの入出力を切り替えていて、STOP Condition後にSDAとSCLKを入力に切り替えて高インピーダンス状態にしバスを解放する必要があるからです。
tm1637out.pioに実装しているPIOコードでは、TM1637のI2C風プロトコルの大部分をデータシートに沿って実装しています。I2C的な通信を行うPIOコード例として活用してください。
なお、PIOコードではACKをチェックしてNACKを検出したらステートマシン番号のIRQフラグをオンにしていますが、Cコード側の割り込み処理は行っていません。テストしてみた限りNACKが生じることがなさそうであることに加えて、仮にNACKが検出されても対応のしようがない(通信エラーが起きたことがわかるだけ)からです。マルチインスタンス化していることもあり、NACKのための割り込み処理を追加するとかなり複雑になりますが、複雑にするだけの価値が見いだせないので、NACKに対応する処理は削除しました。もしに気なるようならIRQフラグをチェックするコードを追加すればいいでしょう。
書籍には記載していなかったので、ここで簡単に使い回しができるライブラリの自作方法を、tm1637_libを例に説明しておきます。
まず、自分のプロジェクトにライブラリ名のサブディレクトリを作成します。本例ではtm1637_libですね。
your_project/
├── tm1637_lib/ # ライブラリフォルダ
│ ├── CMakeLists.txt
│ ├── TM1637.c
│ ├── TM1637.h
│ └── tm1637out.pio
├── CMakeLists.txt # 親プロジェクトのCMakeファイル
└── main.c # アプリケーションメインコード
サブディレクトリの下にライブラリ用のCMakeLists.txtを作成します。tm1637_libではPIOを使っているので、pico_generate_pio_headerもライブラリ用のCMakeLists.txtに書いておきます。
# ライブラリのターゲットを作成 (STATICライブラリ)
add_library(tm1637_lib STATIC
TM1637.c
tm1637out.pio
)
# PIOヘッダの生成
pico_generate_pio_header(tm1637_lib ${CMAKE_CURRENT_LIST_DIR}/tm1637out.pio)
# ヘッダファイルのパスを公開 (このライブラリを使う側が include できるようにする)
target_include_directories(tm1637_lib PUBLIC ${CMAKE_CURRENT_LIST_DIR})
# ライブラリが必要とする依存関係
target_link_libraries(tm1637_lib PUBLIC
pico_stdlib
hardware_pio
)
そしてプロジェクトメインのCMakeLists.txtに次のようにadd_subdirectoryを追加し、target_link_librariesにライブラリ名を追加します。
...
add_subdirectory(tm1637_lib)
...
target_link_libraries(your_executable
pico_stdlib
tm1637_lib # これを追加
...)
...
これでポータブルなライブラリが作成できました。以後、プロジェクトディレクトリの下にライブラリ名(ここではtm1637_lib)ディレクトリごとコピーして、メインのCMakeLists.txtにadd_subdirectoryとtarget_link_librariesを追加すれば、自作ライブラリを今後のプロジェクトに使い回すことができます。
#include "TM1637.h"
// 初期化 (SDAピン番号, 桁数, 輝度0-7)
// SCLピンは SDA + 1 となります
TM1637_t *tm = TM1637_init(4, 4, 4);
if (tm != NULL) {
TM1637_putstr(tm, "12:34");
}
TM1637_t *TM1637_init(uint8_t sda_base_pin, uint8_t col, uint8_t cont)
TM1637を初期化し成功すればハンドルを返す
パラメータ
uint8_t sda_base_pin: SDA(DIO)を接続しているGPIO番号。PIOコードの制約によりsda_base_pin+1のGPIOにSCLKを接続してください。uint8_t col: 接続しているモジュールのカラム数。TM1637は最大6カラムの7セグメントLEDを制御できます。uint8_t cont: コントラスト値。0(暗)~7(明)。戻り値
int TM1637_set_contrast(TM1637_t *p, uint8_t cont)
コントラスト値を設定する
パラメータ
TM1638_t *p: ハンドルuint8_t cont: コントラスト値。0(暗)~7(明)戻り値
int TM1637_putchar(TM1637_t *p, char c, bool dot, uint8_t col)
文字を表示
パラメータ
TM1637_t *p: ハンドルchar c: 表示する文字コードbool dot: ドットセグメントをオンにするならtrueuint8_t col: 表示するカラム戻り値
int TM1637_putstr(TM1637_t *t, char *str)
文字列を表示する
パラメータ
TM1637_t *p: ハンドルchar *str: 表示する文字列。次の文字にピリオドまたはコロンを挿入すると、その文字のドットセグメントがオンになります。ドットセグメントの形状及び位置は製品によって異なります。ピリオド(.)かコロン(:)が一般的です。戻り値