Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.09.19;
Скачать: CL | DM;

Вниз

Чтение и запись в СОМ порт   Найти похожие ветки 

 
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 не надо тупо и настойчиво алёкать. Не надо приводить здесь свои бредовые примеры.
Надо читать и разбирать примеры из документаци.
Прощай.


 
DeepProg   (2004-08-04 00:45) [41]

А с чем, собственно, поговорить пытаетесь?
С модемом аль еще чем?


 
andrey__   (2004-08-05 10:52) [42]

Все нашел, в чем дело разъем (заглушка, которую я поставил на СОМ1)который мне дали, оказался поломан.

>Reindeer Moss Eater ©   (03.08.04 16:29) [40]

>А почему ТЫ должен прочитать то, что ТЫ записал в порт?
>Причем и читаешь и пишешь ты в один и тот же порт.
>Я бы еще понял нуль-модемный кабель и запись в com1 с чтением >из com2.

Если ты начал читать эту тему с начала, то понял бы что я вожусь с конкретным примером andrey__   (27.07.04 14:41) [1] который использует заглушку на порт и записывает и считывает данные с одного порта.
Если на COM1 установить перемычку между сигналами TxD и RxD, то переменная buf_in, после выполнения ReadFile, будет содержать ту же информацию, что и buf_out. Других пояснений пример не требует, все уже было подробно рассмотрено раньше. Хотя твой вариант тоже работает но у меня один СОМ порт.

>PS не надо тупо и настойчиво алёкать. Не надо приводить здесь >свои бредовые примеры.
А ты "крутой" только на клавиатуре?



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

Текущий архив: 2004.09.19;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.063 c
1-1094278842
Соколов
2004-09-04 10:20
2004.09.19
TextFile


14-1093686049
Yakudza
2004-08-28 13:40
2004.09.19
Т. Бадд. Объектно-ориентированное программирование .


8-1087798849
Korneley
2004-06-21 10:20
2004.09.19
Нужен пример захвата видео


3-1093333516
r9000
2004-08-24 11:45
2004.09.19
Ошибка при использовании отчета на QuickRep.


14-1092948046
ИМХО
2004-08-20 00:40
2004.09.19
Николай Карполь