シリアル通信で常にコマンドを受信し続けるには?

解決


ヨシ  2006-09-20 03:13:04  No: 63040

いつもお世話になります。
現在、↓の環境下で開発中ですが、わからないことが出てきたので質問させてください。
Windows XP Professional Version 2002 Service Pack2
Microsoft Visual Studio .NET 2003
MFC Application

【やりたいこと】
シリアル通信を使って送受信を行いたい。
そのとき、転送先からは常に文字が出力されているので、PC側で常にその文字を受信し、アプリ上に出力させたい。
そして、PC側から送信したい場合は、受信中でもその合間をぬって文字を転送したい。

【現状】
下記プログラムのsend()、receive()を使い、送信・受信それぞれ単体であれば動かすことはできます。
ボタンにイベントハンドラを割り当てて、そこから関数を呼ぶことで実現させています。

アプリ起動時に受信を開始するとして、起動時に呼ぶ関数内でreceive()をroopさせれば常に受信させることはできるのかと思いますが、それでは、メインの方に処理が返ってこず、次の送信処理に移行することができません。

何かいい方法はあるのでしょうか?
どなたかご教授宜しくお願いいたします。

HANDLE hComm=NULL;
char buff[20];

void comset(){
      -------------略-------------
  hComm = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 
                0, NULL, OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL, NULL);

  //COM通信パラメータを格納しているDCB構造体を設定する。
  DCB lpDCB;
  GetCommState(hComm, &lpDCB);
  //if(GetCommState(hComm, &lpDCB)==0)return;

  lpDCB.DCBlength = sizeof(DCB);
  lpDCB.BaudRate = 9600;
  lpDCB.Parity = NOPARITY;
  lpDCB.StopBits = TWOSTOPBITS;
  lpDCB.fParity = FALSE;
  lpDCB.fBinary = TRUE; 
  lpDCB.ByteSize = 8;
      -------------略-------------
}

void send()
{
  DWORD dw;

  WriteFile(hComm,"hoge",4,&dw,0);

  return;  
}

void receive(void)
{  
  DWORD dw;
  ReadFile(hComm,buff,20,&dw,0);
  return;
}


tetrapod  2006-09-20 19:49:40  No: 63041

まあ普通はマルチスレッド構成にして
UIスレッド+送受信スレッド(もしくは送信スレッド+受信スレッド)
のように組みます。そのほうが結果的に簡単だし応用も利く。

WM_TIMER で非同期I/O(FILE_FLAG_OVERLAPPED)するって手もあるけど
俺のお勧めはマルチスレッド
MSDNサンプルMTTTY
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp


ヨシ  2006-09-20 20:02:22  No: 63042

回答ありがとうございます。

マルチスレッドという言葉、よく耳にします。
今、ざっといろんなHPを見ていたのですが、マルチスレッドって結構難しそう。。初心者ゆえに少し不安になってしまいました。

ちょっと勉強してみようと思います。
何か参考になるHPとかあったら教えてくださいm(__)m

また、今は一番手軽な方法で実現できればいいかなー。と考えているので、ほかにも方法ありましたら教えてください!


tetrapod  2006-09-20 22:10:54  No: 63043

だから一番手軽なのはマルチスレッド
次に WM_TIMER

WM_TIMER で実装する例の簡単な解説
OnStart() みたいな開始処理で
・ReadFile や WriteFile を呼ぶと終了するまで停止する→UIも停止
  がまずいので、停止しないよう CreateFile のフラグとして
  FILE_FLAG_OVERLAPPED を使う (OVERLAPPED も用意する)
OnTimer() で
・WriteFile/ReadFile が未発行なら、発行する
・発行済みなら GetOverlappedResult で結果を見る
・結果が得られていれば送/受信完了処理の後、未発行に戻してOnTimer終了
・結果が得られていなければ、なにもしないでOnTimer終了

WM_TIMER で作ったことは無いので上記は案だけです。


ヨシ  2006-09-20 23:26:26  No: 63044

回答ありがとうございます。

チャレンジしてみて、また連絡します。

またわからなかったらご教授宜しくお願いします。


ヨシ  2006-09-29 00:42:50  No: 63045

遅くなって申し訳ありません。
マルチスレッドを使って表題の問題を解決することができました。

ご指導ありがとうございました。

今後とも宜しくお願い致します。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加