Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.065 c
2-1274355596
Jacksotnik
2010-05-20 15:39
2010.08.27
Помогите составить SQL запрос


2-1271055485
JohnKorsh
2010-04-12 10:58
2010.08.27
Как программно закрыть информационное сообщение.


8-1205173351
Ramzes001
2008-03-10 21:22
2010.08.27
Помогите!


2-1274083814
Сид
2010-05-17 12:10
2010.08.27
TDBLookupComboBox для редактирования поля


15-1273523397
Юрий
2010-05-11 00:29
2010.08.27
С днем рождения ! 11 мая 2010 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский