• 締切済み

Win32でシリアル通信

現在.NET2003のWin32を使ってシリアル通信を行うプログラムを作成中なんですが、CreateFile()、WriteFile()といった関数を使っているのですがどうもうまくいきません。 どなたかWin32について詳しい方、ご教授頂けないでしょうか?また、こういった事が書いているHP等をご存知の方教えて頂けないでしょうか? ちなみに、ポートを開く部分は下記のようになっているのですが、何か間違いがあれば教えて下さい。 お願い致します。 /* シリアルポートを開く */ BOOL SerialOpenPort(int nPortNumber) { char szSerial[256]; if(g_ahSerial[nPortNumber - 1] != NULL) { return FALSE; } sprintf(szSerial, "COM%d", nPortNumber); g_ahSerial[nPortNumber - 1] = CreateFile( szSerial, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );   if(g_ahSerial[nPortNumber - 1] == INVALID_HANDLE_VALUE) { g_ahSerial[nPortNumber - 1] = NULL; return FALSE; } if(!InitDCB(nPortNumber)) { return FALSE; }  if(!InitCommTimeOuts(nPortNumber)) { return FALSE; }  return TRUE; }

みんなの回答

  • JJsoft
  • ベストアンサー率21% (8/38)
回答No.2

「InitDCB」や「InitCommTimeOuts」は自作の関数ですよね?なのでこのソースだけでは分かりません。とりあえずCreateFile関数は合っているようです。

  • noocyte
  • ベストアンサー率58% (171/291)
回答No.1

> どうもうまくいきません。 もっと具体的に書いていただかないと,答えようがありません. それにソースも,CreateFile() しているところしかわかりませんし. > また、こういった事が書いているHP等をご存知の方教えて頂けないでしょうか? とりあえず "WaitCommEvent" あたりで検索してみては? "WaitCommEvent" で Google 検索 http://www.google.co.jp/search?sourceid=navclient-ff&ie=UTF-8&rls=GGGL,GGGL:2006-34,GGGL:ja&q=WaitCommEvent ↓こんなの見つかりました. シリアルポートによるデータ送受信プログラム (3) - イベント駆動 I/O http://www.lares.dti.ne.jp/~parasa/200107.html WindowsでRS232Cを使う http://members.jcom.home.ne.jp/0434383301/vc10.htm TComm2 の仕組み (Borland C++Builder 用シリアル通信コンポーネントライブラリ) http://www.wakayama-u.ac.jp/~miw/BCB/TComm/About_TCommPort.html

関連するQ&A

  • シリアル通信について。

    PICからPCにデータ(電圧:最大値5)を受信させようとしています。 受信には C++を用いたプログラムを自作したいのですが、 どうしてもうまくいかなかったため投稿させていただきました。 症状としては、まずポートを開く事すら出来ていません。 RS232c {USBで変換) が接続されているポートはCOM1です。 ポートが開くか確かめるプログラムとしては、次のようなソースを使いました。 #include<windows.h> #include<iostream> using namespace std; int main(void){ HANDLE hCom; hCom = CreateFile( (LPCWSTR)"COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hCom == INVALID_HANDLE_VALUE) { cout<<"シリアルポートを開くことが出来ませんでした。\n"<<endl; return false; } CloseHandle( hCom ); return 0; } これを実行すると「シリアルポートを開くことが出来ませんでした。」としかなりません。 ( (LPCWSTR)"COM1"となっているのは、「'CreateFileW' : 1 番目の引数を 'const char [5]' から 'LPCWSTR' に変換できません。」  と出てしまったためです。) ハイパーターミナルを用いてCOM1からデータを受信できていることは確認しましたので、 通信が出来ていないわけではないようなのです。 ありふれた質問である事は重々承知の上ですが、 このソースでシリアルポートが開けない理由を教えていただければ幸いです。 環境:Visual C++ 2008 Express Edition Microsoft Windows XP Version 2002 Service Pack 3

  • PICとPCでのシリアル通信

    PICとPC間でのシリアル通信を行ってるんですけどうまくいきません。ハイパーターミナル使えばうまくいくんでPIC側のソース(C)はうまくいってると思います。ハイパーターミナルを使わずにシリアルの送受信のプログラム(C++)を組んでるんですけどうまくいかなくて。。。 アドバイスなどお願いします!!どこが違うんでしょうか。。。 ●PC側のソース(C++) #include "stdafx.h" #include <stdlib.h> #include <windows.h> #include<iostream> using namespace std; #define COM_PORT_NAME "COM1" #define BAUD_RATE 9600 #define BYTE_SIZE 8 #define PARITY EVENPARITY #define STOP_BIT TRUE #define F_PARITY ONESTOPBIT HANDLE hComm; // シリアルポートとの通信ハンドル bool ComInit() { // シリアルポートを開ける hComm = CreateFile( COM_PORT_NAME, /* シリアルポートの文字列 */ GENERIC_READ | GENERIC_WRITE, /* アクセスモード:読み書き */ 0, /* 共有モード:他からはアクセス不可 */ NULL, /* セキュリティ属性:ハンドル継承せず */ OPEN_EXISTING, /* 作成フラグ: */ FILE_ATTRIBUTE_NORMAL, /* 属性: */ NULL /* テンプレートのハンドル: */ ); if (hComm == INVALID_HANDLE_VALUE) { printf("シリアルポートを開くことが出来ませんでした。\n"); return false; } // 通信属性を設定する DCB dcb; GetCommState(hComm, &dcb); /* DCB を取得 */ dcb.BaudRate = BAUD_RATE; dcb.ByteSize = BYTE_SIZE; dcb.Parity = PARITY; dcb.fParity = STOP_BIT; dcb.StopBits = F_PARITY; SetCommState(hComm, &dcb); /* DCB を設定 */ return true; } void ComEnd() { // ハンドルを閉じる CloseHandle(hComm); } bool WriteData(char *buff, unsigned int data_size) { DWORD dwWritten; /* ポートへ書き込んだバイト数 */ WriteFile(hComm, buff, data_size, &dwWritten, NULL); if (dwWritten!=data_size) { printf("データの送信に失敗しました。\n"); return false; } return true; } bool ReadData(char *buff, unsigned int max_size) { DWORD dwErrors; /* エラー情報 */ COMSTAT ComStat; /* デバイスの状態 */ DWORD dwCount; /* 受信データのバイト数 */ DWORD dwRead; /* ポートから読み出したバイト数 */ ClearCommError(hComm, &dwErrors, &ComStat); dwCount = ComStat.cbInQue; if (dwCount > max_size) { printf("バッファサイズが足りません。\n"); return false; } ReadFile(hComm, buff, dwCount, &dwRead, NULL); if (dwCount != dwRead) { printf("データの受け取りに失敗しました。\n"); return false; } return true; } int main(int argc, char* argv[]) { char ch; while(1){ cin >> ch; printf("入力 %c\n", ch); ComInit(); WriteData(&ch, strlen(&ch)); ReadData(&ch, strlen(&ch)); ComEnd(); } return 0; }

  • シリアル通信の受信待ちについて

    シリアル通信で10Byte受信するまで待ち続けたいのですが、0ByteでReadFileが抜けてしまいます。 ReadFileの最後のパラメタが、NULLならば第3パラメタの値まで待ち続けると思っていたのですが、なにか設定が足りないのでしょうか? タイムアウト値は0にしています。(色々変えて見ましたが同じでした) HANDLE hComm; /* シリアルポートのハンドル */ DCB dcb; char* pszBuf="1234567890"; /* 書込・読込領域 */ hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); GetCommState(hComm, &dcb); /* DCB を取得 */ dcb.BaudRate = 9600; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; dcb.ReadIntervalTimeout = 100; dcb.ReadTotalTimeoutMultiplier = 0; dcb.ReadTotalTimeoutConstant = 0; dcb.WriteTotalTimeoutMultiplier = 10; dcb.WriteTotalTimeoutConstant = 500; SetCommState(hComm, &dcb); /* DCB を設定 */ DWORD dwRead; /* ポートから読み出したバイト数 */ ReadFile(hComm, pszBuf, 10, &dwRead, NULL);

  • QTシリアル通信

    現在開発環境QT5.3を使用しシリアル通信のプログラムを組んでいるんですが 以下のエラーが発生し、調査を行っても不明なため質問させていただきました OS:WindowsXP 開発環境:QT 目的:RS422通信 まずシリアル通信ポートがパソコンに標準でついていないため、インターフェースから PCIタイプのシリアル通信ボードを購入し、取り付けました メーカの自己診断、メーカの送受信は確認し文字の送受信を確認しました。 デバイスマネージャで確認し、"COM3"と"COM4"であることを確認しました。 そこでQTでプログラムを組んでいくとCreateFile関数でエラーが発生することを確認しました GetLastError関数の戻り値を確認すると0を返すことを確認しました。 以下が今回記述したプログラムのソースコードとなります。 #include <windows.h> #inlclude <stdio.h> #include <stdlib.h> #include <string.h> void MainWindow::Serial_open() { HANDLE hPort; SetLastError(NO_ERROR); hPort = CreateFile((LPWSTR)"COM3",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hPort==INVALID_HANDLE_VALUE) { DWORD dw = GetLastError(); //ここで戻り値0がくる。 } } 以上よろしくお願いします

  • VisualStudio2010のC++の通信

    VisualStudio2010のC++のシリアルポートによる通信で質問なんですが、 CreateFile で正しい値などを入力したにもかかわらず接続できないと出てきます。 具体的に言うと、H8 3697にシリアル通信で接続したいんですが上手くいきませんでした。 ハイパーターミナルでH8 3697に接続は出来て、受信、送信が出来たので VisualStudio2010のC++のプログラミングが悪いと思います 以下がそのソースコードになっています。 接続ボタンが押されたときのイベント(処理)使用言語 C++ ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ DCB dcbPortConfig; memset(&dcbPortConfig, 0, sizeof(DCB)); dcbPortConfig.DCBlength = (DWORD)sizeof(DCB); dcbPortConfig.BaudRate = 19200; dcbPortConfig.ByteSize = 8; dcbPortConfig.Parity = 0; dcbPortConfig.StopBits = 0; m_hComPort = CreateFile("COM11", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(m_hComPort != INVALID_HANDLE_VALUE) { //AfxMessageBox(_T("CMyComm::Open CreateFile失敗")); } // ポートのボーレート、パリティ等を設定 BOOL bRet = SetCommState(m_hComPort, &dcbPortConfig); if(bRet != FALSE) { AfxMessageBox(_T("CMyComm::Open() SetCommState失敗")); } ではよろしくお願いします。 ちなみにH8 3697のほうのソースでは最初初期処理してそれから無限ループでなんかの文字列を10秒ごとに送信している処理になっています。

  • シリアル通信のポートオープン

    シリアル通信のテストプログラムを作成中でして、一通り動作するようになったのでエラー処理を確認しようとしたところ、存在しないCOMポート?なのにオープンが成功したと処理してしまいます。 環境  P社のノートパソコン  Windows XP Pro SP3  Visual C++6.0 SP6  USB接続のRS-232C変換アダプタを使用  デバイスマネージャでは、拡張ポートはCOM4のみとなっている  ハイパーターミナルの「接続の設定」では、接続方法の選択肢にCOM3とCOM4の2つがある ・COM4を使うと、オープン後、正常に通信できます。 ・COM3を使うと、オープンは出来るが、通信は出来ません。 ソースを記載します。 if(HANDLE_CHECK(m_hComm) == FALSE){ ss.Format("COM%d", m_nRsPort); m_hComm = ::CreateFile(ss, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(HANDLE_CHECK(m_hComm) == TRUE){ dcb.DCBlength = sizeof(DCB); if(::GetCommState(m_hComm, &dcb) != FALSE){ dcb.BaudRate = m_nRsBaudrate; dcb.Parity = m_nRsParity; ・ ・ ・ ・ ・ ・ if(::SetCommState(m_hComm, &dcb) != FALSE){ COM3の場合もCOM4の場合もここを通っている。 } else{ } } } } COM3のオープン時、エラーの検知は出来ないのでしょうか? よろしくお願いします。

  • シリアル通信でのデータ受信

    シリアル通信にてデータを連続的に受信するプログラムを つくりたいと思っています. 以下のプログラムを作成して, main関数のcountを増やして,繰り返しreadを行おうとすると, 出力結果として, 時,分,秒,ID,値B,値C,値Dというフォーマットで 0, 9,30, 1,514,708,542,290 0, 9,30, 2,515,707,542,288 0, 9,30, 3,514,709,542,287 0, 9,30, 4,514,707,543,289 0, 9,30, 5,514,708,542,289 0, 9,30, 6,514,708,542,292 0, 9,30, 7,514,708,542,291 0, 9,30, 8,514,708,542,289 0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289 (この後フが連続) フフフフフフフフフフフフフフフ ク 0, 9,39,36,514,708,542,290 0, 9,39,37,515,709,541,291 0, 9,39,38,514,707,542,286 0, 9,39,39,514,708,542,281 0, 9,39,40,514,708,542,284 0, 9,39,41,514,707,542,286 0, 9,39,42,514,707,542,290 0, 9,39,43,514,709,542,290 0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289 フフフフフフフフフ・・・再びフ となってしまいます. 問題としては ・フがたくさんでてきてしまう. ・1サイクルの最後で改行ができていない ・1サイクルが終わって次のサイクルに入る時までの 間にデータが失われている. ・2サイクル目になぜか1サイクル目の値が残っている? などがあります. どなたか解決方法を教えていただけると大変助かります. よろしくお願いします. ------------------------------- #include "stdafx.h" #include <stdlib.h> #include <windows.h> #include <string.h> #include <stdio.h> #define COM_PORT_NAME "COM2" #define BAUD_RATE 57600 #define BYTE_SIZE 5000 //250 #define PARITY NOPARITY //EVENPARITY #define STOP_BIT TRUE #define F_PARITY ONESTOPBIT HANDLE hComm; // シリアルポートとの通信ハンドル bool ComInit() { // シリアルポートを開ける hComm = CreateFile( COM_PORT_NAME, /* シリアルポートの文字列 */ GENERIC_READ | GENERIC_WRITE, /* アクセスモード:読み書き */ 0, /* 共有モード:他からはアクセス不可 */ NULL, /* セキュリティ属性:ハンドル継承せず */ OPEN_EXISTING, /* 作成フラグ: */ FILE_ATTRIBUTE_NORMAL, /* 属性: */ NULL /* テンプレートのハンドル: */ ); if (hComm == INVALID_HANDLE_VALUE) { printf("シリアルポートを開くことが出来ませんでした。\n"); return false; } // 通信属性を設定する DCB dcb; GetCommState(hComm, &dcb); /* DCB を取得 */ dcb.BaudRate = BAUD_RATE; dcb.ByteSize = BYTE_SIZE; dcb.Parity = PARITY; dcb.fParity = STOP_BIT; dcb.StopBits = F_PARITY; SetCommState(hComm, &dcb); /* DCB を設定 */ return true; } void ComEnd() { // ハンドルを閉じる CloseHandle(hComm); } bool ReadData(char *buff, unsigned int max_size) { DWORD dwErrors; /* エラー情報 */ COMSTAT ComStat; /* デバイスの状態 */ DWORD dwCount; /* 受信データのバイト数 */ DWORD dwRead; /* ポートから読み出したバイト数 */ ClearCommError(hComm, &dwErrors, &ComStat); dwCount = ComStat.cbInQue; FILE *fid; fid=fopen("test.txt", "w"); printf("%d %d\n", dwCount, max_size); fprintf(fid,"%d %d\n", dwCount, max_size); fclose(fid); if (dwCount > max_size) { printf("バッファサイズが足りません。\n"); return false; } if(hComm != NULL){ ReadFile(hComm, buff, dwCount, &dwRead, NULL); if (dwCount != dwRead) { printf("データの受け取りに失敗しました。\n"); return false; } } return dwRead; } int main(int argc, char* argv[]) { char buff[BYTE_SIZE]; int count = 0; int data_length; FILE *fid2; fid2=fopen("test2.txt","w"); ComInit(); while(1){ if(count == 2) break; count++; data_length=ReadData(buff, strlen(buff)); printf("%s ",buff); fprintf(fid2, "%s ",buff); } fclose(fid2); ComEnd(); return 0; }

  • BCB6.0でのCOM設定方法

    BCB初心者なのですが、BCBを使用してシリアル通信を行なっています。 COM設定が不定な状態で使用することになり、設定できるようにしたのですがエラーが発生してしまいます。 [Unit1.cpp側] if (!CommOpen()){ Application->MessageBox("ポートを開けません","回線オープン",MB_ICONEXCLAMATION | MB_OK); return; } [Unit1.h側] int FChPort;  // シリアルポートナンバー HANDLE hCom; DCB comdcb; COMMTIMEOUTS comtout; BOOL CommOpen() { FChPort = 1; //シリアルポートのオープン char szComPort[10]; wsprintf(szComPort, "COM%d", FChPort); hCom = CreateFile( szComPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,OPEN_EXISTING, 0, NULL ); if(hCom==INVALID_HANDLE_VALUE){ return FALSE; } return TRUE; } 上記が現状です。 RadioButton1~9にはCaptionが「COM1」~「COM9」になっているため CheckされているCaptionの、右から1文字をCOMポート設定に割り当てたいと考えています。 そこで、 FChPort = 1; の部分を FChPort = StrToInt(RightStr(Unit1->RadioButton1->Caption,1)); に変更したのですが、デバッガ例外が発生し、読み込み違反があったというエラーが発生してしまいました。 (例としてRadioButton1で試しました。) なぜなのでしょうか? また、このような場合、どのようにすればCOM設定ができるのか教えていただきたいのですが…。 よろしくお願いします。 開発環境はWindows XPです。

  • 通信(送信)のプログラム

    bool WriteData(char *buff, unsigned int data_size) {     DWORD dwWritten; /* ポートへ書き込んだバイト数 */ WriteFile(hComm, buff, data_size, &dwWritten, NULL); if (dwWritten!=data_size) { printf("データの送信に失敗しました。\n"); return false; } return true; } 上の関数はシリアル通信の送信する関数なんですが、これに数値などを入れたいんですが、char型のため、一文字しか入れれません。たとえば、01ならchar型の0とchar型の1を別々に送らないとだめなんですが、このようにするしか無理なんでしょうか?int型の数値を好きなように入れて送りたいんですが。あと、OxFFのように16進数も入れれると便利なんですが。駄文ですいません。プログラムの知識が浅はかですいません。

  • シリアル通信の出力バッファと送信完了イベントについて

    こんにちわ。よろしくお願いします。 どの言語として扱うか迷ったのですが、恐らくはC/C++が一番だろうと思ってここで質問させていただきます。 質問の内容ですが、現在、シリアル通信のアプリケーションを作っていまして、CreateFileの引数にFILE_FLAG_OVERLAPPEDを与えて非同期で読み書きを行うようにしています。 非同期ですので、OVERLAPPED構造体をstaticで宣言し、 WriteFile時に引数で与えています。 --- m_hComm = CreateFile( (const char*)pCom, GENERIC_READ|GENERIC_WRITE,0, NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ) ; WriteFile(m_hComm, pwData,dwLen, &dwWrite, &osWriter); --- 問題はここからで、OVERLAPPED構造体のイベントが、シグナル状態になり、GetOverlappedResult(m_hComm, &osWriter, &dwWrite, TRUE)を抜けるのはいいのですが、実際には送信は完了しておらず、GetCommStateで通信速度を変更すると送信途中のデータが化けて通信エラーになってしまいます。 どうやら、今使用しているPCのUARTの出力バッファが大きいのか、Windows側のバッファからUARTバッファに書き込みが完了した時点でWindowsはOVERLAPPED構造体のイベントをシグナルにしているようです。 (もちろんFIFOは切ってあります) 他のPCで確認したところ、問題ありませんでした。 もしどなたか、シリアルの出力バッファを監視するいい方法があったら教えていただけないでしょうか。

専門家に質問してみよう