Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Асинхроный I/O с COM портом, Передача данных из потока 
:(
    Опции темы
Com123
  Дата 14.9.2005, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 14.9.2005

Репутация: нет
Всего: нет



У меня такая трабла. Начал писать прогу асинхронного I/O - типа терминалки. Алгоритм стандартный OVERLAPPED. В главном потоке приложения отправляю AT комманду WriteFile'ом. Для чтения (ReadFile) из порта запускаю отдельный поток. Процедура треда выглядит более или менее стандартно у всех:

Код

procedure TSimpleThread.Execute;
var
  Overlapped : TOverlapped;
begin
  FillChar(Overlapped,SizeOf(TOverlapped),0);
  Overlapped.hEvent:= CreateEvent(nil,True,False,nil);
  ...
  ...
  while not Terminated do
  begin
    if not WaitCommEvent(hCom,EventMask,@Overlapped) then begin
      if GetLastError = ERROR_IO_PENDING then  begin
          Signal := WaitForSingleObject(Overlapped.hEvent,INFINITE);
        if (Signal = WAIT_OBJECT_0 + 1)
         then GetOverlappedResult(hCom,Overlapped,Readed,False)
      end;
    end;
    ClearCommError(hCom, ErrorMask, @CStat);
    if (EventMask and EV_RXCHAR)=EV_RXCHAR then        //Если пришли данные...
    begin
       Quelen := CStat.cbInQue;
       ReadFile(hCom,Buff,Quelen,Readed,@Overlapped);  // ...то читаем их в Buff
       if Readed > 0 then                              // Если это что-то ненулевое
       begin
        Move(Buff,RecivBuff[CntByte],Readed);         //..то мы его накопляем в RecivBuff
        Inc(CntByte,Readed);              //увеличить счётчик принятых
        ...
        ...
      end;                                   
    end;
  end;
...
...
end;



Все это вроде бы работает. Из порта приходят данные и копятся в RecivBuff (array[0..255] of Char), НО ответ на AT команду приходит не за одно событие EV_RXCHAR, а за несколько (каждый раз по разному) например сначала может прийти 2 байта потом 40 потом 12 smile Проблема: как в потоке чтения узнать что данные пришедшие за несколько EV_RXCHAR все вместе составляют ответ на АТ команду. Т.е. TSimpleThread.Execute должен передать в главный поток готовую строку ответа а не кусок строки(как это сделано во многих примерах). КАК??? или может че то не так понял...

p.s. В исходниках XModem и некоторых других я видел какие то действия с таймером и GetTickCount но до конца не разобрался. Хочется написать самому поэтому не хочу пользовать готовые компоненты и библиотеки.

PM MAIL   Вверх
Петрович
Дата 15.9.2005, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 15
Всего: 55



Обычно, модем дает ответ сразу. Однако, его прием и правда может разбиваться на несколько EV_RXCHAR.
Я в своей программе использую следующий алгоритм: Если очередной байт (событие EV_RXCHAR) не приходит в течении времени t, то считаю что принял все что хотел сказать мне модем. Величина t выбирается в зависимости от установленной скорости COM-порта, и равна времени передачи/приема 5-10 байт. Т.е. например при скорости 19200: t = 5 * (1+8+1)/19200
Ну и конечно можно использовать знание о командах и ответах. Если установлен вербальный режим, то на большинство комманд, модем отвечает одной строкой завершающейся символом ^M. Вот его-то и можно в таком случае считать признаком конца ответа. Не забывая конечно про эхо команды, если оно включено. Есть правда режим кодов, в нем нет признака конца. Ну и естественно есть команды, на которые некоторые модемы могут ответить несколькими строками.
В общем, я предпочитаю первый вариант.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Com123
Дата 15.9.2005, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 14.9.2005

Репутация: нет
Всего: нет



Опять не догнал - что такое 5 * (1+8+1) ?


Это сообщение отредактировал(а) Com123 - 15.9.2005, 17:48
PM MAIL   Вверх
Петрович
Дата 16.9.2005, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 15
Всего: 55



Цитата(Com123 @ 15.9.2005, 17:23)
Опять не догнал - что такое 5 * (1+8+1) ?

5 - число байт
1 - Стартовый бит
8 - биты данных (байт)
1 - Стоповый бит.
В последовательном интерфейсе, используемом в RS-232 стандарте по которому работает COM-порт, байт предваряется одним дополнительным битом (стартовым), и завершается еще одним (стоповым). По ним осуществляется синхронизация приемника и передатчика.
Если быть более точным, то стоповых битов может быть больше (1, 1.5 или 2). Но, обычно используется 1. Кроме того, может добавляться еще один бит - бит проверки на четность/нечетность. Это тоже теперь почти не используется.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Гость_Serg
Дата 16.9.2005, 17:49 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Приятно следить за беседой профессионалов smile .
Извините, что отвлекаю, но очень нужно подключить весы к компу, а информация очень скудная.
Знаю только, что применяется протокол Long. Для получения данных на весы предварительно необходимо отослать сигнал(ENQ=(AFh; S I CR LF) – информация из тех. документации к весам). Для записи в порт применяю WriteFile(hPort,MyBuff,Length(Str),ByteWritten,Nil). Как заполнить переменную MyBuff? smile smile

М
 
Гость_Serg, в следующий раз вопрос задавайте в отдельной теме!
Ответ на вопрос:
Код
const ENQ : array [0..4] of byte = ($AF, Ord('S'), Ord('I'), 13, 10);
WriteFile (hPort, ENQ, SizeOf(ENQ), ByteWritten, Nil)
либо
Код
var MyBuff : string;
MyBuff := #$AF + 'SI' + #13 + #10;
WriteFile(hPort,PChar(MyBuff)^,Length(MyBuff),ByteWritten,Nil);


Это сообщение отредактировал(а) p0s0l - 16.9.2005, 21:03
  Вверх
Гость_Serg
Дата 17.9.2005, 11:08 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Спасибо за помощь smile
(на счет отдельной темы я тоже все понял - в следующий раз учту smile )
  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0806 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.