Форум: "Начинающим";
Текущий архив: 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.06 c