Ввод/вывод СОМ порта

Тема в разделе "Общие вопросы по С и С++", создана пользователем innovator, 1 сен 2009.

Наш партнер Genesis Hackspace
  1. innovator

    innovator Гость

    [codebox]//---------------------------------------------------------------------------

    #include <vcl.h>
    #pragma hdrstop

    #include "UMain.h"
    #include "UFLog.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    HANDLE hCom;
    COMMTIMEOUTS ct;
    int addres = 16;
    char *buf_out,
    cnt=0,
    *buf_in;
    DWORD bc;

    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    }


    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    FLog->ShowModal(); // открытие формы заставки. Чтобы ShowModal(); работало надо в свойстве Visible главной формы и формы заставки выставить значение false!
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::ButtonStartClick(TObject *Sender)
    {
    // коментарии по книге "Последовательные интерфейсы ПК. Практика программирования" (Агуров, 2004)
    ct.ReadIntervalTimeout=10; // задаёт допустимый интервал ожидания в миллисекундах между получением двух символов
    ct.ReadTotalTimeoutMultiplier=0; // множитель в миллисекундах
    ct.ReadTotalTimeoutConstant=0; // задаёт константу, добовляемую к произведению, получае мую при вычислении времени из ReadTotalTimeoutMultiplier
    ct.WriteTotalTimeoutMultiplier=0; // анологично для чтения
    ct.WriteTotalTimeoutConstant=0; // аналогично для чтения
    hCom = CreateFile ("COM1", // название порта
    GENERIC_READ|GENERIC_WRITE, // порт используется как для чтения, так и для записи
    0, // общий доступ к порту запрещён
    NULL, // атрибуты защиты не используются и устанавливаются в NULL
    OPEN_EXISTING, // открыть ресурс если он существует, или вернуть ошибку если не существует
    FILE_FLAG_OVERLAPPED, // FILE_ATTRIBUTE_NORMAL- синхроный режим, FILE_FLAG_OVERLAPPED - асинхронный режим
    NULL); // последний параметр обязательно NULL

    if (hCom == INVALID_HANDLE_VALUE) // если при открытии порта была ошибка, то
    Panel1->Caption = "ERROR COM"; // вывести на панель
    else
    {
    DCB dcb = {0}; // инициализация DCB
    if (!GetCommState(hCom, &dcb)) // если проинициализировался с ошибкой, то
    {Panel1->Font->Size=30; Panel1->Caption = "ERROR BCD";} // вывести на панель
    else
    {
    dcb.BaudRate = 38400; // скорость соединеия
    dcb.ByteSize = 8; // размер слова
    dcb.Parity = EVENPARITY; // проверка на чётность
    dcb.StopBits = TWOSTOPBITS; // два стоповых бита
    if(!SetCommState(hCom, &dcb)) // если BCD не про инициализировалась, то
    {Panel1->Font->Size=20; Panel1->Caption = "ERROR Setup BCD";}
    else
    {
    SetCommTimeouts(hCom, &ct); // установка таймаутов
    PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR); // очистка приёмника и передатчика
    SetupComm(hCom, 256, 256); // Устанавливает размер в байтах очередей приёма и передачи рекомендуемые
    buf_out = &addres;
    Timer1->Enabled=true; // запуск таймера после инициализации порта
    }
    }
    }
    }
    //---------------------------------------------------------------------------

    void __fastcall TForm1::ButtonStopClick(TObject *Sender)
    {
    Timer1->Enabled = false; // остановка таймера
    //buf_in=(char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(buf_out)+1);
    cnt=0; // обнуление считчика ошибки чтения
    Label1->Caption = " ";
    CloseHandle(hCom); // закрытие порта
    }
    //---------------------------------------------------------------------------


    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
    if ((WriteFile(hCom, // передач деструктора порта
    buf_out, // буфер данных
    strlen(buf_out), // размер буфера данных
    &bc, // число переданых байт
    NULL)) // параметры ассинхронной передачи
    == 0) // если передача не удалась, то
    Label1->Caption = "Error Write";
    else {
    if ((ReadFile(hCom, // передач деструктора порта
    buf_in, // буфер для принятых данных
    strlen(buf_in), // размер буфера для принятых данных
    &bc, // число принятых байт
    NULL)) // параметры ассинхронной передачи
    == 0) // если приём не удался, то
    {
    ++cnt;
    Label1->Caption = "Error Read: " + cnt;
    }
    else // если всё хорошо, то
    {
    Panel1->Caption = *buf_in; // вывести на экран значение
    }
    }
    }
    //---------------------------------------------------------------------------[/codebox]

    Здравствуйте формучане. Есть вопросик по этому коду. Функция передачи данных WriteFile возвращает 0 (признак ошибки передачи), хотелось бы услышать Ваши ответы почему. Есть такая мысль что из-за того, что тип буфера buf_out char, а тип передаваемого адреса int. Может и из-за конфигурации?
    Заранее благгодарен.
    На всякий случай приложил файл.
     

    Вложения:

    • UMain.cpp
      Размер файла:
      5,6 КБ
      Просмотров:
      18
  2. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    При помощи GetLastError() получите код ошибки и вы узнаете почему
     
  3. innovator

    innovator Гость

    Например прописать a=GetLastError(); ?
    И ещё такая мысль: А может запись в порт возвращать 0, т.к нету ответа от устройства подключённого к порту, Или кабель не подключён?
    А функцию сейчас попробую.
     
  4. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Например... В а будет код ошибки, описание ошибки найдете в MSDN
     
  5. innovator

    innovator Гость

    Прописал так:
    Код (Text):
    int addres = 16, cnt=0, n;
    LPDWORD a;
    LPCOMSTAT b;
    unsigned char buf_out[1],
    buf_in[2];
    DWORD    bc;
    buf_out[0] = addres;
    if ((WriteFile(hCom,                                      // передач деструктора порта
    buf_out,                                         // буфер данных
    strlen(buf_out),                                 // размер буфера данных
    &bc,                                             // число переданых байт
    NULL))                                        // параметры ассинхронной передачи
    == 0)                                        // если передача не удалась, то
    {n=ClearCommError(hCom, a, b); Label1->Caption = "Error Write" + IntToStr(n);}
    и выдал n=1. Я не знаю что такое MSDN, посмотрел в Агуров. Написано что переполнение буфера либо раньше принят сигнал EOF.
     
  6. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
  7. innovator

    innovator Гость

    Те так вот сказать по коду не можешь, что не так? С английским худо у меня. А на русской версии про Сом не нашёл.
     
Загрузка...

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