Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Программирование под Windows > WinAPI
Перезагрузить страницу Как сделать чтение COM-порта
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
Ondyon Ondyon вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 30.03.2005
По умолчанию Как сделать чтение COM-порта - 19.07.2006, 13:09

Уже много про это писали, прочитал все, все равно не получается.

Делаю все, как написано, при чтении в OVERLAPPED режиме
срабатывает событие прихода символа,
GetOverlappedResult тоже возвращает, что чтение завершилось,
но число реально прочитанных байт 0.

Пробовал после такого неуспешного чтения делать

ResetEvent(sync.hEvent);
и
CloseHandle(sync.hEvent); и заново его создавать перед запуском чтения
и
ClearCommBreak(com_port);
и
и даже SetCommBreak(com_port); перед чтением ставил! не блокирует!!

Вот код

Код:
com_port = CreateFile( "COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

while(1) {
    char *buffer=(char*)malloc(1000);
    buffer[1]=0;
    memset(&sync,0,sizeof(OVERLAPPED));
    sync.hEvent=CreateEvent(NULL,TRUE,NULL,NULL);

    SetCommMask(com_port,EV_RXCHAR);

    DWORD real_bytes;
    int res=ReadFile(com_port, buffer, 40, &real_bytes, &sync);
    if(res) { 
        print("Read freely - strange!"); 
        print(real_bytes);
        continue; 
        }
    DWORD err=GetLastError();
    if(err!=ERROR_IO_PENDING) { print("Read Error - strange!"); break; }
    Scope->Post("pending");           // ВСЕ ВЕРНО, ИДЕТ СЮДА

    DWORD wait=WaitForSingleObject(sync.hEvent, 1000);
    if(wait==WAIT_TIMEOUT) { print("timeout...");   /* do something */ continue; }
    if(wait==WAIT_OBJECT_0) {
        print("trigged...");     //СОБЫТИЕ СРАБАТЫВАЕТ!!
        real_bytes=0;
        res=GetOverlappedResult(com_port, &sync, &real_bytes, FALSE);
        if(!res) print("still working");     //НЕТ, ОПЕРАЦИЯ ЗАВЕРШИЛАСЬ ВРОДЕ
        print(real_bytes);       // А ВОТ ПРОЧИТАНО 0 БАЙТ!
        Sleep(100);
        }
    ClearCommBreak(com_port);   //ВСЕ ЭТО НЕ ПОМОГАЕТ
    ResetEvent(sync.hEvent);         //ВСЕ ЭТО НЕ ПОМОГАЕТ
    CloseHandle(sync.hEvent);       //ВСЕ ЭТО НЕ ПОМОГАЕТ и идет заново

    free(buffer);
    Sleep(200);
    }


================================================== =========

попробовал без OVERLAPPED
ТО ЖЕ САМОЕ!!!

int res=ReadFile(com_port, buffer, 40, &real_bytes, NULL);

успешно завершается, но говорит, что реально прочитано 0 байт.

пробовал ставить настройки порта - пофигу
например, вот такие:

Код:
    DCB dcb;
    res=GetCommState(com_port, &dcb);
    if(!res) { Scope->Post("Cannot get port parameters"); return; }
    dcb.BaudRate=CBR_9600;
    dcb.fBinary=TRUE;
    dcb.fParity=FALSE;
    dcb.fOutxCtsFlow=FALSE;
    dcb.fOutxDsrFlow=FALSE;
    dcb.fDtrControl=DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity=FALSE;
    dcb.fTXContinueOnXoff=TRUE;
    dcb.fOutX=FALSE;
    dcb.fInX=FALSE;
    dcb.fErrorChar=FALSE;
    dcb.fNull=FALSE;
    dcb.fRtsControl=RTS_CONTROL_DISABLE;
    dcb.fAbortOnError=FALSE;
    dcb.ByteSize=8; 
    dcb.Parity=NOPARITY;  
    dcb.StopBits=ONESTOPBIT;
    res=SetCommState(com_port, &dcb);
    if(!res) { Scope->Post("Cannot set port parameters"); return; }
Ответить с цитированием
  (#2 (permalink)) Старый
Ondyon Ondyon вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 30.03.2005
По умолчанию 19.07.2006, 13:58

Тестируюсь с помошью старой комовской мышки.
Драйвер в винде удален.
Программка CommTest показывает, что все работает.
Правда при старте сразу же приходят 80h 80h 00h
но дальше-то все.
а у меня ноль идет бесконечно (т.е. не ноль, а "0 байт прочитано");
Ответить с цитированием
  (#3 (permalink)) Старый
Shadow_Replicant Shadow_Replicant вне форума
Member
 
Сообщений: 322
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 10.08.2005
По умолчанию 19.07.2006, 14:35

я слегка изменил ваш код под BCB, но идея думаю понятно будет, у меня этот код работает :
Код:
HANDLE com_port = CreateFile( "COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (com_port == INVALID_HANDLE_VALUE){
  Memo1->Lines->Add("Error in openning ");
  return;
}
if (!SetCommMask(com_port,EV_RXCHAR)) Memo1->Lines->Add("RXCHAR event not set");
OVERLAPPED sync;
memset(&sync,0,sizeof(OVERLAPPED));
sync.hEvent=CreateEvent(NULL,TRUE,NULL,NULL);
char *buffer= new char[1001];
while(1) {
  Application->ProcessMessages();
  DWORD real_bytes;
  int res=ReadFile(com_port, buffer, 1000, &real_bytes, &sync);
  if(res) {
    Memo1->Lines->Add("Read freely - strange!" + IntToStr(real_bytes)+ " : " + buffer);
    continue;
  }
  DWORD err=GetLastError();
  if ((res==false) && (err==ERROR_IO_PENDING)) {
    //Memo1->Lines->Add("ERROR_IO_PENDING");
    //Scope->Post("pending");
  }

  DWORD wait=WaitForSingleObject(sync.hEvent, 1000);
  if(wait==WAIT_TIMEOUT) { Memo1->Lines->Add("timeout..."); continue; }
  if(wait==WAIT_OBJECT_0) {
    Memo1->Lines->Add("trigged...");
    real_bytes=0;
    res=GetOverlappedResult(com_port, &sync, &real_bytes, FALSE);
    if (!res) Memo1->Lines->Add("still working");
    else {
      buffer[real_bytes] = 0;
      Memo1->Lines->Add(IntToStr(real_bytes));
      Memo1->Lines->Add(buffer);
    }
  }
}
delete[] buffer;
Sleep(1000);
CloseHandle(sync.hEvent);
Ответить с цитированием
  (#4 (permalink)) Старый
Ondyon Ondyon вне форума
Новичок
 
Сообщений: 4
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 30.03.2005
По умолчанию 19.07.2006, 15:40

А в чем разница?

Вот, кусок кода, где закомментаренные 2 строчки
про "pending"
Это не ошибка, это нормально, если read выдает ERROR_PENDING
ну, это не важно, все равно оно дальше идет после этого блока.

У меня, кстати, этот код,
в отличие от первого, наоборот, все время писал "timeout"
на WaitForSingleObject несмотря на данные, которые валились в порт.
А потом я увидел второе отличие - количесвто байт на чтение в команде ReadFile.
У вас оно 1000
у меня было 1 или 40
когда я вернул свое значение, все стало работать по-старому.

Может, еще какие-то принципиальные изменения не заметил?

У меня ощущение, что проблема в настройках порта.
Тем более, что при СИНХРОННОМ режиме (без OVERLAPPED) тоже ничего не работает,
read пролетает успешно, прочитав 0 байт

Может, еще какие-то идеи есть?
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Из USB порта идет дым. DiM88 Любые вопросы от новичков 7 26.08.2010 21:26
Инициализация COM порта в С++ Денисrf Visual C++ 18 12.10.2009 20:48
Работа с СОМ-портом как сделать чтение данных Nick64 Delphi 0 05.10.2006 10:32
Шпионаж LPT порта Serj_psv Железо. Написание драйверов 1 02.02.2006 00:39
Работа с портами как сделать проверку порта Zoomie Delphi 3 26.12.2005 18:01
Чтение с Com порта по маске события в асинхронном режиме MaMaV C++ Builder 33 07.12.2005 20:19
Чтение данных из Com порта по событию EV RXCHAR Bun C++ Builder 5 28.11.2005 16:18
Как сделать чтение из файла построчно Sosed Вопросы начинающих программистов 2 20.04.2005 01:53
Чтение MIDI-файлов как это сделать Mew Delphi 2 29.08.2004 02:17
Программа для Com-порта Алексей Демидов Работа 1 16.04.2004 09:56
Как сделать чтение из файла imported_solaris С/С++ 24 29.12.2003 14:40
Как программно сделать чтение из файла EvroStandart Delphi 9 17.06.2003 17:04



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов