掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
RS232Cの制御電文におけるBCC(Block Checking Code)算出について (ID:150642)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
takeさん 本当にありがとうございます。 わたしもTCommコンポーネントの挙動を確認していました。 Openすると、直ぐに抜けてしまうので(最初のif文:if FHandle < 0 then)、CreateFileが実行されないのが原因なのでしょうかね。 ※FHandleの値の初期値は0です 尚、Writeメソッドの内容もこちらで改ざんされてしまっている模様です。すみません。 <Comm.pas抜粋> { 通信ポートのオープン } procedure TComm.Open; var szPort: array [0..9] of Char; // ポート名 CommTimeouts: TCommTimeouts; // タイムアウト構造体 begin if FHandle < 0 then // 通信中でない時 begin FReadOs.Offset := 0; // 受信オーバーラップ処理用 FReadOs.OffsetHigh := 0; // イベントオブジェクトの作成 FReadOs.hEvent := CreateEvent(nil, // ハンドルを継承しない True, // 手動リセットイベント False, // 非シグナル状態で初期化 nil); // イベントオブジェクトの名前 if FReadOs.hEvent = 0 then raise ECommOpenError(-2); // イベントが作成できない FWriteOs.Offset := 0; // 送信オーバーラップ処理用 FWriteOs.OffsetHigh := 0; // イベントオブジェクトの作成 FWriteOs.hEvent := CreateEvent(nil, // ハンドルを継承しない True, // 手動リセットイベント False, // 非シグナル状態で初期化 nil); // イベントオブジェクトの名前 if FWriteOs.hEvent = 0 then begin CloseHandle(FReadOs.hEvent); // 受信用イベントのクローズ raise ECommOpenError(-3); // イベントが作成できない end; StrPCopy(szPort, 'COM'+ IntToStr(FPort)); // ポート名の作成 FHandle := CreateFile(szPort, // ポート名 GENERIC_READ or GENERIC_WRITE, 0, // 排他的使用(*) nil, // セキュリティー属性なし OPEN_EXISTING, // 既存(*) FILE_ATTRIBUTE_NORMAL or // 通常 FILE_FLAG_OVERLAPPED, // オーバーラップ入出力 0); // テンプレートなし(*) if FHandle < 0 then // エラー発生時 raise ECommOpenError.Create(FHandle); // 例外の生成 // 送受信バッファーサイズの設定 SetupComm(FHandle, FInQueueSize, FOutQueueSize); // すべてのバッファー情報を破棄する PurgeComm(FHandle, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR); // タイムアウトのセットアップ CommTimeouts.ReadIntervalTimeout := MAXDWORD; CommTimeouts.ReadTotalTimeoutMultiplier := 0; CommTimeouts.ReadTotalTimeoutConstant := 1000; CommTimeouts.WriteTotalTimeoutMultiplier := 0; CommTimeouts.WriteTotalTimeoutConstant := 1000; SetCommTimeouts(FHandle, CommTimeouts); // 通信環境の設定 SetBaudRate(FBaudRate); // 通信速度 SetByteSize(FByteSize); // データビット数 SetParityBits(FParityBits); // パリティービット数 SetStopBits(FStopBits); // ストップビット数 SetFlowControls(FFlowControls); // フロー制御 SetReceiveNotifySize(FReceiveNotifySize); SetSendNotifySize(FSendNotifySize); SetEventMask(FEventMask); // イベントマスク FThread := TCommWatch.Create(Self, FHandle); // 受信監視スレッドの起動 EscapeCommFunction(FHandle, SETDTR); // DTRをオンにする end; end; { データの送信 } procedure TComm.Write(const Buffer; Size: Integer); var dwError: DWord; Stat: TComStat; dwBytesWritten: DWord; begin if FHandle < 0 then raise ECommError.Create('通信が開始されていない。'); if FOutQueueSize < Size then raise ECommError.Create('送信データ長が長すぎる。'); repeat // 送信キューが空くのを待つ // Application.ProcessMessages; // これがあると送信が逆転する ClearCommError(FHandle, dwError, @Stat); until (FOutQueueSize - Stat.cbOutQue) >= Size; if not WriteFile(FHandle, Buffer, Size, dwBytesWritten, @FWriteOs) then begin if GetLastError = ERROR_IO_PENDING then // オーバーラップ処理時 begin while not GetOverlappedResult(FHandle, FWriteOs, dwBytesWritten, True) do begin if GetLastError = ERROR_IO_INCOMPLETE then // まだ完了しない Continue else begin ClearCommError(FHandle, dwError, @Stat); Break; end; end; end else begin // その他のエラー発生 ClearCommError(FHandle, dwError, @Stat); raise ECommReadWriteError.Create(dwError); end; end; end;
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.