-
Здравствуйте! Возник вопрос, возможно ответ лежит на поверхности, но проблемой, с которой косвенно связан вопрос, занимаюсь уже второй день и несколько "зациклился". При обмене с железкой используется синхронное чтение и запись в СОМ-порт (отдельный поток с двумя очередями - на входящие и на исходящие сообщения). И вот в процессе общения необходимо изменить скорость обмена, количество стоповых бит и контроль четности. Выполнимо ли это без закрытия/открытия-по-новой СОМ-порта ? Если выполнимо в общих чертах, достаточно ли установить новый SetCommState() или потребуется что-то еще ?
Заранее благодарю за ответы.
З.Ы. сильно не пинайте, только подтолкните к решению :)
-
Справка утверждает, что
The function reinitializes all hardware and control settings, but it does not empty output or input queues
-
Но подозреваю, что если Read/WriteFile и SetCommState вызываются из разных потоков, хэндл открытого порта следует защитить крит.секцией
-
Собственно, что мне и нужно. Просто одним SetCommState() в асинхронном режиме ограничится не удалось, приходится CloseHandle() + OpenFile() и т.д. и открывать вновь.
З.Ы. "не удалось" означает, что железка подобные операции как-то неадекватно воспринимает и не отвечает, а если пересоздать - работает замечательно.
-
> З.Ы. "не удалось" означает, что железка подобные операции > как-то неадекватно воспринимает и не отвечает, а если пересоздать > - работает замечательно. >
А что тебе известно про "железку"? Тут ведь почти всё зависит именно от неё! Мои железки твои "ковыряния в носу" пошлют сразу нафиг. Или ты считаешь, что "железки" подключаемые к СОМ-порту обязаны следовать одному строго заданному правилу?
-
> Германн © (10.10.08 01:28) [4] Знаю то, что первоначальный коннект осуществляется на скорости 1200/7бит/с контролем четности (Е). После "обмена любезностями" железка отправляет сообщение что "мол не хотите ли сударь поменять скорость на человеческую" (9600/8бит/без контроля четности), ждет когда я ей отвечу на первоначальной и переключается на 9600. Вот момент переключения и не проходит. Железка не отвечает на 9600, а через минуту (тайм-аут соединения) отвечает на 1200 мол "я Вас не так поняла и во взаимности отказываю" :)
З.Ы. железка - SEVC-D (старый который, не актарисовский)
-
>Выполнимо ли это без закрытия/открытия-по-новой СОМ-порта ? Вроде НЕТ.
-
Хотя нет. Проверил, можно. Я и сам не знал ;)
function PortToStr(Port: Byte): string;
begin
Str(Port, Result);
Result := '\\.\COM' + Result;
end;
function OpenPort(Port:Byte): THandle;
var Tout: TCommTimeouts;
DCB: TDCB;
begin
Result := CreateFile(PChar(PortToStr(Port)),
GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if Result= INVALID_HANDLE_VALUE then Exit;
ZeroMemory(@DCB, SizeOf(DCB));
DCB.DCBlength := SizeOf(DCB);
DCB.Flags := 1;
DCB.BaudRate := CBR_4800;
DCB.Parity := NOPARITY;
DCB.ByteSize := 8;
DCB.StopBits := ONESTOPBIT;
if not SetCommState(Result, DCB) then Exit;
end;
procedure ChangeBaud(const H:THandle);
var DCB: TDCB;
begin
ZeroMemory(@DCB, SizeOf(DCB));
DCB.DCBlength := SizeOf(DCB);
DCB.Flags := 1;
DCB.BaudRate := CBR_9600;
DCB.Parity := NOPARITY;
DCB.ByteSize := 7;
DCB.StopBits := ONESTOPBIT;
if not SetCommState(H, DCB) then Exit;
end ;
procedure TForm1.Button1Click(Sender: TObject);
var H:THandle;
begin
H:= OpenPort(2) ;
ChangeBaud(H);
end; Лог :
0.00006146 Project1.exe IRP_MJ_CREATE Serial1 SUCCESS Options: Open
0.00000363 Project1.exe IOCTL_SERIAL_GET_BAUD_RATE Serial1 SUCCESS
0.00000251 Project1.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial1 SUCCESS
0.00000223 Project1.exe IOCTL_SERIAL_GET_CHARS Serial1 SUCCESS
0.00000223 Project1.exe IOCTL_SERIAL_GET_HANDFLOW Serial1 SUCCESS
0.00000950 Project1.exe IOCTL_SERIAL_SET_BAUD_RATE Serial1 SUCCESS Rate: 4800
0.00000531 Project1.exe IOCTL_SERIAL_CLR_RTS Serial1 SUCCESS
0.00000531 Project1.exe IOCTL_SERIAL_CLR_DTR Serial1 SUCCESS
0.00000391 Project1.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial1 SUCCESS StopBits: 1 Parity: NONE WordLength: 8
0.00000307 Project1.exe IOCTL_SERIAL_SET_CHAR Serial1 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:0 XOFF:0
0.00000447 Project1.exe IOCTL_SERIAL_SET_HANDFLOW Serial1 SUCCESS Shake:0 Replace:0 XonLimit:0 XoffLimit:0
0.00000223 Project1.exe IOCTL_SERIAL_GET_BAUD_RATE Serial1 SUCCESS
0.00000251 Project1.exe IOCTL_SERIAL_GET_LINE_CONTROL Serial1 SUCCESS
0.00000196 Project1.exe IOCTL_SERIAL_GET_CHARS Serial1 SUCCESS
0.00000223 Project1.exe IOCTL_SERIAL_GET_HANDFLOW Serial1 SUCCESS
0.00000978 Project1.exe IOCTL_SERIAL_SET_BAUD_RATE Serial1 SUCCESS Rate: 9600
0.00000503 Project1.exe IOCTL_SERIAL_CLR_RTS Serial1 SUCCESS
0.00000531 Project1.exe IOCTL_SERIAL_CLR_DTR Serial1 SUCCESS
0.00000363 Project1.exe IOCTL_SERIAL_SET_LINE_CONTROL Serial1 SUCCESS StopBits: 1 Parity: NONE WordLength: 7
0.00000251 Project1.exe IOCTL_SERIAL_SET_CHAR Serial1 SUCCESS EOF:0 ERR:0 BRK:0 EVT:0 XON:0 XOFF:0
0.00000391 Project1.exe IOCTL_SERIAL_SET_HANDFLOW Serial1 SUCCESS Shake:0 Replace:0 XonLimit:0 XoffLimit:0
-
> МистерТ (10.10.08 07:19) [5] > > > Германн © (10.10.08 01:28) [4] > Знаю то, что первоначальный коннект осуществляется на скорости > 1200/7бит/с контролем четности (Е). > После "обмена любезностями" железка отправляет сообщение > что "мол не хотите ли сударь поменять скорость на человеческую" > (9600/8бит/без контроля четности), ждет когда я ей отвечу > на первоначальной и переключается на 9600. > Вот момент переключения и не проходит. Железка не отвечает > на 9600, а через минуту (тайм-аут соединения) отвечает на > 1200 мол "я Вас не так поняла и во взаимности отказываю" > :)
Значит чего-то ты о ней не знаешь или чего-то делаешь неправильно. Железка своё отрабатывает давая ответ: "я Вас не так поняла и во взаимности отказываю". (Кстати, грамотная железка. Не все железки такие грамотные. Многие просто промолчали бы).
-
> GanibalLector © (10.10.08 18:19) [7]
Теоретически это и не запрещено, а ты попробуй данные попосылать, интересно что выйдет :-)
|