Конференция "WinAPI" » COM-порт изменение скорости при синхронном режиме работы [Win2k, WinXP]
 
  • МистерТ (09.10.08 16:22) [0]
    Здравствуйте!
    Возник вопрос, возможно ответ лежит на поверхности, но проблемой, с которой косвенно связан вопрос, занимаюсь уже второй день и несколько "зациклился".
    При обмене с железкой используется синхронное чтение и запись в СОМ-порт (отдельный поток с двумя очередями - на входящие и на исходящие сообщения). И вот в процессе общения необходимо изменить скорость обмена, количество стоповых бит и контроль четности.
    Выполнимо ли это без закрытия/открытия-по-новой СОМ-порта ?
    Если выполнимо в общих чертах, достаточно ли установить новый SetCommState() или потребуется что-то еще ?

    Заранее благодарю за ответы.

    З.Ы. сильно не пинайте, только подтолкните к решению :)
  • Сергей М. © (09.10.08 16:34) [1]
    Справка утверждает, что

    The function reinitializes all hardware and control settings, but it does not empty output or input queues
  • Сергей М. © (09.10.08 16:38) [2]
    Но подозреваю, что если Read/WriteFile и SetCommState вызываются из разных потоков, хэндл открытого порта следует защитить крит.секцией
  • МистерТ (09.10.08 19:18) [3]
    Собственно, что мне и нужно.
    Просто одним SetCommState() в асинхронном режиме ограничится не удалось, приходится CloseHandle() + OpenFile() и т.д. и открывать вновь.

    З.Ы. "не удалось" означает, что железка подобные операции как-то неадекватно воспринимает и не отвечает, а если пересоздать - работает замечательно.
  • Германн © (10.10.08 01:28) [4]

    > З.Ы. "не удалось" означает, что железка подобные операции
    > как-то неадекватно воспринимает и не отвечает, а если пересоздать
    > - работает замечательно.
    >

    А что тебе известно про "железку"? Тут ведь почти всё зависит именно от неё! Мои железки твои "ковыряния в носу" пошлют сразу нафиг. Или ты считаешь, что "железки" подключаемые к СОМ-порту обязаны следовать одному строго заданному правилу?
  • МистерТ (10.10.08 07:19) [5]
    > Германн ©   (10.10.08 01:28) [4]
    Знаю то, что первоначальный коннект осуществляется на скорости 1200/7бит/с контролем четности (Е).
    После "обмена любезностями" железка отправляет сообщение что "мол не хотите ли сударь поменять скорость на человеческую" (9600/8бит/без контроля четности), ждет когда я ей отвечу на первоначальной и переключается на 9600.
    Вот момент переключения и не проходит. Железка не отвечает на 9600, а через минуту (тайм-аут соединения) отвечает на 1200 мол "я Вас не так поняла и во взаимности отказываю" :)

    З.Ы. железка - SEVC-D (старый который, не актарисовский)
  • GanibalLector © (10.10.08 18:02) [6]
    >Выполнимо ли это без закрытия/открытия-по-новой СОМ-порта ?

    Вроде НЕТ.
  • GanibalLector © (10.10.08 18:19) [7]
    Хотя нет. Проверил, можно. Я и сам не знал ;)


    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


  • Германн © (11.10.08 00:43) [8]

    > МистерТ   (10.10.08 07:19) [5]
    >
    > > Германн ©   (10.10.08 01:28) [4]
    > Знаю то, что первоначальный коннект осуществляется на скорости
    > 1200/7бит/с контролем четности (Е).
    > После "обмена любезностями" железка отправляет сообщение
    > что "мол не хотите ли сударь поменять скорость на человеческую"
    > (9600/8бит/без контроля четности), ждет когда я ей отвечу
    > на первоначальной и переключается на 9600.
    > Вот момент переключения и не проходит. Железка не отвечает
    > на 9600, а через минуту (тайм-аут соединения) отвечает на
    > 1200 мол "я Вас не так поняла и во взаимности отказываю"
    > :)

    Значит чего-то ты о ней не знаешь или чего-то делаешь неправильно. Железка своё отрабатывает давая ответ: "я Вас не так поняла и во взаимности отказываю". (Кстати, грамотная железка. Не все железки такие грамотные. Многие просто промолчали бы).
  • tesseract © (23.10.08 12:47) [9]

    > GanibalLector ©   (10.10.08 18:19) [7]


    Теоретически это и не запрещено, а ты попробуй данные попосылать, интересно что выйдет :-)
 
Конференция "WinAPI" » COM-порт изменение скорости при синхронном режиме работы [Win2k, WinXP]
Есть новые Нет новых   [134435   +33][b:0][p:0.002]