標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第569回]
●なぜか受信バッファがオーバーフローしてしまいます
ND80ZVのZ80BASICで簡単なRS232C受信プログラムを実行して、そこに短いテキストファイルのデータを送信したところ、無事うまく受信して、そのデータをPRINT文で、WindowsのDOSプロンプト画面に表示させるところまではなんとかできました。
PRINT文はデータをUSB経由でWindowsパソコンに送って、そこでDOSプロンプトの画面に表示させます。
ところがもう少し大きいサイズのデータを、Borland C++で作ったRS232C送信プログラムで、ND80ZVに送信しようとしましたら、「不正な処理」メッセージが出されてしまいました。
これはRS232C送信プログラムでデータを送信するときに、標準の送信バッファの容量を越えるサイズのデータをWriteFile()関数に与えてしまったためでした(多分)。
そこで送信データを1000バイトずつに区切ってWriteFile()関数に渡すようにしたところ、「不正な処理」メッセージは出なくなりました。
というところが、前回までに説明しました内容です。
これで全てうまくいってくれれば、めでたしめでたし、なのですけれど、世の中というものは、そこまで甘くはないのですよねえ。
送信側は「不正な処理」メッセージも出なくなって、エラーなく送信を完了してくれるようになったのですけれど。
今度は受信側でエラーが発生してしまいました。
logfile nd80zlog\07300945.txt open ND80ZVに接続しました 0001 0000 - z 1000 00C3 - *** nd80z3 basic **** >h. TEXT 8004-8073 ヘンスウ DE47-DFFF >. 10 A%=0 20 READ #1,A$,A% 30 IF A%<1 GOTO 20 40 PRINT A$,"a%=";A% 50 GOTO 10 >r. /// w232.cpp for mycpu 09/03/13 3/20 a%=37 #include <windows.h> a%=20 #include <stdio.h> a%=18 // a%=2 FILE *rfp; a%=11 char outbf[300]="\0"; a%=22 char comname[5]="\0"; a%=22 char *fname; a%=13 int dtbyte=0;a%=14 int e; a%=7 unsigned long int dwWrite;a%=27 HANDLE hcom; a%=13 int open(); a%=11 int write(); a%=12 int close(); a%=12 // a%=2 oid main(int argn,char *args[]) a%=31 name=args[1];a%=13 /file open a%=10 f(!(rfp=fopen(fname,"r")))a%=26 {printf("can't open %s\n",fname);}// paa%=40 s to end a%=8 ERR:73 20 READ #1,A$,A% >/exit 0000 00C3 - ndremote.exeを終了しました logfile closed at Fri Jul 30 09:47:05 2010
ERR:73が表示されています。
232C受信エラーです。
でもこれだけでは何がおきたのかわかりませんから、PIC18F14K50のプログラムを少し直して、エラーの種類もわかるようにして、確認をしてみました。
その結果、受信バッファのオーバーフローであることがわかりました。
PIC18F14K50はRS232C受信を割り込み処理で行っています。
受信したデータは割り込みプログラムによって、PICの内蔵メモリ上に設けた256バイトの受信バッファに書き込まれます。
Z80BASICの側は、READ #1命令を実行したときに、PIC18F14K50に対して、受信バッファのデータを渡すように要求します。
RS232Cのボーレートは9600ボーなので、これはスタートビットとストップビットを計算に入れると、960バイト/秒の速度です。
約1バイト/1msecの速度ですから、バッファがオーバーフローするまでに260msecほども時間があります。
いくらなんでもPIC18F14K50とZ80CPUの間のデータの受け渡しに1バイト1msecもの時間がかかるなどということはありえません。
ええ。
大体のところはつかんでいるのです。
もしPRINT文を実行しないで、たとえば受信したデータを配列に格納してしまって、全部受信し終わってから、それをPRINT文で表示させるようにすれば、ERR:73は発生しないのです。
問題はPRINT文にあるようです。
しかし、しかし、PRINT文はUSB(HID)経由でWindowsパソコンにデータを送りますが、その速度は1回の送信あたり、1msecです。
それじゃRS232Cと同じじゃないの?
いや、それは違います。
RS232Cは9600ボーのとき、1バイトの受信に約1msecかかりますが、USB(HID)の送信は1回あたり64バイトのデータを送ることができますから、速度が違います。
もっとも、つねに64バイトフルに送っているか、というと当然ロスはあるわけなのですが…。
そういえば、画面の表示が異常に遅いのですよねえ。
確かにそこのところが気にかかります。
一体何がおきているのかもう少し詳しくしらべてみよう、ということで、Z80CPUとPIC18F14K50の間のデータのやり取りの状況をオシロで確認してみることにしました。
そうしましたら…。
な、なんと、とんでもないことがわかってしまいました。
上側(CH1)は、PRINT文の実行時にZ80CPU側から、PIC18F14K50にデータを送出するときのSTROBE信号です。
下側(CH2)は、PIC18F14K50がそれに応答するREADY/BUSY信号です。
STROBE信号がほとんど下がりっぱなしじゃありませんか。
この間は、PIC18F14K50の応答を待っているのです。
PIC18F14K50が応答するのに1秒もかかっています!?
ああ。
時間がなくなってしまいました。
この続きはまた次回にいたします。
2010.7.31upload
前へ
次へ
ホームページトップへ戻る