前回つくった UART 受信回路を、一部変更しました。変更部分を記録しておきます。
変更したのは 2箇所です。ひとつは、ボーレート誤差があって連続したスタートビットが早く届いた場合への対応。もう一つは、シフトレジスタ 74HC595 の初期化回路の追加です。
タイミングダイヤグラム
タイミングダイヤグラム (図1) です。ストップビット SP の受信後すぐに受信動作を停止して、次のスタートビットを待つようにしました。
カウンタは、初期値 0x61 からスタートし、0xf8 で 10個目のシリアルクロック SCK が立ち上がったら動作を停止し待機します。こうすることで、スタートビットが早くきても受信することができます。短縮した時間は 5%ですので、通常のボーレート誤差 2~3%以内であれば対応できると思います。
スタートビット、ストップビット付近の拡大図 (図2) です。
スタートビット付近は変更ありません。
ストップビット付近。前回はカウント 0xff で停止していました。変更後は、カウント 0xf8 で停止信号 SUPPR を出力してカウンタを停止、次のスタートビットを待ちます。SCK の幅が 1クロック分になりますが、必要なのは立ち上りエッジですので、問題はありません。
ブロックダイヤグラム
ブロックダイヤグラム (図3) にシフトレジスタ初期化回路を追加しました。
回路図
初期化回路
クロック発振回路
スタートビット検出回路
初期化回路、クロック発振回路、スタートビット検出回路に変更はありません。詳細は前回記事を参照ください。
シリアルクロック発生回路
9600Hzの 10個のパルスを出力するパルストレイン回路 (図7) です。カウント動作の停止タイミングを変更しました。
変更点は 1箇所。下位カウンタ U9 のキャリー COU9 を、上位カウンタ U7 のイネーブルプリセット ENP につないでいます。
U9 の COU9 を U7 のイネーブルトリガ ENT につないだ場合、U7 のキャリー COU7 は 0xff で出力されます。これを ENP に変更すると、COU7 は U7 が 0xf のとき、すなわち 0xf0~0xff 間で出力されるようになります。そこで、COU7 とシリアルクロック SCK の AND (U6B) をとれば、カウント 0xf8 で停止信号 SUPPR を出力できます。
シフトレジスタ初期化回路
前回、どうしようかなぁと考えていたシフトレジスタの初期化ですが、図8 の回路を追加しました。電源オン時にシフトレジスタ 74HC595 を初期化します。
電源オン後、100ms 遅延して初期化信号 CLR が HIGH に立ち上がります。これを RCLK としてストレージレジスタを初期化します。
その後、10μs 遅延してアウトプットイネーブル OE を LOW にし、ストレージレジスタの出力を有効にします。
カウンタ停止信号 SUPPR は通常の RCLK として入力されます。
データ受信回路 (シリアル・パラレル変換)
シフトレジスタ初期化回路の追加に伴い、シフトレジスタ 74HC595 の入力信号を変更しました。
変更した入力信号は RCLK と OE で、どちらもシフトレジスタ初期化回路から受けます。
74HC595 の初期化は、まず CLR (SRCLR) を LOW にしてシフトレジスタを初期化、つぎに RCLK を立ち上げてストレージレジスタを初期化、最後に OE を LOW にしてストレージレジスタ出力を有効にします。このシーケンスをシフトレジスタ初期化回路が行ないます。
テスト用周辺回路
テスト用のデータ表示 LED回路、バッファレジスタ回路、テスト信号発生回路については変更ありません。前回記事を参照してください。
Arduino Nano Every からテスト用シリアル通信信号を出力するスケッチですが、受信回路が起動しないうちに送信を開始してしまうので、待ち時間を設けました。5行目を追加しています。
- void setup() {
- // Serial.begin(9600); // Connect to serial monitor
- Serial1.begin(9600, SERIAL_8N1); // Connect to TxD(D0) pin
- delay(500); // Waiting to start
- }
- void loop() {
- for (byte value = 0x00; value <= 0xff; value++) {
- // Serial.println(char(value));
- Serial1.write(value);
- Serial1.print('\r'); // CR 0x0d
- Serial1.print('\n'); // LF 0x0a
- delay(500);
- }
- }
後記
今回は、前回つくった UART受信回路の変更箇所をまとめておきました。Arduino から受信するってことに限ればどっちでもいいやんって感じですけど、まぁ気になったところはやっぱり修正しておきたいかな、と。
ちなみに、しばらくの間 Arduino Nano Every からのシリアル通信を受けて動作テストしていたのですが、ボーレート誤差もないし、スタートビット検出回路の誤動作 (メタステーブルの発生) もありませんでした。当初思っていたより安定してるんで、とりあえず満足してます。
で、じつは送信回路もできあがりました。送信回路は簡単だよねぇって思ってたんですけど、シフトレジスタの制御シーケンスにちょっと悩みましたです。また、ぼちぼちと記事まとめます。