Skip to content

Instantly share code, notes, and snippets.

@katahiromz
Created November 23, 2024 05:09
Show Gist options
  • Save katahiromz/3a4a12d295af9c097829d5931bbd73b1 to your computer and use it in GitHub Desktop.
Save katahiromz/3a4a12d295af9c097829d5931bbd73b1 to your computer and use it in GitHub Desktop.
RS-232C COM通信
// RS-232C通信設定
bool VskWin32File::set_com_params(VskString params)
{
// 空白を削除し、大文字にする
auto str = params;
mstr_replace_all(str, " ", "");
mstr_replace_all(str, "\t", "");
vsk_upper(str);
// COMの設定を取得する
DCB config = { sizeof(config) };
if (!::GetCommState(m_hFile, &config))
{
mdbg_traceA("GetCommState failed: 0x%08lX\n", ::GetLastError());
return false;
}
// COMポートの設定
config.BaudRate = CBR_1200; // ボーレート
config.ByteSize = 7; // データビット
config.Parity = ODDPARITY; // パリティ
config.StopBits = ONESTOPBIT; // ストップビット
// パラメータを取得する
size_t ich = 0;
for (auto ch : str)
{
switch (ich)
{
case 0:
switch (ch) // パリティチェック
{
case 'E': config.Parity = EVENPARITY; break; // 偶数パリティ
case 'O': config.Parity = ODDPARITY; break; // 奇数パリティ
case 'N': config.Parity = NOPARITY; break; // パリティなし
}
break;
case 1:
switch (ch) // データビット
{
case '7': config.ByteSize = 7; break; // データビット7
case '8': config.ByteSize = 8; break; // データビット8
}
break;
case 2:
switch (ch) // ストップビット
{
case '1': config.StopBits = ONESTOPBIT; break; // 1ビット
case '2': config.StopBits = ONE5STOPBITS; break; // 1.5ビット
case '3': config.StopBits = TWOSTOPBITS; break; // 2ビット
}
break;
case 3:
switch (ch) // XON/XOFF制御
{
case 'X':
config.fInX = config.fOutX = TRUE;
config.XonChar = 0x11; // XONキャラクタ
config.XoffChar = 0x13; // XOFFキャラクタ
break;
case 'N':
break;
}
break;
case 4:
switch (ch) // SI/SO制御
{
case 'S':
config.fInX = config.fOutX = TRUE;
config.XonChar = 0x0F; // XONキャラクタ
config.XoffChar = 0x0E; // XOFFキャラクタ
break;
case 'N':
break;
}
break;
}
++ich;
}
// パラメータを設定する
if (!::SetCommState(m_hFile, &config))
{
mdbg_traceA("SetCommState failed: 0x%08lX\n", ::GetLastError());
return false;
}
// タイムアウト設定
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 5000;
timeouts.ReadTotalTimeoutConstant = 5000;
timeouts.ReadTotalTimeoutMultiplier = 1000;
timeouts.WriteTotalTimeoutConstant = 5000;
timeouts.WriteTotalTimeoutMultiplier = 1000;
if (!::SetCommTimeouts(m_hFile, &timeouts))
{
mdbg_traceA("SetCommTimeouts failed: 0x%08lX\n", ::GetLastError());
return false;
}
return true;
}
VskError VskFileManager::open_com_file(VskFilePtr& file, VskString device, const VskString& params)
{
vsk_upper(device);
if (device == "COM")
device = "COM1";
// RS-232C 通信ファイルを開く
// NOTE: 管理者権限が必要かもしれません
HANDLE hComFile = ::CreateFileA(
device.c_str(), // COM1, COM2, or COM3
GENERIC_READ | GENERIC_WRITE, // 読み書き可能
0, // 共有モードなし
NULL, // セキュリティ属性
OPEN_EXISTING, // 既存のデバイスを開く
0, // 非同期動作なし
NULL // テンプレートなし
);
if (hComFile == INVALID_HANDLE_VALUE)
return vsk_error_from_last_error(::GetLastError());
file = std::make_shared<VskWin32File>(hComFile, VskFile::MODE_DEFAULT, VskFile::TYPE_COM);
file->set_com_params(params);
return VSK_NO_ERROR;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment