Raspberry Pico: カスタムC-SDKライブラリの設計 (パート1)
Raspberry Picoは、2021年2月に発売された新しいマイクロコントローラーです。コミュニティはこの新しいボードに興奮し、多くの人が素晴らしいプロジェクトをスタートしました。私も早期に2枚のボードを手に入れ、Arduinoベースのロボットをいじりながら、いつものLEDの点滅やポテンショメータのチュートリアルを行いました。
やがて、Picoにますます興味を持ち始め、新しいプロジェクトを開始しました。それは、HC595Nシフトレジスターの接続と制御のライブラリです。HC595Nシフトレジスターは3つの入力ピンで接続され、シリアルデータを受信し、8つのピンに並列データを出力します。この記事では、シフトレジスターの基本を説明し、その後、HC595Nチップの詳細とライブラリの基本設計、そのオブジェクトと機能を提供します。
この記事は元々私のブログに掲載されています。
シフトレジスターの基本
マイクロコントローラーは、GPIOピンを介して他の周辺機器とのインターフェースを可能にします:バイナリ電圧レベルを高または低に適用するか、PWMを使用してデジタルデータを送信します。マイクロコントローラー1つに複数の周辺機器をつなぎたい複雑なプロジェクトでは、GPIOピンの数が制限要素になることがあります。これに対処するために、シフトレジスターという特別なデバイスを使って作業を行います。シフトレジスターは入力を受け取り、それを出力に変換します。
集積回路は論理ゲートで構成されています。AND、OR、NAND、NOR、XORなどの単純な論理ゲートは、2つのデバイス間の入出力処理を制御するのに役立ちます。もっと複雑な論理デバイスは組み合わせ論理と順序論理にグループ化されます。
組み合わせ論理では、1つのデバイスからの入力信号が同時に適用されて出力信号を生成します。複数の入力と単一の出力の変換には、多重化器が使われます。単一の入力と複数の出力の変換には、逆多重化器が使われます。
順序論理では、同じ原則が適用されますが、信号は時間をかけて中継されます。言い換えると、順序論理は一定の論理状態を定義し、その後、タイミングメカニズムを使って出力に伝送することができます。これらのデバイスはシフトレジスターと呼ばれます。
シフトレジスターはシリアルまたは並列入力をシリアル出力や並列出力に処理できます。入力ピンによって制御され、レジスターに値をセットし、ラッチとクロックピンによって状態の送信方法とタイミングが決まります。内部的には、フリップフロップが接続されて、1つの出力が次の入力となるようになっています。フリップフロップがレジスターです。クロック信号が適用されると、次の状態にそれらの現在状態をシフトします。
最も一般的なタイプのシフトレジスターは、シリアル入力をシリアル出力またはパラレル出力に変換します。このタイプはSISO/SIPOとして略され、1つの入力ピンで複数の出力ピンを制御することで、実質的にピンの数を延ばすのに役立ちます。
HC595シフトレジスター
HC595Nは、テキサスインスツルメンツによる8ビットSIPOシフトレジスターです。これは、あなたが日常の電子機器やMCUのシールド/ハットでよく使われている可能性のある基本的なシフトレジスターです。
まずはピン配置を確認して、その基本操作について見ていきましょう。
ピン配置
データシートを見ると、効果的なピン配置が次のようになっています。
ソース: https://www.ti.com/lit/gpn/SN74HC595
基本
- ピン8: GN
- ピン13: 出力有効、アクティブハイ
- ピン16: VCC 2V ~ 6V
入力
- ピン14: シリアル (SER)
- ピン11: シリアルクロック (SRCLK)
- ピン10: シリアルクリア (SRCLR) / アクティブハイ
- ピン12: レジスタクロック (RCLK)
出力
- ピン15: QA
- ピン1: QB
- ピン2: QB
- ピン3: QC
- ピン4: QD
- ピン5: QF
- ピン6: QG
- ピン7: QH
- ピン9: QH* シリアルデータ出力、複数のシフトレジスターをデイジーチェーン接続するために使用されます
動作モード
シフトレジスターは次の機能を提供します:
- シリアルデータ入力:SRCLKがハイになり、SERがハイの場合、バイナリ1を書き込みます。SRCLKがハイで、SERがローの場合、最初のレジスターにバイナリ0を書き込みます
- 並列データ出力:SRCLKがローでRCLKが1クロックサイクルの間ハイになると、シフトレジスターの現在の内容をストレージレジスターに書き込みます
- シフトレジスターデータのリセット:SRCLRを2クロックサイクルの間、ローに設定します
- ストレージレジスターデータのリセット:
データシートで私が準備に重要だと考えたもう一つの詳細は、シフトレジスター・チップに信号を送る際のタイミング値です。タイミングは適用された電圧によって異なります。私はrp2040 Picoが提供する3.3V出力に対して具体的な値が見えませんでしたので、これらの値は2Vの下限値に対応しています:
- tclock 周波数:最大5Hz
- tw パルス持続時間:最小100Hz
ライブラリの設計
この情報を持って、私たちはライブラリの設計を始めることができます。まずはライブラリの主要なオブジェクトについて話し、その後でその機能を定義します。
ライブラリは、シフトレジスターチップを表現する単一のオブジェクトを提供する必要があります。このオブジェクトはCのStruct
です。これは、シフトレジスターをPicoに接続するために使用されるピン設定を保持します。そして、2つの状態も保持します:シリアルピンの現在の入力と、ストレージレジスター値を表す8ビットの整数値です。
typedef struct ShiftRegister
{
uint8_t SERIAL_PIN;
uint8_t SHIFT_REGISTER_CLOCK_PIN;
uint8_t STORAGE_REGISTER_CLOCK_PIN;
bool serial_pin_state;
uint8_t register_state;
} ShiftRegister;
このオブジェクトは次の機能を提供する必要があります:
- 単一ビットの書き込み:他のレジスターの値をシフトしながら、最初のレジスターに単一ビットを追加します
- ビットマスクの書き込み:ビットマスクに従って全てのシフトレジスター値を設定します。これはCで
0b1100110
のように表される8ビットの整数値です - フラッシュ:シフトレジスターの現在の状態をストレージレジスターに転送し、これらの値をシフトレジスターの出力ピンに出力します
- シフトレジスターのリセット:シフトレジスターの全ての値をクリアします
- ストレージレジスターのリセット:ストレージレジスターの全ての値をクリアします
これらの機能は次の署名で定義されています:
bool shift_register_write_bit(ShiftRegister *, bool);
bool shift_register_write_bitmask(ShiftRegister *, uint8_t);
bool shift_register_flush(ShiftRegister *);
bool shift_register_reset(ShiftRegister *);
bool shift_register_reset_storage(ShiftRegister *);
これらの設計考慮をもとにして、次の記事でライブラリの実装を続けることができます。
結論
シフトレジスターはシリアルまたは並列データを受け取り、それを保存し、再びシリアルまたは並列データとして出力する便利な集積回路です。一般的なシフトレジスターチップにはHC595Nがあり、それは8ビットのシリアル入力、並列出力データ伝送を提供します。この記事では、このチップのピンレイアウトと基本操作を説明しました:シリアルデータの入力、並列データの出力、そしてシフトレジスターまたはストレージレジスターのリセットです。この理解に基づいて、私はCライブラリの設計の基礎を提供しました:シフトライブラリを表す構造体オブジェクトと、シフトレジスター操作を実装する機能です。
次の記事ではライブラリの実装を見ていきます。
こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/admantium/raspberry-pico-designing-a-custom-c-sdk-library-part-1-13kh