Как получить данные с Com порта?

Тема в разделе "MS Visual C++", создана пользователем DeLure, 17 сен 2007.

Статус темы:
Закрыта.
  1. DeLure

    DeLure Гость

    Подскажите пожалуйста как можна реализовать такую процедуру, как сохранение/отображение в окне данных приходящих в COM-порт (например с АЦП). Можно ли это реализовать как динамически изменяющююся зависимость (в риалтайме)?

    Может существует какя нибудь литература по этому поводу, или исходники, подскажите пожалуйста.

    Зарание огромное спасибо!!!
     
  2. zubr

    zubr Гость

    Есть неплохая книга Агурова "Программирование последовательных интерфейсов" (в названии точно не уверен, по памяти). В сети была в электронном виде.
     
  3. Dmitriy.Ch

    Dmitriy.Ch Гость

    Кстати, пытаюсь разобраться с классом для асинхронного чтения с Com порта из этой книги и переписать его на Си.
    Подскажите как на Си проверять не завершен ли поток и как вызвать функцию основного окна из функции потока
     
  4. zubr

    zubr Гость

    Вот пример из MSDN:
    Код (Text):
    Monitoring Communications Events
    The following example code opens the serial port for overlapped I/O, creates an event mask to monitor CTS and DSR signals, and then waits for an event to occur. The WaitCommEvent function should be executed as an overlapped operation so the other threads of the process can perform I/O operations during the wait.



    #include <windows.h>
    #include <assert.h>
    #include <stdio.h>

    void main( )
    {
    HANDLE hCom;
    OVERLAPPED o;
    BOOL fSuccess;
    DWORD dwEvtMask;

    hCom = CreateFile( "COM1",
    GENERIC_READ | GENERIC_WRITE,
    0,  // exclusive access
    NULL, // default security attributes
    OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED,
    NULL
    );

    if (hCom == INVALID_HANDLE_VALUE)
    {
    // Handle the error.
    printf("CreateFile failed with error %d.\n", GetLastError());
    return;
    }

    // Set the event mask.

    fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);

    if (!fSuccess)
    {
    // Handle the error.
    printf("SetCommMask failed with error %d.\n", GetLastError());
    return;
    }

    // Create an event object for use by WaitCommEvent.

    o.hEvent = CreateEvent(
    NULL,  // default security attributes
    FALSE, // auto reset event
    FALSE, // not signaled
    NULL    // no name
    );


    // Intialize the rest of the OVERLAPPED structure to zero.
    o.Internal = 0;
    o.InternalHigh = 0;
    o.Offset = 0;
    o.OffsetHigh = 0;

    assert(o.hEvent);

    if (WaitCommEvent(hCom, &dwEvtMask, &o))
    {
    if (dwEvtMask & EV_DSR)
    {
    // To do.
    }

    if (dwEvtMask & EV_CTS)
    {
    // To do.
    }
    }
    else
    {
    DWORD dwRet = GetLastError();
    if( ERROR_IO_PENDING == dwRet)
    {
    printf("I/O is pending...\n");

    // To do.
    }
    else
    printf("WaitCommEvent failed with error %d.\n", GetLastError());
    }
    }
     
  5. Dmitriy.Ch

    Dmitriy.Ch Гость

    А как вызвать функцию основного окна или отобразить принятый символ например в EditBox
     
  6. DeLure

    DeLure Гость

    Я написал, откомпелировал и запустил программу, которая по сути должна выводить на экран информацию поступающую на СОМ-порт.
    Для проверки работоспособности такой программы подключил мишь в СОМ-порт.

    После запуска консоль была чистая и ничего не выполнялось.

    Прежде того что бы искать ошибки программы, хотелось бы знать можно ли таким способом проверять прогу? Не загружает ли Виндовс мишь операционными командами и этим не давая работать моей программе?

    Как лучше проверить такую прогу, если никакого микроконтролера и АЦП под рукой нету))??
     
  7. zubr

    zubr Гость

    Так же как и в обычной программе. Если чтение-запись COM-порта производится в потоке - передавай в качестве параметра в поток указатель на класс основного окна this и работай с ним в потоке.
    А что должно было выполняться? Если COM-порт не был ни с каким устройством связан или устройство молчало, то ничего с него не получишь.
    2 способа:
    1. Если на компе есть 2 COM-порта, соединяем их нуль-модемом (специальный провод, только нужно его сделать правильно, иначе спалишь компорт(ы)). Пишем программку с 1 кнопкой и 2-мя окошками - 1 окошко и кнопка для отправки данных в компорт, 2-ое окошко для приема данных из компорта. Запускаем 2 экземпляра приложения с подключением их к разным компортам и с одного передаем данные в компорт, с другого получаем и наоборот.
    2. Работаем с обычным модемом. Посылаем команды модему из программы и читаем ответы модема в программе.
     
  8. Dmitriy.Ch

    Dmitriy.Ch Гость

    Я нашел лучшее решение. Передовать информацию из потока чтения о том, что пришел очередной байт, в класс основного окна с помощью сообщений.
     
  9. zubr

    zubr Гость

    Чем это решение лучше?
     
  10. Dmitriy.Ch

    Dmitriy.Ch Гость

    а чем хуже?
     
  11. skysun

    skysun Гость

    Есть еще решение синхронизировать доступ к буферу(в который пишутся данные с порта) из разных потоков с помощью, например семафора. Так например если один поток изменил буфер то он же меняет состояние семафора. Во втором потоке происходит событие и он быстренько копирует данные из буфера.


    Не самый простой способ, но (по моему) самый красивый и надежны.
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей