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

Вниз

COM порт Win API. Проблемы с приёмом.   Найти похожие ветки 

 
PooHer   (2009-07-06 23:58) [0]

Умные люди, не бросьте в беде :)!
Совсем уже нет мыслей по чему такое может может произойти.
Создаю поток, в котором ожидаю приёма, но ничего не принимается (слушаю эхо). Передача проходит корректно (проверено).
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; {while}
end;
end;

Всё упрощено, но по моему работать должно??


 
KilkennyCat ©   (2009-07-07 00:03) [1]

а проконтролировать выполнение условий?


 
KilkennyCat ©   (2009-07-07 00:10) [2]

И вообще, не маловат ли Buf?
И не стоит ли его очищать перед приемом?
И каким макаром выбран именно этот компорт, а не какой-нить еще, коих в системе дофига может быть? И где его инициализация?


 
PooHer   (2009-07-07 00:17) [3]


> И вообще, не маловат ли Buf?

Передаю и принимаю 1 байт.

> И каким макаром выбран именно этот компорт, а не какой-нить
> еще, коих в системе дофига может быть? И где его инициализация?
>

Инициализация в основном потоке, я хе говорил, передача происходит корректно.
> а проконтролировать выполнение условий?

Контроль убран уже от безысходности. С ним тоже ничего не работает.


 
KilkennyCat ©   (2009-07-07 00:19) [4]

А, я подумал, что имеется ввиду передача от того, кто передает...


 
Германн ©   (2009-07-07 02:21) [5]


> PooHer   (07.07.09 00:17) [3]
>
>
> > И вообще, не маловат ли Buf?
>
> Передаю и принимаю 1 байт.

Уууу. Опять "идиотская" синхронная работа с асинхронным по своей сути устройством.


 
KilkennyCat ©   (2009-07-07 03:38) [6]


> Германн ©

а с чего ты решил, что устройство асинхронно? только из-за протокола? Так это очень и очень спорно. Зависит от параметров синхронности. предположим, раз в год в течении суток. Что, асинхронность передачи в этом случае будет так заметна и как-то влиять?
Да и синхронность тут тоже совершенно не видна.


 
Вариант   (2009-07-07 08:01) [7]


> PooHer   (06.07.09 23:58)


> dwMask:=0;
> WaitCommEvent(CId, dwMask, @OverRead);

Я так понимаю, ты открыл порт указав флаг  FILE_FLAG_OVERLAPPED?
WaitCommEvent  у тебя использует OverRead и вернется не ожидая событий. Для ожидания событий надо вызвать  WaitForXXX функцию и/или GetOverlappedResult. И ты не проверяешь результат возврата WaitCommEvent (false/true + GetLastError  в случае ошибки). Может быть и ошибка, но указывающая , что идет  операция перекрытого ввода/вывода (это нормально) или другая.... И кстати, а SetCommMask ты вызывал?


 
Сергей М. ©   (2009-07-07 09:24) [8]

+ и опять те же грабли с обращением к VCL-контролам в доп.потоке


 
Сергей М. ©   (2009-07-07 09:32) [9]

Черным же по белому в справке написано:

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must .. point to a valid OVERLAPPED structure


> Контроль убран уже от безысходности


Вот если бы ты не убирал контроль результатов вызовов WinAPI-функций (сомневаюсь что он вообще у тебя был), то он бы сразу показал тебе, что WaitCommEvent() вернула отказ по причине очевидной инвалидности переданного ей параметра OverRead.


 
Сергей М. ©   (2009-07-07 09:34) [10]

То же самое касается вызова ReadFile - те же грабли в ту же точку приложения)


 
PooHer   (2009-07-07 11:19) [11]

Чтение изначально было такое:
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");
// В Buf находятся прочитанные байты
// Далее идет обработка принятых байтов
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");


 
Сергей М. ©   (2009-07-07 11:34) [12]


> Чтение изначально было такое


И что же подвигло тебя убрать проверки (пусть даже элементарные), фигурировашие в изначальном варианте ?


 
PooHer   (2009-07-07 11:43) [13]


> И что же подвигло тебя убрать проверки (пусть даже элементарные),
>  фигурировашие в изначальном варианте ?

Да то, что не работает ничего, замучался уже.
Во втором потоке программа крутится на ожидании звента, фактически данные отправляются и приходят в порт на 100%.


 
PooHer   (2009-07-07 11:47) [14]

Вообще, с Delphi только начинаю работать. Проектирую устройства на микроконтроллерах, пишу на АСМе. Встал вопрос о сопряжении МК и ПК. С Delphi последний раз общался лет 8 назад, забыл всё что знал, а знал мало :)
То, что данные уходят корректно проверено на железяке(МК).


 
PooHer   (2009-07-07 11:53) [15]

100% рабочий пример кода есть у кого? Пусть даже самый простой, без проверок(сам допишу). Просто мне кажется, что у меня какая-то ПРИНЦИПИАЛЬНАЯ ошибка в коде, но в виду отсутствия опыта, определить её не представляется возможным.
Можно, конечно, использовать готовые библиотеки, но очень хочется познать суть (Собственно по этому и пишу для МК на АСМе, а не на Си или Баскоме).


 
Сергей М. ©   (2009-07-07 12:07) [16]


> не работает ничего


И в этом, надо понимать, виноваты те самые проверки, которые ты убрал ?

Но ведь если изначально эти проверки тобой выполнялись, то значит ты же ожидал увидеть хоть какой-либо результат их "деятельности"  ?
А вместо ожидаемого сообщения "Error при попытке выполнения такой-то конкретно функции", ты, значит,  увидел сообщение "Не работает ничего ! Да ну их нафих эти проверки, все равно толку от них ноль !", потому и убрал проверки ? Я правильно логику твоих действий понимаю ?)


 
Вариант   (2009-07-07 13:00) [17]


> PooHer   (07.07.09 11:19) [15]

Как уже писали выше - этот вариант в [11] ближе к нормальному. Но и в нем нет SetCommMask - и какие тогда события ты хочешь отслеживать, если не указал это? ПРочитай про SetCommMask, поставь это в инициализации  порта и мне кажется что-то у тебя уже должно заработать.


 
Вариант   (2009-07-07 13:08) [18]

Кстати и про SetCommTimeouts тоже стоит почитать
Посмотри статьи на
http://www.delphikingdom.com/asp/section.asp?id=2
http://www.delphikingdom.com/asp/itemq.asp?Mode=1&ItemID=151
На том же сайте можешь поискать статьи
"Работа с портами ввода-вывода в DELPHI"


 
Вариант   (2009-07-07 13:19) [19]

И снова не все увидел, у тебя в [11] вообще нет обработки событий порта. Зачем тебе тогда WaitCommStatus? Ладно, почитай статьи....


 
PooHer   (2009-07-07 14:58) [20]

cId := CreateFile(PChar("COM"+IntToStr(Num)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,0);

SetCommMask(cId, EV_RXCHAR);

Вот так было.


 
Сергей М. ©   (2009-07-07 15:23) [21]


> PooHer   (07.07.09 14:58) [20]


Работа с маской событий вообще не нужна, равно как и Wait/ClearCommEvent
Равно как лишен смысла и overlapped ввод-вывод в доп.потоке, не делающем более ничего существенного, кроме собственно ввода-вывода из/в СОМ-порт


 
PooHer   (2009-07-07 15:50) [22]


> Работа с маской событий вообще не нужна, равно как и Wait/ClearCommEvent

Ну а как тогда работать?


 
Вариант   (2009-07-07 15:55) [23]


> PooHer   (07.07.09 15:50) [22]

Если не нужна специфика работы с портом и подробная расшифровка специфичных ошибок, то достаточно ReadFile и WriteFile. Но настройка порта нужна.


 
Вариант   (2009-07-07 15:57) [24]


> PooHer   (07.07.09 15:50) [22]

Статьий глянь, их много в интернете. На королевстве дельфи посмотри, ссылки давал


 
PooHer   (2009-07-07 18:51) [25]

Ну если просто вот так, в цикле сразу после передачи читать, должно работать?
(Не смеяться, это просто в качестве эксперимента.
procedure TForm2.Button4Click(Sender: TObject);

var
datas: string;
dwWrite: DWORD;
OverWrite: TOverlapped;
//WriteBytes: array of Byte;
//********************************
Buf: array[0..1] of Char;
dwRead, Read: DWORD;
i: integer;
//********************************
begin
//передача
datas:="a";
//dwWrite:=datas;
OverWrite.hEvent := CreateEvent(nil, True, False, nil);
if OverWrite.hEvent = Null then
raise Exception.Create("Error creating write event");

if (not WriteFile(cId, datas, SizeOf(datas),
dwWrite, @OverWrite))
and (GetLastError <> ERROR_IO_PENDING) then
raise Exception.Create("&#206;&#248;&#232;&#225;&#234;&#224; &#238;&#242;&#239;&#240;&#224;&#226;&#234;&#232;");

//********************************
//цикл приёма
for i:=1 to 2000 do
begin
dwRead:=10;
buf:="0";
ReadFile(cId, Buf, dwRead, Read, nil);
if Buf[0] <> "0" then
panel1.caption:=string(Buf);
end;
//********************************
end;


 
Вариант   (2009-07-08 06:48) [26]


> PooHer   (07.07.09 18:51) [25]

Не смеюсь.Нет, работать не будет. " В одну телегу впрячь не можно. Коня и трепетную лань." (с) А. С. Пушкин - это к тому, что есди ты используешь перектрытый ввод/вывод, открыл порт с флагом FILE_FLAG_OVERLAPPED, то и запись и чтение у тебя должны быть overlapped, а ты читать пытаешься синхронно.
И потом, если ты делаешь overlapped(перекрытую) операцию ввода/вывода, то где -то и как-то надо получить и результат ее завершения - это значит использовать или GetOverlappedResult и/или WaitForSingleObject или WaitForMultipleObjects. И ты не читал статей ?

Прочитай, выбери один какой-то вариант работы и доводи его до ума. А то у тебя тут куча вариантов, все разные. И ошибки появляются снова и не уходят из-за этого.


 
Сергей М. ©   (2009-07-08 10:26) [27]


> PooHer   (07.07.09 18:51) [25]


Зачем тебе overlapped ввод-вывод ?
Не нужен он тебе вообще.
Не усложняй себе жизнь.



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

Форум: "WinAPI";
Текущий архив: 2011.03.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.004 c
2-1293698764
nza
2010-12-30 11:46
2011.03.27
фиксированные строки


2-1293796610
tippa
2010-12-31 14:56
2011.03.27
входит ли строка в поток?


15-1290889921
set
2010-11-27 23:32
2011.03.27
Атрибуты на папках


2-1293384218
ProgRAMmer Dimonych
2010-12-26 20:23
2011.03.27
PaintBox как в MS Paint (только WinAPI)


15-1291622692
Медвежонок Пятачок
2010-12-06 11:04
2011.03.27
Есть такая профессия ....





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский