/*
* WIN32APIでRS-232C通信
* COM1ポートをオープンし、2400bps,データ長8ビット,パリティなし,ストップビット長1ビット,
* RTSフローONで5秒間受信し、アドレスrecievedDataに受信したデータを格納します。
* その後、「dummy data」という文字列を同じポートへ送信して終了します。
*/
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
void rs232c() {
HANDLE comPort = CreateFile(_T("COM1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // シリアルポートを開き、ハンドルを取得(
※10番以上のCOMポート名は _T("\\\\.\\COM10") としないと認識してくれない)
DCB dcb; // シリアルポートの構成情報が入る構造体
GetCommState(comPort, &dcb); // 現在の設定値を読み込み
dcb.BaudRate = 2400; // 速度
dcb.ByteSize = 8; // データ長
dcb.Parity = NOPARITY; // パリティ
dcb.StopBits = ONESTOPBIT; // ストップビット長
dcb.fOutxCtsFlow = FALSE; // 送信時CTSフロー
dcb.fRtsControl = RTS_CONTROL_ENABLE; // RTSフロー
SetCommState(comPort, &dcb); // 変更した設定値を書き込み
Sleep(5000); // 受信バッファにメッセージが溜まるまで待つ
DWORD errors; // エラーが起きた場合、エラーコードが入る
COMSTAT comStat; // 通信状態バッファ構造体
ClearCommError(comPort, &errors, &comStat); // 入出力バッファの情報を通信状態バッファへ取り込む
int lengthOfRecieved = comStat.cbInQue; // 通信状態バッファ内の受信したメッセージ長を取得する
// char *recievedData[lengthOfRecieved + 1]; // 受信したメッセージ長分のデータバッファをスタック上に確保
HANDLE hhp = HeapCreate(0, 0, 0); // ヒープハンドルを生成
char *recievedData = (char *)HeapAlloc(hhp, 0, sizeof(char) * (lengthOfRecieved + 1)); // 受信したメッセージ長 + 終端文字分のデータバッファをヒープ上に確保
DWORD numberOfGot; // 受信バッファから実際に読み取ったバイト数が入る
ReadFile(comPort, recievedData, lengthOfRecieved, &numberOfGot, NULL); // 受信バッファからデータバッファへ取り込む
recievedData[lengthOfRecieved] = '\0'; // 受信したデータに終端文字を追加
puts(recievedData); // 受信したデータを表示
const char *sentData = "dummy data"; // 送信する文字列
DWORD lengthOfSent = 10; // 送信するバイト数
DWORD numberOfPut; // 実際に送信したバイト数が入る
WriteFile(comPort, sentData, lengthOfSent, &numberOfPut, NULL); // ポートへ送信
CloseHandle(comPort); // シリアルポートを閉じる
HeapDestroy(hhp); // ヒープを解放
}
int main(void) {
rs232c();
return 0;
}
※受信したメッセージ長分のデータバッファ確保部分でC99のVLA(可変長配列)を使っていましたが、C11でオプション扱いに変更され、C++14では仕様に含まれていないので環境依存になります。念のためHeapAllocするように変更しました。VC++やMinGW使ってるならVLAで問題なく動くと思います。他の環境はよく分からないので一応。