ec2-3-144-21-237.us-east-2.compute.amazonaws.com , 39844th | 2002/12/10 UPDATED |
SetCommState
をDCB構造体から初期値を与えて初期化すると思われるが、うまい値を設定してあげないと正しく設定することができない。
DeviceIoControl
からIOCTL_SERIAL_SET(GET)_BAUD_RATE
を使って変更する例であるntddser.h
からの抜粋である。 そのままファイルをインクルードすると、二重定義エラーがわんさか出てしまうので、必要なところだけを使っている。[ヘッダー]
#include <winioctl.h> // // This structure used by set baud rate // typedef struct _SERIAL_BAUD_RATE { ULONG BaudRate; } SERIAL_BAUD_RATE,*PSERIAL_BAUD_RATE; #define IOCTL_SERIAL_SET_BAUD_RATE CTL_CODE(FILE_DEVICE_SERIAL_PORT, 1, \ METHOD_BUFFERED,FILE_ANY_ACCESS) #define IOCTL_SERIAL_GET_BAUD_RATE CTL_CODE(FILE_DEVICE_SERIAL_PORT,20, \ METHOD_BUFFERED,FILE_ANY_ACCESS)
baud = 115200/div
からの値になることである。div = 115200/baud
の結果の小数点以下が切り捨てられた値が設定されるので、入力に 10500を突っ込んでも、実際のボーレートは 11520ボーとなってしまう。div = 11
となる値を入力せねばならない。 この場合、10472をセットすると、実ボーレートを、おおよそ10472.7ボーとすることができる。[設定の例]
HANDLE hComm; // あらかじめCOMポートを初期化のこと int setbaud_W2K(int baud) { SERIAL_BAUD_RATE sSB; DWORD junk; sSB.BaudRate = baud; DeviceIoControl( hComm, IOCTL_SERIAL_SET_BAUD_RATE, &sSB, sizeof(sSB), 0, NULL, &junk, (LPOVERLAPPED) NULL); DeviceIoControl( hComm, IOCTL_SERIAL_GET_BAUD_RATE, 0, NULL, &sSB, sizeof(sSB), &junk, (LPOVERLAPPED) NULL); return sSB.BaudRate; }
SetCommState
も内部でIOCTLを呼んでいるわけで、変なボーレートを与えて設定に失敗してしまう原因は、デバイダ値が切り捨てられて処理されるので、値によっては入力ボーレートと実設定ボーレートの差が大きくなってしまい、それが検出されてハネられてしまっているというわけである。
であるので、rbaud = 115200/(int)(115200/baud)
が正しい値になるものを与えてあげれば良いと言うことになる。
void setbaud_W98(int baud) { div = 115200/baud; line = _inp( 0x3fb ); // COM1 デバイダ設定ビット _outp(0x3fb, line | 0x80 ); // bit7 = 1 _outp(0x3f8, (unsigned char)(div & 0xff)); // デバイダ LSB _outp(0x3f9, (unsigned char)(div & 0xff00) >> 8); // デバイダ MSB _outp(0x3fb, line); // 設定終了 }
-- LINK FREE -- |
||
HOME | LAST |