Форум: "WinAPI";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];
ВнизЧтение и запись в СОМ порт Найти похожие ветки
← →
andrey__ (2004-07-27 14:39) [0]Нашёл ссылку:
D:\Internet\delphi\Мастера DELPHI Работа с COM-портами под Windows_ (документация, исходники, скачать).htm
вроде всё понятно но пример не работает. В чем дело?
← →
andrey__ (2004-07-27 14:41) [1]извините не ту ссылку написал. Вот она:
http://www.delphimaster.ru/articles/comport2/index.html#PageTop
← →
Piter © (2004-07-27 15:28) [2]а там разве не указан e-mail автора статьи? Вот и обратись...
← →
GanibalLector © (2004-07-27 19:46) [3]то плохой пример...Поищи в этой теме в других ветках.Там все есть.
← →
AndrewVolkov © (2004-07-27 23:18) [4]то GanibalLector
Нормальный пример. Даже очень....чем он вам не нравиться? Для понимания самое то.
то Андрей
а что именно не работает?
← →
AndrewVolkov © (2004-07-27 23:27) [5]Я не поленился проверил - у меня все работает и на прием и на запись в порт.
1. Может у тебя настройки порта неверные (Скорость, Бит останова...
2. Отвечающая сторона - должна ли она реагировать на ваши запросы. И правильно ли вы формируете, то что хотите послать?
← →
Игорь Шевченко © (2004-07-27 23:32) [6]Хорошая статья:
"Одно могу сказать точно - НЕ ДЕЛАЙТЕ как сделано в примере." (цитата)
← →
GanibalLector © (2004-07-28 01:20) [7]2 AndrewVolkov
>Нормальный пример. Даже очень....чем он вам не нравиться?
Из того,что я помню сходу...(просто давно эту статью читал)...так вот,а ты запиши $0 или считай из устройства $0. И таких приятных мелочей там много!!!
← →
andrey__ (2004-07-28 11:00) [8]>AndrewVolkov © (27.07.04 23:27) [5]
>Я не поленился проверил - у меня все работает и на прием и на >запись в порт.
>1. Может у тебя настройки порта неверные (Скорость, Бит >останова...
Насколько я понял настройки задаются в примере и я их не менял
GetCommState(CommHandle,DCB); - получаем текущее DCB.
DCB.BaudRate:=CBR_9600; - устанавливаем скорость работы.
DCB.Parity:=NOPARITY; - устанавливаем отсутствие проверки на четность
DCB.ByteSize:=8; - 8 бит в передаваемом байте.
DCB.StopBits:=OneStopBit; - одиночный стоп-бит.
DCB.EvtChar:=chr(13); - вот собственно задаем символ для SetCommMask. В данном случае - возврат каретки.
SetCommState(cId,DCB); - ну теперь собственно прописываем исправленное DCB.
А проблема вообщем такая:
Запускаю программу, запускаю поток чтения, ввожу код символа в edit (например $55) и посылаю в порт, потом ввожу число 13 (без $) в edit и посылаю в порт , но никакого результата.
Я ставил точку останова в IF
if (TransMask and EV_RXFLAG)=EV_RXFLAG then
begin
ClearCommError(CommHandle,Errs,@Stat);
Kols := Stat.cbInQue;
ReadFile(CommHandle,Resive,Kols,Kols,@Ovr);
Form1.Panel1.Caption:=string(Resive);
end;
И по результатам - я не захожу в IF.
← →
andrey__ (2004-07-28 15:16) [9]Я выяснил в чем причина - у меня не получается запись в порт при выполнении ф-ции
WriteFile(CommHandle,Transmit,KolByte,KolByte,@Ovr);
Я немого изменил код примера и вставил в ф-цию записи в порт след. код для поняти какая ошибка происходит:fl:=WriteFile(CommHandle,Transmit,KolByte,KolByte,@Ovr);
if not fl then
begin
ShowMessage(SysErrorMessage(GetLastError));
end;
и у меня при попытке записать в порт выдаёт сообщение
"Протекает наложенное событие ввода/вывода"
Подскажите вчём дело и что делать?
← →
pavel_guzhanov (2004-07-28 16:43) [10]У меня была подобная проблема, решилась после того, как я стал добавлять к посылаемой в порт строке символы возврата каретки и перевода строки:
Command:="02"+#13#10;
StrPCopy(BufferIn, Command);
WriteFile(h, BufferIn, StrLen(BufferIn),.....
← →
Reindeer Moss Eater © (2004-07-28 17:06) [11]У меня была подобная проблема...
Ни малейшего подобия.
Это особенность конкретного девайса подключенного к порту.
И к самой процедуре записи в порт не имеющая не малейшего отношения.
и у меня при попытке записать в порт выдаёт сообщение
"Протекает наложенное событие ввода/вывода"
Подскажите вчём дело и что делать?
Ранее уже была инициализирована запись в порт.
Она у тебя асинхронная.
Надо ждать пока не закончится.
Ждать объект синхронизации ссылка на которой в структуре оверлаппед
← →
Reindeer Moss Eater © (2004-07-28 17:12) [12]Я выяснил в чем причина - у меня не получается запись в порт при выполнении ф-ции
WriteFile(CommHandle,Transmit,KolByte,KolByte,@Ovr);
...
fl:=WriteFile(CommHandle,Transmit,KolByte,KolByte,@Ovr);
if not fl then
begin
ShowMessage(SysErrorMessage(GetLastError));
end;
WriteFile в асинхронном режиме и не должна была вернуть True в случае успеха.
← →
Reindeer Moss Eater © (2004-07-28 17:41) [13]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/writefile.asp
← →
jack128 © (2004-07-28 19:15) [14]
> GetCommState(CommHandle,DCB); - получаем текущее DCB.
> DCB.BaudRate:=CBR_9600; - устанавливаем скорость работы.
> DCB.Parity:=NOPARITY; - устанавливаем отсутствие проверки
> на четность
> DCB.ByteSize:=8; - 8 бит в передаваемом байте.
> DCB.StopBits:=OneStopBit; - одиночный стоп-бит.
> DCB.EvtChar:=chr(13); - вот собственно задаем символ для
> SetCommMask. В данном случае - возврат каретки.
> SetCommState(cId,DCB);
К слову говоря, такую манеру изменения параметров порта, вроде сама Microsoft cоветует, да? ИМХО в корне не правильно. лудше так ZeroMemory(@dcb, SizeOf(dcb)); и выставить все параметры самостоятельно...
← →
Reindeer Moss Eater © (2004-07-29 10:50) [15]Замечательный совет.
Особенно если в DCB не хотим ничего менять кроме одного конкретного параметра.
← →
andrey__ (2004-07-29 11:44) [16]Что бы записать в порт и считать из порта у меня должно ли быть подключено к нему какое-то устройство (скажем модем) или можно и без устройства?
← →
Reindeer Moss Eater © (2004-07-29 12:10) [17]Что бы выйти из самолета через дверь, обязательно ли что бы был подан трап? Или можно без трапа?
← →
DeepProg (2004-07-29 12:34) [18]andrey__
Если нужно не этот пример заставить работать, а вообще разобраться, то полезно было наведаться в Поздемелье Магов(http://www.delphikingdom.ru/mastering/index.htm).
Почитайте вот это:
1.Работа Титова - там почти все, что касается непосредственно портов.
http://delphi.mtu-net.ru/zip/com_win32.zip
2. Цикл статей по портам начинается здесь - http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=388
3. Здесь про синхронную работу(несмотря на название) http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=723
← →
andrey__ (2004-07-29 16:57) [19]Как узнать что данные были записаны в порт, если WriteFile возвращает False.
← →
Reindeer Moss Eater © (2004-07-29 17:14) [20]По ссылке из [13] ходил?
Пост № 11 читал?
← →
Reindeer Moss Eater © (2004-07-29 17:28) [21]Если файл открыт с флагом оверлаппед, и если чтение запись использует структуру оверлаппед, то любой успешный вызов чтения записи возвращает False;
Следующий за этим GetlastError должен сказать IO_PENDING.
Убедившись в этом, надо вызвать функцию ожидания объекта синхронизации ссылка на который содержится в оверлаппед структуре (не забыв создать сам объект ожидания)
А когда объект просигналит - можно считать сколько там чего было принято и отправлено.
← →
anton. (2004-07-30 10:10) [22]To andrey__
Мучаюсь с этой же проблемой, если разберешься напиши в форум
← →
andrey__ (2004-07-30 10:25) [23]Это имелось в виду?
WriteFile(CommHandle,Transmit,KolByte,KolByte,@Ovr);
if GetLastError = Error_IO_PENDING then
if not GetOverlappedResult(CommHandle,Ovr,n,true)then
ShowMessage(SysErrorMessage(GetLastError))
else
← →
anton. (2004-07-30 10:40) [24]Мне нужно что бы хоть что то появилось на панели прием :-)
← →
Reindeer Moss Eater © (2004-07-30 10:53) [25]Это имелось в виду?
Это, но не только это.
Перед GetOverLappedResult надо дождаться пока просигналит евент
← →
anton. (2004-07-30 11:00) [26]нашел вот такой пример
wOverlapped.hEvent := CreateEventA(nil, False, False,‘SendEvent‘);
IsSended := WriteFile(hComm, Buff, SizeOf(Buff), ByteNum, @wOverlapped);
if not IsSended then begin
ErrorCode := GetLastError;
if ErrorCode = ERROR_IO_PENDING then begin
if WaitForSingleObject(wOverlapped.hEvent, TimeOut) <> WAIT_OBJECT_0 then begin
ErrorCode := GetLastError;
CloseHandle(wOverlapped.hEvent);
← →
andrey__ (2004-07-30 15:19) [27]WaitCommEvent(CommHandle,TransMask,@Ovr);
постоянно выдаёт False, я TransMask равняется - 0;
Как мне тогда впоймать нужное событие?
← →
Reindeer Moss Eater © (2004-07-30 15:47) [28]Третью строчку поста 21 проситай вниметельно.
Особенно вторую её половину.
← →
andrey__ (2004-07-30 16:15) [29]То что я понял:
procedure TForm1.FormCreate(Sender: TObject);
begin
Ovr.hEvent := CreateEventA(nil, False, False,"SendEvent");
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
CloseHandle(Ovr.hEvent);
end;procedure ReadComm;
var
Resive:array [0..255] of char;
fl :LongBool;
n, ErrorCode: Cardinal;
begin
while true do
begin
TransMask:=0;
fl:= WaitCommEvent(CommHandle,TransMask,@Ovr); //ждем
if not fl then
begin //1
ErrorCode := GetLastError;
if ErrorCode = ERROR_IO_PENDING then
if WaitForSingleObject(Ovr.hEvent, 5000) <> WAIT_OBJECT_0 then
begin //11
ErrorCode := GetLastError;
end //11
else
begin //12
if (TransMask and EV_RXFLAG)=EV_RXFLAG then //проверяем нужное событие
begin //121
ClearCommError(CommHandle,Errs,@Stat);//сбрасываем флаг
Kols := Stat.cbInQue;
ReadFile(CommHandle,Resive,Kols,Kols,@Ovr);//читаем
Form1.Panel1.Caption:=string(Resive);
end; //121
end; //12
end; //1
end;//while
end;
Дело в том что я не паподаю на строкуif (TransMask and EV_RXFLAG)=EV_RXFLAG then
//проверяем нужное событие
← →
Reindeer Moss Eater © (2004-07-30 16:47) [30]Дело в том что я не паподаю на строку
А ты посмотри чем ты маску проинициализировал
← →
andrey__ (2004-07-30 17:08) [31]>Reindeer Moss Eater © (30.07.04 16:47) [30]
>А ты посмотри чем ты маску проинициализировал
Вот чем:
SetCommMask(CommHandle,EV_RXFLAG);
← →
andrey__ (2004-08-02 10:35) [32]ало.
← →
Reindeer Moss Eater © (2004-08-02 10:39) [33]Вот чем:
SetCommMask(CommHandle,EV_RXFLAG);
А вот это кто писал?
TransMask:=0;
fl:= WaitCommEvent(CommHandle,TransMask,@Ovr); //ждем
← →
andrey__ (2004-08-02 11:39) [34]Как я понял, переменная TransMask не инициализирует маску события, а служит для того чтобы в неё записывался результат - маска того события, которое произошло.
TransMask:=0;
WaitCommEvent(CommHandle,TransMask,@Ovr); //ждем
if (TransMask and EV_RXFLAG)=EV_RXFLAG then //проверяем нужное событие
само событие задаётся :SetCommMask(CommHandle,EV_RXFLAG);
← →
Reindeer Moss Eater © (2004-08-02 13:19) [35]Я что-то нить беседы терять начал.
Ты же асинхронную запись в порт отлаживаешь, а не чтение
Зачем тебе WaitCommEvent вообще?
← →
andrey__ (2004-08-02 13:51) [36]Я хотел прощупать механизмы работы с СОМ портами (так как текущая задача предполагает это), но у меня не работает даже элементарный пример:
andrey__ (27.07.04 14:41) [1]
← →
Reindeer Moss Eater © (2004-08-02 14:15) [37]Возьми ссылку из поста 13 и щупай наздоровье.
Там пример тоже элементарный, но рабочий.
← →
andrey__ (2004-08-03 11:29) [38]Давайте так. Я написал примерчик см. ниже. Поместите на форму кнопку и Label и скопируете пример в обработчик кнопки.
строка fl:=WriteFile(port,buf_out,strlen(buf_out),bc,nil);
выполняетсянормально: fl=true, bc=11 как и понимаю запись в порт произошла.
А вот строка fl:=ReadFile(port,buf_in,strlen(buf_out),bc,nil);
после ее выполнения: fl=true bc=0 т.е. ничего не считал.
Почему я не могу считать с порта то что записал? Кто знает прошу подсказать.procedure TForm1.Button1Click(Sender: TObject);
var
dcb:tDCB;
ct:COMMTIMEOUTS;
port:tHANDLE;
bc:DWORD;
buf_out:Pchar;
buf_in:Pchar;
fl:LongBool;
begin
buf_out:=StrNew("Test string");
dcb.DCBlength:=sizeof(tDCB);
BuildCommDCB("baud=9600 parity=N data=8 stop=1",dcb);
//dcb.fNull:=TRUE;
ct.ReadIntervalTimeout:=10;
ct.ReadTotalTimeoutMultiplier:=100;
ct.ReadTotalTimeoutConstant:=100;
ct.WriteTotalTimeoutMultiplier:=10;
ct.WriteTotalTimeoutConstant:=10;
port:=CreateFile("COM1",GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0);
SetCommState(port,dcb);
SetCommTimeouts(port,ct);
PurgeComm(port,PURGE_TXCLEAR or PURGE_RXCLEAR);
SetupComm(port,256,256);
buf_in:=HeapAlloc(GetProcessHeap(),0,strlen(buf_out)+1);
fl:=WriteFile(port,buf_out,strlen(buf_out),bc,nil);
if not fl then
beep;
fl:=ReadFile(port,buf_in,strlen(buf_out),bc,nil);
if not fl then
beep;
Label1.Caption:=string(buf_in);
HeapFree(GetProcessHeap(),0,buf_in);
CloseHandle(port);
end;
← →
andrey__ (2004-08-03 16:24) [39]ало!
← →
Reindeer Moss Eater © (2004-08-03 16:29) [40]Почему я не могу считать с порта то что записал? Кто знает прошу подсказать.
А почему ТЫ должен прочитать то, что ТЫ записал в порт?
Причем и читаешь и пишешь ты в один и тот же порт.
Я бы еще понял нуль-модемный кабель и запись в com1 с чтением из com2.
PS не надо тупо и настойчиво алёкать. Не надо приводить здесь свои бредовые примеры.
Надо читать и разбирать примеры из документаци.
Прощай.
Страницы: 1 2 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.09.19;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.034 c