Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

Cбои при чтении с порта.   Найти похожие ветки 

 
Who_is_you? ©   (2010-04-20 10:58) [0]

Читаю с Сом порта функцией ReadFile по приходу символа (ставлю маску EV_RXFLAG).
Открываю порт, жду символ, читаю.
Нужно принять 10 таких строк.

Если запускаю программу *.exe, то все четко работает.
Если не выходя из программы закрываю порт, а потом открываю заново и читаю, то первую строку не получаю.
Получается вошел в программу: первый раз прочитал 10 строк, а второй, третий и т.д. - 9строк.

Как с этим бороться?


 
Вариант   (2010-04-20 11:07) [1]

Непонятно кто и как посылает порту данные, есть ли контроль потока данных, как настроен порт...  Какие строки ждем - как определили что строк 9, а не 10 - то есть как разделяются  принятые данные на строки - вопросов много.
Начнем с ->
Код открытия  и настройки порта, код работы с портом (ожидание события и чтения из порта) хотелось бы увидеть


 
Who_is_you? ©   (2010-04-20 13:14) [2]

Это добавление к вышесказанному:
Контроля потока данных нет. (Неплохо бы ввести CRC.)


procedure TForm1.SetupOpenPort(Sender: TObject); //Setup & open порт
begin
     //создание порта и получение его хэндла
 hCom:=CreateFile(ComX,Generic_Read or GENERIC_WRITE,0,nil,Open_Existing,
                   File_Attribute_normal or FILE_FLAG_OVERLAPPED,0);
 if hCom=Invalid_handle_Value then
   begin
     ShowMessage("Не могу открыть порт. Задайте параметры порта.");
     CloseHandle(hCom);       //закрытие порта
   end;

//  SetupComm(hCom,BufSize_rd_Com,BufSize_rd_Com);
 //ставим маску - "по пришествии определенного символа"
 SetCommMask(hCom,EV_RXFLAG);
   //построение DCB и иницализация порта
 with DCB do
   begin
     BaudRate:=115200;
     ByteSize:=8;
     Parity:=NoParity;
     StopBits:=OneStopBit;
     EvtChar:=chr($0A);     //задание символа для флага:($0A )
//      XoffLim:=$0A;
//     EvtChar:=$0A;
//     EofChar:=11;
   end;
 if not SetCommState(hCom,DCB) then     //устанавливаем DCB
   begin
     ShowMessage("Порт не настроен");
//      Application.Terminate;
   end;
end;

procedure TForm1.Button2Click(Sender: TObject); //запуск на чтение
//Var
//   sr: TSearchRec;
//   FileAttrs  :Integer;
var
  ThreadID:dword;
begin

ClearCommError(hCom,Errors,@Stat);  //сбрасываем флаг
ReadFile(hCom,wrwr,byteRead,byteRead,@Ovr);//читаем если что-то было в буфере
  //создаем паралельный поток
  // Потоки создаются функцией CreateThread,
  //   и уничтожаются функциями ExitThread и TerminateThread.
  //там будет вертеться процедура приема строки
  //с порта - ReadComm
CommThread := CreateThread(nil,0,@ReadComm,nil,0,ThreadID);
WriteComm(Ord("F"));   // чтение из DataFlash 45DB161D и передача в компьютер

Timer1.Enabled := False;
end;

procedure ReadComm;
 var
  Data_rd:array [1..14] of byte;      //  (3байта*4канала+0x0D+0x0A)
  i            :byte;
const
  BufSize_Data_rd=SizeOf(Data_rd);

 begin
    while true do
  begin
   TransMask:=0;
   WaitCommEvent(hCom,TransMask,@Ovr); //ждем
   if (TransMask and EV_RXFLAG)=EV_RXFLAG then //проверяем нужное событие
    begin
     ClearCommError(hCom,Errs,@Stat);//сбрасываем флаг, читаем Stat
     byteRead := Stat.cbInQue;
     ReadFile(hCom,Data_rd,byteRead,byteRead,@Ovr);//читаем
     //прием байт + $0D+$0A

     WriteFile(hOutFile,Data_rd,byteRead,byteRead,nil);

     FlagRead:=true; //пришли данные
    end;//mask
   end;//while
 end;



Закрываю соответственно:

TerminateThread(CommThread,0); //
CloseHandle(hCom);       //


 
Вариант   (2010-04-20 14:00) [3]


> Who_is_you? ©   (20.04.10 13:14) [2]

Насчет , что нет управления потоком (аппартный контроль или XON/XOFF   контроль) - не уверен, по крайней мере явно этого не задается в приведенном коде. Конечно соотвествующие флаги в DCB скорее всего обнулены, но просто хотел обратить на это внимание.
Далее -

hCom:=CreateFile(ComX,Generic_Read or GENERIC_WRITE,0,nil,Open_Existing,
                  File_Attribute_normal or FILE_FLAG_OVERLAPPED,0);


FILE_FLAG_OVERLAPPED  - говорит о томЮ что мы будем работать с портом в OVERLAPPED режиме и функции WaitCommEvent, ReadFile и WriteFile вернут управление в программу сразу и не обязательно с результатом true - результат надо проверять и использовать функции ожидания завершения OVERLAPPED (перекрытой) операции. В частности   WaitCommEvent(hCom,TransMask,@Ovr); //ждем
ничего не ждет, а сразу возвращает управление и еще неизвестно с каким результатом.


>  WriteFile(hOutFile,Data_rd,byteRead,byteRead,nil);

Как открыт HOutFile? Если тоже с FILE_FLAG_OVERLAPPED> то тут так же ошибка


 
Who_is_you? ©   (2010-04-21 10:30) [4]

Насчет обнуления соотвествующих флагов в DCB - спасибо. Укажу явно.

hOutFile:=CreateFile(FileName,Generic_Write,0,nil,Open_Always,File_Attribute_nor mal,0);


FILE_FLAG_OVERLAPPED  - говорит о томЮ что мы будем работать с портом в OVERLAPPED режиме и функции WaitCommEvent, ReadFile и WriteFile вернут управление в программу сразу и не обязательно с результатом true - результат надо проверять и использовать функции ожидания завершения OVERLAPPED (перекрытой) операции. В частности   WaitCommEvent(hCom,TransMask,@Ovr); //ждем
ничего не ждет, а сразу возвращает управление и еще неизвестно с каким результатом.


Ну, так вроде все правильно или я чего-то не понимаю. Что смотреть, что писать?
После WaitCommEvent я сразу проверяю: if (TransMask and EV_RXFLAG)=EV_RXFLAG then //проверяем нужное событие

А какие действия Вы имеете в виду:

Надо проверять и использовать функции ожидания завершения OVERLAPPED (перекрытой) операции.


Благодарен Вашей информации.


 
GanibalLector ©   (2010-04-21 11:24) [5]


> ReadFile(hCom,wrwr,byteRead,byteRead,@Ovr);//читаем если
> что-то было в буфере  


А зачем, если есть PurgeComm. Сбрось все что есть в буфере и все.
PurgeComm(PortHandle, PURGE_TXCLEAR or PURGE_RXCLEAR)


 
GanibalLector ©   (2010-04-21 11:32) [6]


>   ClearCommError(hCom,Errs,@Stat);//сбрасываем флаг, читаем
> Stat


А почему ты не проверяешь Errs на наличие ошибок ?
У меня, например, есть девайс, который в 50% отвечает ошибкой CE_FRAME. И продолжать чтение просто бесполезно ибо будет приходить мусор.

Есть какие-то гарантии того, что девайс 100% нормальный и таких ошибок не будет ?


 
Вариант   (2010-04-21 11:49) [7]


> Who_is_you? ©   (21.04.10 10:30) [4]
> А какие действия Вы имеете в виду:

Дополню  небольшим перечнем функций, с которыми надо ознакомиться -
WaitForSingleObject, WaitForMultipleObjects,GetOverlappedResult.
Рекоменндую поискать и посмотреть статьи по программированию последовательного порта. И еще раз обращу внимание на  необходимсоть проверки результатов функций. И WaitCommEvent и ReadFile, и WriteFile и многие другие - это функции, которые возвращают результат, который как правило надо проверить - была ли ошибка и если была, то по какой причине.


 
Who_is_you? ©   (2010-04-21 12:48) [8]

GanibalLector ©
Насчет PurgeComm - согласен.

>   ClearCommError(hCom,Errs,@Stat);//сбрасываем флаг, читаем
> А почему ты не проверяешь Errs на наличие ошибок ?

Никогда ошибок не бывало. Если читает, то читает нормально.
Но вобщем нужно об этом подумать.

Вариант   (21.04.10 11:49) [7]
Спасибо за серьезные рекомендации - отправляюсь читать.



Страницы: 1 вся ветка

Текущий архив: 2010.08.27;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.067 c
2-1267356695
Officeman
2010-02-28 14:31
2010.08.27
Помогите ! Проблема с выводом текст на принтер


2-1270365241
Ms-R
2010-04-04 11:14
2010.08.27
поворот RECT


15-1275368289
user123
2010-06-01 08:58
2010.08.27
Два интересующих меня вопроса о копировании и видеопотоке


15-1267615251
noob_one
2010-03-03 14:20
2010.08.27
Можно ли готовую dll прикомпилировать к программе?


10-1166152424
Grain
2006-12-15 06:13
2010.08.27
Excel и Windows 2000