標準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

前へ
次へ
ホームページトップへ戻る