| 216.73.216.150 , 40886th | 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 |