Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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
14-1094050344
}|{yk
2004-09-01 18:52
2004.09.19
Помогите перевести


3-1093260994
Desperado
2004-08-23 15:36
2004.09.19
Конфликты транзакций


3-1092993457
Lizka
2004-08-20 13:17
2004.09.19
как вытащить значение запроса


1-1093958777
TSa
2004-08-31 17:26
2004.09.19
Адресная книга


1-1093897901
Ермак
2004-08-31 00:31
2004.09.19
Индексация текста





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