-
Умные люди, не бросьте в беде :)! Совсем уже нет мыслей по чему такое может может произойти. Создаю поток, в котором ожидаю приёма, но ничего не принимается (слушаю эхо). Передача проходит корректно (проверено). procedure TComRead.Execute;
var
ComStat: TComStat;
dwMask, dwError: DWORD;
OverRead: TOverlapped;
Buf: array[0..20] of char;
dwRead: DWORD;
dd: string;
begin
FreeOnTerminate := True;
while not Terminated do
begin
dwMask:=0;
WaitCommEvent(CId, dwMask, @OverRead);
if dwMask = EV_RXCHAR then
begin
ClearCommError(CId, dwError, @ComStat);
dwRead := ComStat.cbInQue;
if dwRead > 0 then
begin
ReadFile(CId, Buf, dwRead, dwRead, @OverRead);
Form2.Panel1.Caption:=string(Buf);
end;
end;
end;
end; Всё упрощено, но по моему работать должно??
-
а проконтролировать выполнение условий?
-
И вообще, не маловат ли Buf? И не стоит ли его очищать перед приемом? И каким макаром выбран именно этот компорт, а не какой-нить еще, коих в системе дофига может быть? И где его инициализация?
-
> И вообще, не маловат ли Buf?
Передаю и принимаю 1 байт.
> И каким макаром выбран именно этот компорт, а не какой-нить > еще, коих в системе дофига может быть? И где его инициализация? >
Инициализация в основном потоке, я хе говорил, передача происходит корректно. > а проконтролировать выполнение условий?
Контроль убран уже от безысходности. С ним тоже ничего не работает.
-
А, я подумал, что имеется ввиду передача от того, кто передает...
-
> PooHer (07.07.09 00:17) [3] > > > > И вообще, не маловат ли Buf? > > Передаю и принимаю 1 байт.
Уууу. Опять "идиотская" синхронная работа с асинхронным по своей сути устройством.
-
> Германн ©
а с чего ты решил, что устройство асинхронно? только из-за протокола? Так это очень и очень спорно. Зависит от параметров синхронности. предположим, раз в год в течении суток. Что, асинхронность передачи в этом случае будет так заметна и как-то влиять? Да и синхронность тут тоже совершенно не видна.
-
> PooHer (06.07.09 23:58)
> dwMask:=0; > WaitCommEvent(CId, dwMask, @OverRead);
Я так понимаю, ты открыл порт указав флаг FILE_FLAG_OVERLAPPED? WaitCommEvent у тебя использует OverRead и вернется не ожидая событий. Для ожидания событий надо вызвать WaitForXXX функцию и/или GetOverlappedResult. И ты не проверяешь результат возврата WaitCommEvent (false/true + GetLastError в случае ошибки). Может быть и ошибка, но указывающая , что идет операция перекрытого ввода/вывода (это нормально) или другая.... И кстати, а SetCommMask ты вызывал?
-
+ и опять те же грабли с обращением к VCL-контролам в доп.потоке
-
Черным же по белому в справке написано:
If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must .. point to a valid OVERLAPPED structure
> Контроль убран уже от безысходности
Вот если бы ты не убирал контроль результатов вызовов WinAPI-функций (сомневаюсь что он вообще у тебя был), то он бы сразу показал тебе, что WaitCommEvent() вернула отказ по причине очевидной инвалидности переданного ей параметра OverRead.
-
То же самое касается вызова ReadFile - те же грабли в ту же точку приложения)
-
Чтение изначально было такое: procedure TReadThread.Execute;
var
ComStat: TComStat;
dwMask, dwError: DWORD;
OverRead: TOverlapped;
Buf: array[0..$FF] of Byte;
dwRead: DWORD;
begin
OverRead.hEvent := CreateEvent(nil, True, False, nil);
if OverRead.hEvent = Null then
raise Exception.Create('Error creating read event');
FreeOnTerminate := True;
while not Terminated do
begin
if not WaitCommEvent(cId, dwMask, @OverRead) then
begin
if GetLastError = ERROR_IO_PENDING then
WaitForSingleObject(OverRead.hEvent, INFINITE)
else
raise Exception.Create('Error waiting port event');
end;
if not ClearCommError(cId, dwError, @ComStat) then
raise Exception.Create('Error clearing port');
dwRead := ComStat.cbInQue;
if dwRead > 0 then
begin
if not ReadFile(cId, Buf, dwRead, dwRead, @OverRead) then
raise Exception.Create('Error reading port');
end;
end;
end; Инициализация: cId:= CreateFile(‘COM1’, GENERIC_READ or GENERIC_WRITE, 0, nil,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if cId= INVALID_HANDLE_VALUE then
raise Exception.Create('Error opening port');
if not GetCommState(cId, Dcb) then
raise Exception.Create('Error setting port state');
Dcb.BaudRate := CBR_9600;
Dcb.Parity := NOPARITY;
Dcb.ByteSize := 8;
Dcb.StopBits := ONESTOPBIT;
if not SetCommState(cId, Dcb) then
raise Exception.Create('Error setting port state');
if not PurgeComm(cId, PURGE_TXCLEAR or PURGE_RXCLEAR) then
raise Exception.Create('Error purging port');
-
> Чтение изначально было такое
И что же подвигло тебя убрать проверки (пусть даже элементарные), фигурировашие в изначальном варианте ?
-
> И что же подвигло тебя убрать проверки (пусть даже элементарные), > фигурировашие в изначальном варианте ?
Да то, что не работает ничего, замучался уже. Во втором потоке программа крутится на ожидании звента, фактически данные отправляются и приходят в порт на 100%.
-
Вообще, с Delphi только начинаю работать. Проектирую устройства на микроконтроллерах, пишу на АСМе. Встал вопрос о сопряжении МК и ПК. С Delphi последний раз общался лет 8 назад, забыл всё что знал, а знал мало :) То, что данные уходят корректно проверено на железяке(МК).
-
100% рабочий пример кода есть у кого? Пусть даже самый простой, без проверок(сам допишу). Просто мне кажется, что у меня какая-то ПРИНЦИПИАЛЬНАЯ ошибка в коде, но в виду отсутствия опыта, определить её не представляется возможным. Можно, конечно, использовать готовые библиотеки, но очень хочется познать суть (Собственно по этому и пишу для МК на АСМе, а не на Си или Баскоме).
-
> не работает ничего
И в этом, надо понимать, виноваты те самые проверки, которые ты убрал ?
Но ведь если изначально эти проверки тобой выполнялись, то значит ты же ожидал увидеть хоть какой-либо результат их "деятельности" ? А вместо ожидаемого сообщения 'Error при попытке выполнения такой-то конкретно функции', ты, значит, увидел сообщение "Не работает ничего ! Да ну их нафих эти проверки, все равно толку от них ноль !", потому и убрал проверки ? Я правильно логику твоих действий понимаю ?)
-
> PooHer (07.07.09 11:19) [15]
Как уже писали выше - этот вариант в [11] ближе к нормальному. Но и в нем нет SetCommMask - и какие тогда события ты хочешь отслеживать, если не указал это? ПРочитай про SetCommMask, поставь это в инициализации порта и мне кажется что-то у тебя уже должно заработать.
-
-
И снова не все увидел, у тебя в [11] вообще нет обработки событий порта. Зачем тебе тогда WaitCommStatus? Ладно, почитай статьи....
|