c言語を用いてRS232C通信を行うプログラムが安定動作しません。
オシロスコープからの電圧値をpcに取り込むプログラムが必要となり,作成しています。現在,一応のところ送受信が出来ており,希望とする機能は実現できているのですが,しばらくプログラムを動作させていると,以下のような問題が発生します。
・数千件程度データを受信したところでプログラムが完全に応答しなくなる(ウインドウも閉じない,通信用ケーブルを物理的に外すとプログラムの停止は出来ます。)
・プログラム動作中に突然ブルースクリーンになる(エラーメッセージはまだ確認できていません)
使用している環境は以下のとおりです。
OS : win7 32bit
コンパイラ : Borland C++ Compiler 5.5
使用ケーブル : UC-SGT
ソースコードはいかに添付します。
私自身プログラミングには疎く,問題の原因がソフトなのか,ハードなのか検討も付いていない状態です。何かこれらの問題の原因について,気づいた事が有りましたら教えていただけると幸いです。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <process.h>
#include <string.h>
HANDLE h;
//クリップボードへのデータ受け渡し関数
void wclip(char a[]){
HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, 256);
strcpy((LPTSTR)hMem, a);
OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
}
//データ送信用スレッド
void sub( void *dummy ) {
unsigned long nn; char ch1[22]=":MEAS:SOUR1 CH1\n"; char ch2[22]=":MEAS:SOUR1 CH2\n"; char ave[16]=":MEAS:MEAN?\n"; int DataSize; COMSTAT Comstat; // 通信デバイス情報構造体 DWORD dwErrorMask; // エラーコードを受け取る変数 while( 1 ){ DataSize = strlen( ch1 ); //データのサイズ取得 do{ ClearCommError( h , &dwErrorMask , &Comstat ); }while( (128 - Comstat.cbOutQue) <= DataSize ); WriteFile( h, ch2, 22, &nn, 0); do{ ClearCommError( h , &dwErrorMask , &Comstat ); }while( (128 - Comstat.cbOutQue) <= DataSize ); WriteFile( h, ave, 16, &nn, 0); do{ ClearCommError( h , &dwErrorMask , &Comstat ); }while( (128 - Comstat.cbOutQue) <= DataSize ); WriteFile( h, ch1, 22, &nn, 0); do{ ClearCommError( h , &dwErrorMask , &Comstat ); }while( (128 - Comstat.cbOutQue) <= DataSize ); WriteFile( h, ave, 16, &nn, 0); }
}
//メイン文
void main() {
int i=0;
int j;
int ret,count=0,DataSize;
double voltage;
char sBuf[1];
char test[7]= "*idn?\n";
char str[100]; char out[100],output[100]; unsigned long nn; DCB dcb; COMMTIMEOUTS cto; unsigned long dummy; clock_t now; /* ---------------------------------------------- ファイルのクリエイト/オープン ---------------------------------------------- */ // クリエイトしたファイルのファイルハンドラを返す h = CreateFile( "COM3", GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 ); if ( h == INVALID_HANDLE_VALUE ) { printf("Open Error of COM3 Port\n"); } /* ---------------------------------------------- シリアルポートの状態操作 ---------------------------------------------- */ GetCommState( h, &dcb ); // シリアルポートの状態を取得 dcb.BaudRate = 115200; // 速度 dcb.ByteSize = 8; // データ長 dcb.Parity = NOPARITY; // パリティ(Even) dcb.StopBits = 1; // ストップビット長 SetCommState( h, &dcb ); // シリアルポートの状態を設定 /* ---------------------------------------------- シリアルポートのタイムアウト状態操作 ---------------------------------------------- */ GetCommTimeouts( h, &cto ); // タイムアウトの設定状態を取得 cto.ReadIntervalTimeout = 35; cto.ReadTotalTimeoutMultiplier = 0; // 1Byte毎のタイマ cto.ReadTotalTimeoutConstant = 35; // 1関数コール毎のタイマ cto.WriteTotalTimeoutMultiplier = 0; // 1Byte毎のタイマ cto.WriteTotalTimeoutConstant = 0; // 1関数コール毎のタイマ SetCommTimeouts( h, &cto ); // タイムアウトの状態を設定 // スレッド作成と起動 _beginthread( sub, 0, &dummy ); now = clock(); /* ---------------------------------------------- 受信データの読み出し(1行分の文字列) ---------------------------------------------- */ while(1) { ReadFile( h, sBuf, 1, &nn, 0 ); // シリアルポートに対する読み込み if ( nn==1 ) { if ( sBuf[0]==10 || sBuf[0]==13 ) { // '\r'や'\n'を受信すると文字列を閉じる if ( i!=0 ) { str[i] = '\0'; i=0; now = clock(); printf("%5d%10d %s\n",count,now,str); voltage = atof(str); sprintf(output, "%d,%d,%.3f", count , now, voltage * 1000); wclip(output); //クリップボードへ出力 count++; } } else { str[i] = sBuf[0]; i++; } } //ret = PurgeComm( h, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); }
}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/02/08 17:09
2015/02/09 21:00
2015/02/09 23:25