標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第591回]
●受信ERROR
一般にパソコンなどで使われるRS232C通信は調歩同期式といわれる方法です。
英語ですとasynchronousという言葉になります。
これですと非同期という意味になります。
うう。
では調歩同期式つうのは、いったい同期なのか非同期なのか?
その昔、はじめてRS232Cなるものに出会ったときは、大いに迷ったものです。
同期式というからには、送信側と受信側に共通のクロック信号があって、さらにデータの始まりを示す信号などがあって、これに同期してデータを送るから、同期式なのでしょう。
当然、非同期というからには、共通のクロック信号は使いません。
正式のRS232C通信ではデータラインTXD、RXDのほかにもCTS、RTS、DSR、DTRなど多くの制御線を使います。
しかし一般的なパソコン同士のRS232C通信などではそれらの制御線は省略してしまって、データ送信(TXD)、データ受信(RXD)とGNDの3本の線だけで通信を行います。
もしもこちらが送信だけで、相手が受信だけというシステムならば、こちらのTXDと相手のRXDを接続して、GNDを共通にするだけでデータの送信ができてしまいます。
8ビットのデータを1ビットのシリアルに変換して送信するわけですから、データの始まりを示すマークがないことには、受信側で正しく元のパラレルデータに復元することはできません。
そこで、データが送信されていない状態のときは、データラインを1(H)にしておいて、データを送るときには、データの前に1ビットの長さの0(L)を送ります。
これがスタートビットです。
受信側はこのスタートビットの立下りに同期してデータを受け入れます。
しかし、もしも8ビットのデータの最後が0(L)であったとすると、その最後の0とスタートビットの0との境がわからなくなってしまいます。
そこでデータの終わりには、1〜2ビットの長さの1(H)を置きます。
これがストップビットです。
このようにすることで、8ビットのデータを受信し終わると、必ずストップビットが来ますから、そこで次のデータのスタートビットを待つことができます。
送信側と受信側のクロックに多少の差異があっても、8ビットのデータを受信する期間内では、その差異が誤差の範囲内に収まるならば、次のスタートビットの立下りでそのズレは解消されますから、受信側で正しく受信データを復元することができます。
調歩同期という名前は、おそらくスタートビットで足並みを揃えることで同期を取る、ということから名付けられたのではないか、と思います。
asynchronous(非同期)という名前からは、スタートビットで足並みを揃えるという意味は伝わってきません。
いまどきはなんでもかんでも横文字のまま輸入してしまいます。
おそらくアジアでもっとも英語が苦手な国民でしょうにねえ。
そこへいくと我々の先輩達は実にまじめで賢くそしてかつ勤勉でありました。
たったひとつの外国語でさえ、実に丁寧に日本語(実はたいていは漢字なのですが)に翻訳する努力を惜しみませんでした。
調歩同期式のRS232Cデータ信号については、[第188回]のあたりで説明をいたしました。
そこでの説明図をちょっと引用しましょう。
文字AのASCIIコード(41)の送信波形の説明図です。
41は、01000001です。
そのようにビットで表現するときは一般にビット7が左で、ビット0が右になるように表記します。
しかしRS232Cで送信するときの波形は、その表記とはちょうど正反対になります。
ビット0から送信するからです。
●フレーミングエラー(framing error)
またまたえらく前書きが長くなってしまいました。
調歩同期式がそのようなデータの同期方式であることがわかりますと、受信エラーについても自然に理解ができるようになります。
通信時にたまたま信号ラインに強力なノイズが乗ってしまったためにエラーが発生するというようなことも考えられますが、調歩同期式で普通に通信しているときには、突発的なエラーを検出することはできません。
そのようなエラーを検出するためには、パリティビットを追加して9ビットのデータにして送信するとか、データ全体を加算してチェックサムを照合するなどの対策を取ります。
PIC18F14K50のRS232C受信でハードウェアが検出する受信エラーは、もっと根本的なものです。
たとえば送信側が4800ボーで送信しているのに、受信側の設定が9600ボーであったとすると、結果はどうなるでしょう?
おそらくまともに受信できそうにない、ということは容易に想像がつくと思います。
さきほどの送信波形の図で説明をしましょう。
送信側は4800ボーなのに受信側が9600ボーの設定になっていたとすると、上の図の上側の波形が送信波形のとき、受信側の信号のタイミングは下の波形で示されます。
ビットの長さがちょうど半分になります。
そうすると受信データは、ビット0から順に、01100000になりますから、送信データの41だったものが、06に化けてしまいます。
このとき最後のストップビットのところを見ますと、0(L)になっています。
調歩同期式のルールではデータの最後は必ずストップビット(H)が来るはずなのですが、それがありません。
これは明らかに信号に異常があることになりますから、このとき受信エラービットがONになって、受信が打ち切られます。
これがフレーミングエラー(framing error)といわれるエラーです。
決められたワク(frame)から逸脱している、という意味でしょう。
これも容易に想像できますように、送信側と受信側とでボーレートが異なっていても、たまたまストップビットの位置に1(H)が検出されればエラーにはなりません。
まあ、送信するデータの全てがそのようにたまたまストップビットの位置が1(H)になっている、などということは滅多にあることではありませんが、送信するデータ数が少ないときなどですと、ひょっとするとエラーにならないで受信が完了してしまうかもしれません。
エラーにはならなかったとしても、当然受信したデータは元の送信データとは異なったものになってしまいます。
●オーバーランエラー(overrun error)
PIC18F14K50のRS232C受信で発生するエラーには、フレーミングエラーとは別のエラーがもうひとつあります。
オーバーランエラーです。
PIC18F14K50のRS232C受信では、受信バッファに2バイトのデータを置くことができます。
あ。
この受信バッファは私がプログラムで設定した割り込み受信のデータバッファのことではなくて、標準でハードとして内蔵している受信バッファのことです。
PIC18F14K50は、RS232C受信データを2バイトのFIFO受信バッファに格納します。
格納された受信データはプログラムによって速やかに引き取らなければいけません。
もしプログラムが受信バッファのデータを引き取るのが遅れて、そこに3バイト目のデータが受信されてしまうと、もう受信データの置き場がありません。
このときオーバーランエラービットがONになって、受信は打ち切られます。
●受信ERROR信号
フレーミングエラーもオーバーランエラーも、これはもうあってはならないエラーですから、必ずZ80CPU側に伝えなければなりません。
そこでエラーの発生を伝えるために独立した1本の出力ラインを割り当てました。
MYCPU80ではその出力にLEDをつないでいます。
この回路図は[第589回]でもお見せしたND80ZVのI/OインターフェースのうちのPIC18F14K50を中心にした部分の、さらにその一部のみを切り取って示したものです。
PIC18F14K50のRC4(pin6)がERROR信号出力です。
当初はエラーが発生したら、このラインの出力をLにする、というだけのものでした。
エラーインジケータのようなものです。
しかしその後に、Z80BASICでRS232C受信プログラムを書いて、その動作テストをしているときに、受信エラーが発生したのですが、そのときはただBASICの受信エラーを示すコードが表示されるだけでしたから、そのエラーがどういうエラーなのかがわからなくて、その原因を特定することができませんでした。
そこで、そのエラーの原因を特定するために、それまでは受信エラーが発生したときに、ただ受信ERROR信号が出力されるだけだったものに、少し手を加えて、エラーの内容もわかるようにPIC18F14K50のプログラムを変更しました。
そのあたりの経緯につきましては[第569回]に書きました。
受信エラーが発生したときに、受信ERROR信号を出力するだけではなくて、そのときにはどうせ受信データは使い物にはなりませんから、受信データの代わりに、エラービット情報も出力するように変更したのです。
PIC18F14K50のRS232C受信時のエラー情報は、RCSTAレジスタのビット1、ビット2にセットされます。
[出典]MICROCHIP社PIC18F14K50DataSheet
bit1がオーバーランエラーで、bit2がフレーミングエラーです。
PIC18F14K50がZ80CPUに受信エラーが発生したことを知らせるために、受信エラー出力をLにするとともにデータとして出力することにしたエラー情報は、RCSTAのエラービットと同じにしました。
すなわち、
オーバーランエラーのときは、データとして02(00000010)を出力し、
フレーミングエラーのときは、データとして04(00000100)を出力することにしました。
2010.8.24upload
前へ
次へ
ホームページトップへ戻る