Как правильно работать с TDCB?
, Непонятка с SDK и константами...
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.223] |
|
|
ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Как правильно работать с TDCB?
, Непонятка с SDK и константами...
|
Сообщ.
#1
,
|
|
|
|
Букв будет много, но по другому не получится. Стал я заполнять TDCB для порта и обнаружил слудующее:
SDK: The DCB structure defines the control setting for a serial communications device. typedef struct _DCB { // dcb DWORD DCBlength; // sizeof(DCB) DWORD BaudRate; // current baud rate DWORD fBinary: 1; // binary mode, no EOF check DWORD fParity: 1; // enable parity checking DWORD fOutxCtsFlow:1; // CTS output flow control DWORD fOutxDsrFlow:1; // DSR output flow control DWORD fDtrControl:2; // DTR flow control type DWORD fDsrSensitivity:1; // DSR sensitivity DWORD fTXContinueOnXoff:1; // XOFF continues Tx DWORD fOutX: 1; // XON/XOFF out flow control DWORD fInX: 1; // XON/XOFF in flow control DWORD fErrorChar: 1; // enable error replacement DWORD fNull: 1; // enable null stripping DWORD fRtsControl:2; // RTS flow control DWORD fAbortOnError:1; // abort reads/writes on error DWORD fDummy2:17; // reserved WORD wReserved; // not currently used WORD XonLim; // transmit XON threshold WORD XoffLim; // transmit XOFF threshold BYTE ByteSize; // number of bits/byte, 4-8 BYTE Parity; // 0-4=no,odd,even,mark,space BYTE StopBits; // 0,1,2 = 1, 1.5, 2 char XonChar; // Tx and Rx XON character char XoffChar; // Tx and Rx XOFF character char ErrorChar; // error replacement character char EofChar; // end of input character char EvtChar; // received event character WORD wReserved1; // reserved; do not use } DCB; В модуле WINDOWS TDCB объявлена так: ![]() ![]() type _DCB = packed record DCBlength: DWORD; BaudRate: DWORD; Flags: Longint; wReserved: Word; XonLim: Word; XoffLim: Word; ByteSize: Byte; Parity: Byte; StopBits: Byte; XonChar: CHAR; XoffChar: CHAR; ErrorChar: CHAR; EofChar: CHAR; EvtChar: CHAR; wReserved1: Word; end; Понятно, что указанные в SDK поля: DWORD fBinary: 1; // binary mode, no EOF check DWORD fParity: 1; // enable parity checking DWORD fOutxCtsFlow:1; // CTS output flow control DWORD fOutxDsrFlow:1; // DSR output flow control DWORD fDtrControl:2; // DTR flow control type DWORD fDsrSensitivity:1; // DSR sensitivity DWORD fTXContinueOnXoff:1; // XOFF continues Tx DWORD fOutX: 1; // XON/XOFF out flow control DWORD fInX: 1; // XON/XOFF in flow control DWORD fErrorChar: 1; // enable error replacement DWORD fNull: 1; // enable null stripping DWORD fRtsControl:2; // RTS flow control DWORD fAbortOnError:1; // abort reads/writes on error DWORD fDummy2:17; // reserved представлены в TDCB как Flags: Longint. Т.е. для того, что бы присвоить полю DWORD fDtrControl значение, например RTS_CONTROL_DISABLE нужно в TDCB ПРАВИЛЬНО заполнить поле Flags: Longint. Если бы RTS_CONTROL_DISABLE, RTS_CONTROL_ENABLE, DTR_CONTROL_HANDSHAKE и т.д. были битовыми константами, то я бы сделал так: ![]() ![]() fDCB.Flags := fDCB.Flags or aCOMProp.RTSControl or aCOMProp.DTRControl; Но эти константы объявлены как: ![]() ![]() const { DTR Control Flow Values. } DTR_CONTROL_DISABLE = 0; {$EXTERNALSYM DTR_CONTROL_DISABLE} DTR_CONTROL_ENABLE = 1; {$EXTERNALSYM DTR_CONTROL_ENABLE} DTR_CONTROL_HANDSHAKE = 2; {$EXTERNALSYM DTR_CONTROL_HANDSHAKE} { RTS Control Flow Values} RTS_CONTROL_DISABLE = 0; {$EXTERNALSYM RTS_CONTROL_DISABLE} RTS_CONTROL_ENABLE = 1; {$EXTERNALSYM RTS_CONTROL_ENABLE} RTS_CONTROL_HANDSHAKE = 2; {$EXTERNALSYM RTS_CONTROL_HANDSHAKE} RTS_CONTROL_TOGGLE = 3; {$EXTERNALSYM RTS_CONTROL_TOGGLE} Поэтому так делать нельзя... А как правильно сделать??? |
|
Сообщ.
#2
,
|
|
|
|
код выдран из старого проекта...думаю, в качестве примера работы с dcb.Flags сойдет
![]() ![]() type ............ TComPortHwHandshaking = ( hhNONE, hhNONERTSON, hhRTSCTS ); TComPortSwHandshaking = ( shNONE, shXONXOFF ); TPacketMode = ( pmDiscard, pmPass );{ What to do with incomplete (incoming) packets } TComPortLineStatus = ( lsCTS, lsDSR, lsRING, lsRLSD); TComPortLineStatusSet = set of TComPortLineStatus; ........ const dcb_Binary = $00000001; dcb_ParityCheck = $00000002; dcb_OutxCtsFlow = $00000004; dcb_OutxDsrFlow = $00000008; dcb_DtrControlMask = $00000030; dcb_DtrControlDisable = $00000000; dcb_DtrControlEnable = $00000010; dcb_DtrControlHandshake = $00000020; dcb_DsrSensivity = $00000040; dcb_TXContinueOnXoff = $00000080; dcb_OutX = $00000100; dcb_InX = $00000200; dcb_ErrorChar = $00000400; dcb_NullStrip = $00000800; dcb_RtsControlMask = $00003000; dcb_RtsControlDisable = $00000000; dcb_RtsControlEnable = $00001000; dcb_RtsControlHandshake = $00002000; dcb_RtsControlToggle = $00003000; dcb_AbortOnError = $00004000; dcb_Reserveds = $FFFF8000; var dcb: TDCB; .............................. dcb.Flags := dcb_Binary; { Enables the DTR line when the device is opened and leaves it on } if fEnableDTROnOpen then dcb.Flags := dcb.Flags or dcb_DtrControlEnable; { Kind of hw handshaking to use } case FComPortHwHandshaking of { No hardware handshaking } hhNONE:; { No hardware handshaking but set RTS high and leave it high } hhNONERTSON: dcb.Flags := dcb.Flags or dcb_RtsControlEnable; { RTS/CTS (request-to-send/clear-to-send) hardware handshaking } hhRTSCTS: dcb.Flags := dcb.Flags or dcb_OutxCtsFlow or dcb_RtsControlHandshake; end; { Kind of sw handshaking to use } case FComPortSwHandshaking of { No software handshaking } shNONE:; { XON/XOFF software handshaking } shXONXOFF: dcb.Flags := dcb.Flags or dcb_OutX or dcb_InX; end; |
|
Сообщ.
#3
,
|
|
|
|
Я собственно и пологал, что придется самому битовые константы определять для флагов, но надеялся, что есть стандартные функции...
Кстати, я вот почитал SDK по внимательнее... И, как мне показалось, с DCB напрямую работать вообще не надо. А правильно использовать COMMCONFIG. Через нее все и устанавливать, включая и настройки устройства... толи голый RS232, толи конкретный модем... Вобщем, есть у меня подозрения, что подобный подход мелкомягкими не задумывался, поэтому и все не так гладко выходит с этой DCB. ... Или я гоню? |
|
Сообщ.
#4
,
|
|
|
|
Имхо - гонишь-)
А читать лучше MSDN Пример из plaform SDK: ![]() ![]() Configuring a Communications Resource The following example opens a handle to COM1 and fills in a DCB structure with the current configuration. The DCB structure is then modified and used to reconfigure the device. /* A sample program to illustrate setting up a serial port. */ #include <windows.h> int main(int argc, char *argv[]) { DCB dcb; HANDLE hCom; BOOL fSuccess; char *pcCommPort = "COM2"; hCom = CreateFile( pcCommPort, GENERIC_READ | GENERIC_WRITE, 0, // comm devices must be opened w/exclusive-access NULL, // no security attributes OPEN_EXISTING, // comm devices must use OPEN_EXISTING 0, // not overlapped I/O NULL // hTemplate must be NULL for comm devices ); if (hCom == INVALID_HANDLE_VALUE) { // Handle the error. printf ("CreateFile failed with error %d.\n", GetLastError()); return (1); } // We will build on the current configuration, and skip setting the size // of the input and output buffers with SetupComm. fSuccess = GetCommState(hCom, &dcb); if (!fSuccess) { // Handle the error. printf ("GetCommState failed with error %d.\n", GetLastError()); return (2); } // Fill in the DCB: baud=57,600 bps, 8 data bits, no parity, and 1 stop bit. dcb.BaudRate = CBR_57600; // set the baud rate dcb.ByteSize = 8; // data size, xmit, and rcv dcb.Parity = NOPARITY; // no parity bit dcb.StopBits = ONESTOPBIT; // one stop bit fSuccess = SetCommState(hCom, &dcb); if (!fSuccess) { // Handle the error. printf ("SetCommState failed with error %d.\n", GetLastError()); return (3); } printf ("Serial port %s successfully reconfigured.\n", pcCommPort); return (0); |
|
Сообщ.
#5
,
|
|
|
|
А на кой черт тогда COMMCONFIG?
Плюс вот еще что в SDK написано. Communications Resource Configuration The COMMCONFIG structure defines the configuration of a communications resource, serial or otherwise. The format of the structure varies depending on the type of communications resource (the provider subtype). The first few structure members are common to all communications resources; additional members are defined for specific provider subtypes. Specific service providers may extend the COMMCONFIG structure as well. An application can get and set the configuration of a communications resource by using the GetCommConfig and SetCommConfig functions. When opened, a communications resource is initialized using the default configuration for its provider subtype. To get and set the default configuration for a provider subtype, use the GetDefaultCommConfig and SetDefaultCommConfig functions. To prompt the user for configuration information, use the CommConfigDialog function. This function displays a dialog box defined by the service provider and fills in a COMMCONFIG structure based on user input. Тут не слова нет, что надо использовать напряму DCB. В дальнейшем она вспывает... но. То, что ее можно напряму редактировать не говорит о том, что это хороший тон... Сколько знаю народа, которы устраивали танцы с этой DCB ни у кого почеловечески все это не работало, т.е. Поэтому я все-таки сомневаюсь, что это правильно. И то, что в иходникак модуля Windows константы задающие флаги для этой структуры объявлены не правильно, на мой вгляд, есть лишнее тому подтверждение. ЗЫЖ MSDN хорошо, но SDK ближе к среде. Из предпоследнего твоего поста я понял, что у тебя был какой-то проек который работал какой-то железкой по RS232 и раз использовались константы RTS_CONTROL_ENABLED и т.д. пологаю, что предпологались разные режимы работы этих сигналов. Смотрела ли ты на осциллографе, в режиме TOGLE как выставляется RTS? У меня основная проблема в том, что бы правильно выставить этот сигнал, он должен быть четко после последнего переданного бита из !буфера порта! в устройство. |