WIN2000でのRS232C通信

[戻る]
hiro 2001/10/15(月) 08:34:17
はじめまして、hiroと申します。
いま、RS232Cで通信を行っていてwin98,NT4.0では問題無く動作するのですが
win2000では動作しませんでした。

ソースは

SetCommMask( m_hCom, EV_TXEMPTY );
EscapeCommFunction( m_hCom, SETRTS );

Sleep( 5 );
    
success = WriteFile( m_hCom, Sbuf, i+2, &n_Write, NULL );
    
while( Event != 4 )
    WaitCommEvent( m_hCom, &Event, NULL);

if( success )
    EscapeCommFunction( m_hCom, CLRRTS );

こんな感じです。
データを送信してWaitCommEventで送信完了を待ちRTS信号を消すといった処理なのですが
オシロスコープで調べたところwin2000ではデータを送信し始めてすぐRTS信号が消えています。
2000ではWaitCommEventの処理が変わったのでしょうか?
ちなみにFlushFileBuffers関数をいれても変化無しでした。

どんな些細なことでも良いので教えていただけたら幸いです。

2001/10/15(月) 11:45:12
> while( Event != 4 )
この部分を
while(Event == EV_TXEMPTY)
としてみてはどうでしょう?

ちなみに、
EV_TXEMPTY : 出力バッファの最後の文字を送信した。
のはずです。

hiro 2001/10/15(月) 11:58:45
さっそくのレスありがとうございます。

while( Event != 4 )
4というのはEV_TXEMPTYのことで
whileでまわしてEV_TXEMPTYビットがたった(出力バッファの最後の文字を送信した)ら
whileを抜けろという処理を行っています。

ですがこの処理がwin98,nt4.0では正常に「出力バッファの最後の文字を送信した」ら
RTS信号が落ちているのですが
win2000では最初のデータビットを送信し始めでEV_TXEMPTYビットがたってしまい
RTS信号が落ちてしまいます。

win2000では通信処理が変わったのでしょうか?

2001/10/15(月) 12:38:56
基本的に EV_TXEMPTY == 4 となることは保証されていません。
(Win98,NT4では偶々4となるだけだと思います)
また、XPになると変わるかもしれない、他の人が見た時に(自分自身でも)何を意味するのか
わからない場合が多々ありますので、数値を直接書く事は避けた方が無難だと思います。

hiro 2001/10/15(月) 13:14:45
ご指摘ありがとうございます。
たしかにわかりにくいので変更いたします。

クラフトマン 2001/10/15(月) 21:03:25
hiro様、ご存知ではなくてされたと思いますので、一言だけご忠告させてください。
この件に関しては、VC++超初心者のホームページにも投稿されてますね。
こういうのは、マルチポストといって、嫌われる行為です。
さらに、while( Event != 4 ) で即値を書いている件については、あちらのページ
で、私がご指摘させていただいており、hiro様自身が「修正します」と返答されてい
ますね。なのに、ここでも全く同じ投稿をしています。
どうしてもマルチポストしなければならないのであれば(そういった理由はめったに
ないはずですが)、せめて、これまでの別のページでの経緯を説明しておくべきだと
思います。
ここと、あちらと両方のページをチェックされている方はたくさんいらっしゃると
思います。
ほんの少しの気配りをするだけです。よろしくお願いします。

hiro 2001/10/16(火) 10:58:51
クラフトマン様。
while( Event != 4 ) で即値を書いている件、これはわたしの不精でカットアンドペーストをつかったために
書いてしまいました。これについては弁解の余地はありません。大変申し訳ありませんでした。
マルチポストの件では私も存じておりますが私が思うマルチポストは同時刻に多数の掲示板に
同様の質問を書くことと考えております。
今回はVC++超初心者での投稿で回答が得られなかったため(クラフトマン様お気を悪くされたら申し訳ありません。
クラフトマン様には大変感謝しています。)向こうではこれ以上レスもつかないと思いこちらで投稿いたしました。
たしかにここと、あちらと両方のページをチェックされている方はたくさんいらっしゃると思います。
ですがそれ以上にこちらだけ、あちらだけの人も多いと思います。
それでこちらでは回答が得られるのではないかと思い投稿いたしました。
これは私の考えですが私は教えてもらう立場なので大きいことはいえませんが。

今回の件でお気を悪くされた方がいたら大変申し訳ありませんでした。

Bun 2001/10/16(火) 12:54:19
わても両方に顔出してまっす。(^^;

ロジックとしては
「送信エンプティビットが立つまで待つ」ってーことではないでしょーか?
動くかどうかは別にしてマスクをかけるべきでは?

while((Event & EV_TXEMPTY) == 0)
    WaitCommEvent( m_hCom, &Event, NULL);

これではどーでしょか?

hiro 2001/10/16(火) 13:58:25
BUN様もありがとうございます。

ロジックは仰られる通りです。
ですがご指摘の方法でも変化はありませんでした。
WaitCommEventがWriteFileして最初のビットを送信し始めてからほぼ素通りで「送信エンプティビットが立てています」
WIN2000ではWaitCommEventが正常に動作しないかもしれません・・・・。

Bun 2001/10/16(火) 14:08:11
スリープで時間待ちはだめっすかね?

9600bpsの場合1バイトを送るのに約1msecかかります。

tw = バイト数×10×(1/9600)でおおまかな伝送時間が
計算できますよね。

×10は
スタートビット 1
ストップビット 1
データ     7
パリティ    1 の場合です。

while((Event & EV_TXEMPTY) == 0)
    WaitCommEvent( m_hCom, &Event, NULL);

Sleep(tw+n); // nは余裕を持たせるための時間

EscapeCommFunction( m_hCom, CLRRTS );

これだとデータは出力されるのでしょうか?

Bun 2001/10/16(火) 14:14:00
間違えました。
>Sleep(tw+n); // nは余裕を持たせるための時間

Sleep(tw/1000 + n); // nは余裕を持たせるための時間 [msec]
でした。

hiro 2001/10/16(火) 14:18:47
Sleepもなんどか試したのですがバイト数に応じて成功する時としないときがあります。
Sleepではミリ秒(ms)単位ですのでバイト数が細かく変わった時に対応できませんでした。
あと、Sleepではパソコンの処理の重さや、相手側の通信状況によって微妙にずれてきますので
使えないと思います。
素早く案をだしていただき申し訳ないのですが。

2001/10/16(火) 16:52:39
> while((Event & EV_TXEMPTY) == 0)
この部分ですが、

while((Event & EV_TXEMPTY) == EV_TXEMPTY))
ではないでしょうか?

2001/10/16(火) 16:55:20
> while((Event & EV_TXEMPTY) == EV_TXEMPTY))

while((Event & EV_TXEMPTY) != EV_TXEMPTY))

の誤りです。m(__)m

Bun 2001/10/16(火) 17:03:47
重さん こんにちは。

>while((Event & EV_TXEMPTY) == EV_TXEMPTY))
>ではないでしょうか?

私の手元の資料では
EV_TXEMPTY 意味「出力バッファの最後の文字を送信しました」 とあります。

WriteFile()した時点ではこのビットは立たないはず。

ですから
while((Event & EV_TXEMPTY) == 0)

でエンプティビットが立つまでWaitCommEvent()するのが正しいのではないでしょうか?

最後の文字を送信したらループを抜けたいのでは?
いかがでしょうか?

Bun 2001/10/16(火) 17:07:20
あぁ、入れ違い。

> while((Event & EV_TXEMPTY) != EV_TXEMPTY))
> の誤りです。m(__)m

そうですね。
こちらがベストですね。

hiro 2001/10/17(水) 09:33:55
重様もありがとうございます。

while((Event & EV_TXEMPTY) != EV_TXEMPTY))
while((Event & EV_TXEMPTY) == 0)
でもWIN98では問題なく動作しましたが2000ではだめでした。

WaitCommEventを使わずに行う処理を考えた方がいいかもしれませんね。
FlushFileBuffersではだめでしたが・・・。
他の使える関数がないか調べたいと思います。

古いスレッドには追加発言できません。