Kageki (TD4互換機) と74HC595で流れるLED

[TD4の命令を実行できる自作CPU「Kageki」](https://elchika.com/article/9ac9fd67-86c5-4b1b-a355-4f662e8af794/)とロジックICの74HC595を用いてLEDの点灯位置を動かしてみた。

# 74HC595

74HC595はロジックICの一つで、シフトレジスタとDフリップフロップが組み合わさっている。
以下の図のように、データ入力SIとクロック入力SCKを用いてシフトレジスタに値を送り込み、クロック入力RCKを用いて送り込んだ値を一斉に出力ピンQA～QHに反映できるようになっている。
また、シフトレジスタの値を直接出力するQH'を次段のSIに接続することで、複数の74HC595を数珠つなぎにして利用できる。

![74HC595の構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/ea213102-5cdf-551a-8c9e-87c1f3ef26d6.png)

なお、他にシフトレジスタをゼロクリアする入力や、出力ピンをハイインピーダンスにする入力があるが、今回は扱わないので省略した。

# 74HC595を用いたLED点灯回路

74HC595のQA～QHの出力ピンをそれぞれ抵抗を経由してLEDに接続した、以下のような回路を作成した。
LEDは、左から順にQA～QHに対応する。
さらに、この回路では、電源および74HC595の各入力をKagekiの出力ポートに直結できるようにしてある。
74HC595の入力`~G`はLOW固定、`~SCLR`はHIGH固定とした。出力`QH'`は接続しない。

<table>
<tr><th>設計表面</th><th>設計裏面</th></tr>
<tr><td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/ab6bcb30-f701-e9fc-403b-c4851a64a07b.png" alt="74HC595回路 設計表面"></td><td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/8ad81611-80e5-c508-9c6e-f32a34218041.png" alt="74HC595回路 設計裏面"></td></tr>
<tr><th>実物表面</th><th>実物裏面</th></tr>
<tr><td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7272870f-1756-fce1-fb7f-c27776564218.jpeg" alt="74HC595回路 実物表面"></td><td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/e7828bbf-aeb5-458a-2a4f-2ea9ff3ffe7e.jpeg" alt="74HC595回路 実物裏面"></td></tr>
</table>

なお、今回の基板およびLEDは以下のものを用いた。

* [ユニバーサル基板 片面 72x47 LUPCB-7247S Linkman製｜電子部品・半導体通販のマルツ](https://www.marutsu.co.jp/pc/i/144024/)
* [LED(赤、5mm、カラーレンズ) 503VD2E-1B Linkman製｜電子部品・半導体通販のマルツ](https://www.marutsu.co.jp/pc/i/2348061/)

ピンの配置が異なるが、以下のモジュールも同様に利用可能であると推測できる。(未確認)

* [国産ライトバーLED表示器（SPI） - aitendo](https://www.aitendo.com/product/17758)
* [ライトバーLED表示器（SPI） - aitendo](https://www.aitendo.com/product/17867)

# プログラム

```
位置 機械語   アセンブリ言語
--------------------------------
0    00001000 FIRST: ADD A, 1000
1    11100101        JNC ONE
2    00001000        ADD A, 1000
3    00000001 DLOOP: ADD A, 0001
4    11101001        JNC ZERO
5    10110001 ONE:   OUT 0001
6    10110101        OUT 0101
7    00110111        MOV A, 0111
8    11111010        JMP DOWN
9    10110100 ZERO:  OUT 0100
A    10110000 DOWN:  OUT 0000
B    01010010        ADD B, 0010
C    11100011        JNC DLOOP
D    10110010        OUT 0010
E    10110000        OUT 0000
F    11110000        JMP FIRST
```

Aレジスタを点灯させる位置、Bレジスタを送信するビットの位置として用いる。
0～1番地で、Aレジスタの値を確認し、`1000`未満 (この先8ビット分キャリーが出ない) の場合は強制的に次のビットは「1」を送信するようにする。(全部消灯という状態を作らせない)
2番地で、確認のための加算を打ち消している。
3～4番地で、Aレジスタに `0001` を加算し、次のビットを「1」にするべきかの判定をしている。
5～8番地で、シフトレジスタに「1」を送信し、Aレジスタに `0111` を格納している。(次に「1」を送信するのは9ビット後)
9～A番地で、シフトレジスタに「0」を送信している。
B～C番地で、送信したビットの位置を管理している。
D～F番地で、8ビット送信したので出力ピンを更新する信号を送り、次の8ビット以内にも「1」を送信できるようにする処理に進んでいる。

# 実行結果

出力ポートの各ビットを74HC595に以下のように接続して実行する。

|Kageki|74HC595|
|:-:|:-:|
|0|SI|
|1|RCK|
|2|SCK|
|3|-|
|GND|GND|
|VCC|VCC|

以下のように、LEDの点灯位置が移動していく様子を確認できた。

<iframe width="560" height="315" src="https://www.youtube.com/embed/cgwUN2CQvOA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>