今回はシフトレジスタを2個直列につなげて16ビット出力させる実験です
繋ぎ方は前回と違ってちょっと特殊な感じになります
QH”の出力はもう一方のレジスタのSI(シリアルデータ入力)に繋げ、もう片方のQH”はGNDに接続
クロックとラッチはタイミングを合わせる為に両方のシフトレジスタ同士のピンをY字で繋げてArduinoと繋げます
で、今回はノイズ対策にクロックピンに0.1μFの積層セラミックコンデンサを両方に付けました
そうしないとノイズで誤動作した際にタイミングがズレるからです
並列接続だとズレてもたいした問題じゃないので付けていませんでした(もちろん有った方がいい)
どこのサイトさんでも似たような繋ぎ方なんでこれで合ってると思われます(保障は無いw)
回路図が無くても74HC595の資料が有ればこの説明でたぶん分かって貰えると思いますが
分からない場合は別サイトさんの所に接続回路があるので探してくださいw

こんな感じでブレッドボード上に組んでLED点灯実験しています
先に結論から言っちゃうと
考え方や使い方は今までのでだいたい合っていたんですが
”下位を先に送ってから右に8ビットシフトさせて上位を送信” これが原因だったみたい
”上位8ビットを送る→下位8ビットを送る” この順に記述しなおしたら何故か正常出力されてしまいました・・・・
なぜこれが判明したかと言うと、前回の実験で{変更した物を代入する}とずっと思っていた為です
なので「シフトさせてしまうと下位8ビットが消える→先に下位8ビットを送信させよう」と思っちゃったのが原因
でも実験で変更されないのが分かった為、基本通りに上位を先に入れてから下位を入れてもう一方のシフトレジスタへ上位8ビットを押し込む事にしたら
全くなんの問題もなく表示されちゃった と言う訳です
理論上ではどっちでもいい様に思うんだけど・・・コンパイル時に問題が出るのかなぁ・・・
で、色々試行錯誤実験を行った結果、1つだけどうしても直らない問題が有りました
これは後述しますので先に色んな実験結果を挙げていきたいと思います
ラッチ操作などは記述していません
投稿時に自動校正されてしまう対策で全角英数を使用している為コピペでは使えません
疑問1 INT型2バイトデータをそのまま出力データ(8ビット専用)に入れて頭から読ませた場合の表示
INT A=0000000011111111;
shiftOut(dataPinA, clockPinA, MSBFIRST, A);
結果 上位(00000000)下位(11111111)になった
shiftOut関数に組み込むと自動的にbyte型(1バイト)に変更される
8ビットしかデータが無いので上位レジスタには何も入らない
74HC595のタイミングチャートでは8ビット目が入る前にQH”が出力されるみたいだが出てきていない
疑問2 2バイトデータを右に8シフトさせて上位8ビットを出力
INT A=0000000100000000;
INT B=A>>8;
shiftOut(dataPinA, clockPinA, MSBFIRST, B);
結果1 上位(00000000)下位(00000001)になった
下位データを送信していない為上位用レジスタには何も入っていない
shiftOut(dataPinA, clockPinA, MSBFIRST, A);を最終行に付け足して上位送信の後に下位を送信
両方送信し終わったあとにラッチ開放(開放でレジスタ内データを出力する)
注)ラッチを開放した後に閉じても次のラッチ開放までレジスタは出力を保持します
結果2 上位(00000001)下位(00000000)になった
8つ右へシフトする事で上位データを下位に持って来ることが出来た
上位データを下位8ビット内に持ってくればshiftOut関数は下位8ビットだけ送信するので上位8ビットを送る事が出来る
その後に下位の8ビットを送信する事でトコロテン式に上位用レジスタへデータを押し出せる
疑問3 どのタイミングで上位レジスタにデータが送られるのか
0000000000000001を出力(LED点灯)させる毎に左へ1ビットずつシフトさせていく
INT A=0b0000000000000001;
for(INT i=0; i<16 ; i++){ i=16になったら{}内命令を辞める→0~15までの16回繰り返し iは1づつ加算される
INT AA=A<<i; Aのデータをiの中の数だけ左にシフト 下位データ用
INT B =AA>>8; 8ビット右にシフト 上位データ送信用
shiftOut(dataPinA, clockPinA, MSBFIRST, B); 上位データ送信
shiftOut(dataPinA, clockPinA, MSBFIRST, AA); 下位データ送信→先に送られた上位データは次のレジスタに移る
結果 普通になんの問題も無く順番に点灯していった
上位→下位の順番さえ守れば直列接続で2バイト(16ビット)データが扱えるみたいです(不思議w)
調子に乗って色々な実験をしているうちに問題も出てきました
見つけた問題点を挙げていくと
問題1 全ビットON(1111111111111111)を送信しても全部のLEDが点灯してくれない
01001110 11101000 の様な感じで表示される(正確な状態は忘れた・・・) いわゆるバグった状態
上位だけ下位だけ全ONは問題ない
最下位ビットだけOFFでも問題はない
全ONの時だけ起こる
問題2 ArduinoのRESETスイッチを押してもレジスタ内データがクリアされず残ってしまう場合がある
少し長めに押せば恐らく大丈夫
 ̄SCLRをVCCではなくArduinoのRESETポートに繋げるとスイッチで確実にクリアされる
上記接続しても内部プルアップでLEDは暗くならないが接続線が1本増える
とりあえずこの2点です
問題2は致命的ではないのですが、問題1の全ONがバグるのは痛い
16x16LED MATRIXを制御する際に全ONが必要になるデータは少ないかもしれないが必要になる時も間違いなくあると思うのでなんとか解決策を見つけたいと思います
一応また再実験しますが、レジスタ全てONでバグるのなら「バグ回避用に3つ目を用意すればいいんじゃね?と考えています
あと、2つ目のQH”出力をGNDに繋げてるのを何も繋げずにとか思いつく限り実験してみます










