Как прочесть состояние COM-порта

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Dias2004
Посетитель
Сообщения: 29
Зарегистрирован: 31 Январь 2006, 15:02
Откуда: Россия, Москва

Как прочесть состояние COM-порта

Сообщение Dias2004 »

Задача: по внешнему физическому событию (нажатие тревожной кнопки) программа на Clarion должна выполнить некие действия. Напрограммировать действие удалось без проблем.

Как заметить событие?
Поскольку внешний мир для ПК - это скорее всего состояние портов,
как наиболее просто обратиться к COM-порту?

Я так понимаю, что для этих целей существуют Windows API, но до сих пор ни разу не приходилось пользоваться...

Если есть опыт или хотя бы мнение по поводу способов решения задачи, подскажите пожалуйста.
Аватара пользователя
Andrew Listiev
Активист
Сообщения: 166
Зарегистрирован: 07 Июль 2005, 11:16
Откуда: Латвия, Рига

Сообщение Andrew Listiev »

Приветствую!

Как ты уже отметил, лучше использовать Win API. В своё время написал хороший набор классов для работы с последовательным портом. По личному опыту могу сказать, что лучше не придумать, полная свобода. Есть сторонние библиотеки, такие как ClaCom (вроде так, насколько помню :D , только платные) пользовал также. Довольно приличные. Есть MSCom.ocx (опять-таки могу ошибиться в названии). Так что есть поле для исследований :wink:
Dias2004
Посетитель
Сообщения: 29
Зарегистрирован: 31 Январь 2006, 15:02
Откуда: Россия, Москва

Сообщение Dias2004 »

Написал код на Дельфи. Всего две функции:
1. открыть порт (CreateFile).
2. прочесть его состояние.

Выглядит это так:

Код: Выделить всё


<декларация переменных>
  hport: THandle;
  vStatus: dword;

<однократно исполняемый код>
  hport := CreateFile('COM1',
                      GENERIC_READ,
                      0,
                      nil,
                      OPEN_EXISTING,
                      0,
                      0);

 Win32Check(hport <> INVALID_HANDLE_VALUE);

<код, исполняемый по таймеру>
  Win32Check(GetCommModemStatus(hport,vStatus));

Работает. Значение vStatus прекрасно отражает текущее состояние входов порта.
Хочу написать это на Clarion, но не знаю и не нашел пока как описать тип данных указатель (handle) на файл.

Пробовал объявить прототип функции CreateFile, как указано в справочнике по WinAPI, имеющемуся в примерах, вот так:

Код: Выделить всё

CreateFileA(*LPCSTR,DWORD,DWORD,*SECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE),HANDLE,PASCAL,RAW
но компилятор сразу ругается на возвращаемый тип HANDLE - illegal return type. Подскажите, кто знает, как составить правильное описание?
Аватара пользователя
StillZero
Ветеран
Сообщения: 454
Зарегистрирован: 06 Июль 2005, 2:17
Откуда: Хабаровск
Контактная информация:

Сообщение StillZero »

*LPCSTR - по нашему *CSTRING
DWORD - LONG
*SECURITY_ATTRIBUTES - можно создать группу, тогда это будет указатель на нее, тебе можно заменить на LONG и передавать 0
HANDLE - LONG

получается так вроде:
CreateFileA(*CSTRING,LONG,LONG,LONG,LONG,LONG,LONG),LONG,PASCAL,RAW
Dias2004
Посетитель
Сообщения: 29
Зарегистрирован: 31 Январь 2006, 15:02
Откуда: Россия, Москва

Сообщение Dias2004 »

Спасибо, я продвинулся!
Все собралось, и порт открылся. Но при попытке получить статус - ошибка. В чем может быть проблема?

Выглядит так:

Код: Выделить всё


<Equates>
GENERIC_READ           EQUATE(80000000h)
OPEN_EXISTING          EQUATE(3)
INVALID_HANDLE_VALUE    EQUATE(-1)

BOOL                     EQUATE(SIGNED)
DWORD                  EQUATE(ULONG)
HANDLE                  EQUATE(UNSIGNED)
LPCSTR                  EQUATE(CSTRING)



<прототипы>
    CreateFile(*LPCSTR,DWORD,DWORD,DWORD,DWORD,DWORD,HANDLE),HANDLE,PASCAL,RAW,NAME('CreateFileA')
    GetCommModemStatus(HANDLE,DWORD),BOOL,PASCAL,RAW,NAME('GetCommModemStatus')



PortCOM1   cstring('COM1')
hPort          long
vStatus       long

<однократно открыли порт>
  hPort = CreateFile(PortCOM1,GENERIC_READ,0,0,OPEN_EXISTING,0,0)
  IF hPort = INVALID_HANDLE_VALUE
    message('Порт COM1 открыть не удалось.')
  .

<по таймеру запрашиваем статус>
IF GetCommModemStatus(hPort,vStatus).
Вызов GetCommModemStatus возвращает 0 (ошибка) и значение vStatus всегда остается нулем независимо от состояния порта. При этом код на Дельфи (см. первое сообщение) работает, и состояние порта отслеживается.
Знатоки, помогите заблудшему.
Аватара пользователя
StillZero
Ветеран
Сообщения: 454
Зарегистрирован: 06 Июль 2005, 2:17
Откуда: Хабаровск
Контактная информация:

Сообщение StillZero »

GetCommModemStatus неверно описан, смотри внимательнее в MSDN, второй параметр это out и соотвественно должен быть описан как *DWORD или что-тоже *LONG

чтобы узнать почему ошибка см GetLastError.

кстати в описании говорится, что эта функция GetCommModemStatus должна использоваться вместе с WaitCommEvent
Dias2004
Посетитель
Сообщения: 29
Зарегистрирован: 31 Январь 2006, 15:02
Откуда: Россия, Москва

Сообщение Dias2004 »

StillZero, действительно я проигнорировал тип параметра out, хуже того - даже и не знал, что это есть передача по ссылке...

Все заработало, спасибо!

Что касается использования WaitCommEvent: в описании не сказано, что ее использование обязательно, просто функция позволяет избавиться от необходимости циклического вызова GetCommModemStatus. В моем конкретном случае в программе уже имеется таймер и его обработчик, поэтому я решил не возиться с еще одной функцией, а организовать именно циклический вызов.
Аватара пользователя
Admin
Администратор
Сообщения: 3959
Зарегистрирован: 05 Июль 2005, 15:59
Откуда: Хабаровск
Благодарил (а): 25 раз
Поблагодарили: 22 раза
Контактная информация:

Сообщение Admin »

еще вот посмотри: http://files.clarionlife.net/dialer.zip
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
han
Новичок
Сообщения: 6
Зарегистрирован: 27 Октябрь 2008, 11:52

Re:

Сообщение han »

Admin писал(а):еще вот посмотри: http://files.clarionlife.net/dialer.zip
Зарегистрировался в приват, получил разрешение админа, но скачать не могу мой login и password не проходят.
Ч.Д.
Аватара пользователя
Admin
Администратор
Сообщения: 3959
Зарегистрирован: 05 Июль 2005, 15:59
Откуда: Хабаровск
Благодарил (а): 25 раз
Поблагодарили: 22 раза
Контактная информация:

Re: Re:

Сообщение Admin »

han писал(а):
Admin писал(а):еще вот посмотри: http://files.clarionlife.net/dialer.zip
Зарегистрировался в приват, получил разрешение админа, но скачать не могу мой login и password не проходят.
Ч.Д.
Читаем тут: http://forum.clarionlife.net/phpbb/view ... =15&t=1326
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
Ответить