Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: работа с СОМ портом  (Прочитано 15332 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Zlatoust
Интересующийся

ua
Offline Offline

« : 25-11-2011 14:14 » 

Добрый день, Знатоки!
Пишу на Borland C++ 6, Win XP.
Работаю с COM RS485 портом.
Код программы:

Код: (C)
Com1Port=CreateFile("COM5",GENERIC_READ|GENERIC_WRITE,
                     0,// устройство связи должно быть открыто для монопольного доступа
                     NULL,// нет атрибутов защиты
                     OPEN_EXISTING, // cустройства связи должен использовать OPEN_EXISTING
                     0, // нет перекрытый с I/O
                     NULL); // для коммуникационных устройств параметр hTemplate должен быть NULL

 if(Com1Port==INVALID_HANDLE_VALUE)  ShowMessage("Порт COM5 занят ");
 
// Установвить размер буфера:
    SetupComm( Com1Port, 1024, 1024 );

// Очистить буфер
    PurgeComm( Com1Port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

 // Задать установки таймаута

    ct.ReadIntervalTimeout=2;
    ct.ReadTotalTimeoutMultiplier=1;
    ct.ReadTotalTimeoutConstant=MAXDWORD;
    ct.WriteTotalTimeoutMultiplier=1;
    ct.WriteTotalTimeoutConstant=1000 ; //MAXDWORD;

    fSuccess =  SetCommTimeouts(Com1Port,&ct);   // timeout
    if (!fSuccess) ShowMessage ("( Error SetCommTimeouts)");

 // Получить текущую конфигурацию.
    fSuccess = GetCommState(Com1Port, &dcb);


  dcb.BaudRate = CBR_38400;      // устанавливаем скорость
  dcb.ByteSize  = 8;                     // размер данных xmit, и rcv
  dcb.Parity      = NOPARITY;         // нет бита четности
  dcb.StopBits = ONESTOPBIT;     // один стоп-бит
  dcb.EofChar  = '}';

    // setup hardware flow control
  dcb.fDtrControl = DTR_CONTROL_ENABLE;
  dcb.fRtsControl = RTS_CONTROL_ENABLE;
  dcb.fOutxDsrFlow = 0;
  dcb.fOutxCtsFlow = 0;

// Установить текущую конфигурацию.
  fSuccess=SetCommState( Com1Port, &dcb );
  if (!fSuccess)  ShowMessage ("(Set_CommState)");

// Послать запрос в файл
  fSuccess = WriteFile(Com1Port, Buffer, Size, &dw,NULL);
  if (!fSuccess)  ShowMessage (" Error WriteFile ");

  for (i=0; i<100; i++)          // ждем ответ
  {
  ClearCommError(Com1Port, & Errors, & Stat);
  if (Stat.cbInQue > 0 ) break;  // буфер порта
  Sleep(10);  // ждать
  }
  // гарантированно пришел ответ
  dw = 0;
  fSuccess=ReadFile(Com1Port, Buffer, 100 , &dw, NULL);

  if (dw > 0)
 после принятия данных из порта  в Buffer, уходим на обработку данных. И вроде все хорошо...

Каждые 5 секунд я запускаю таймер, который считывает данные из порта. Все работает.
Закрываю порт я по завершению работы программы по событию OnClose.

Но со мной в группе работает еще один парень, который тоже пишет программы для работы с этим же портом COM5.

 После того как отработает программа этого парня, "перестает" работать моя программа, а именно:

Код:
 ClearCommError(Com1Port, & Errors, & Stat);
  if (Stat.cbInQue > 0 ) break;  // буфер порта

Stat.cbInQue всегда равен нулю.

И помогает мне только  перезагрузка компа. Только после полной перезагрузки компа моя программа опять работает нормально.
Так вот вопрос: какую команду (или набор команд) мне нужно подать в порт, чтобы не перезагружать компьютер всякий раз, когда мне нужно поработать?



« Последнее редактирование: 25-11-2011 16:17 от Вад » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 25-11-2011 19:07 » 

Может чем поможет:
https://club.shelek.ru/viewart.php?id=208
https://club.shelek.ru/viewart.php?id=225

От BCB6 тут ничего нет. Используется лишь Win32 API.


А RS485 реализован часом не как конвертер уровней из RS232?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 25-11-2011 19:47 » 

Так, видимо, товарищ, не закрывает правильно порт, или же он на него вешает свой обработчик, но при закрытии софта забывает его отключить.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 25-11-2011 20:10 » 

Я предпочитаю подозревать более простые ошибки. Улыбаюсь
Ждем ответов ТС...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
v2
Помогающий

ua
Offline Offline

« Ответ #4 : 25-11-2011 22:11 » 

Разузнай побольше о своём COM5(RS485) (нужны ли ему RTS,DTR и зачем)
а пока попробуй сымитировать  перезагрузку:  
Код:
EscapeCommFunction(Com1Port, CLRDTR);
EscapeCommFunction(Com1Port, CLRRTS);
Sleep(_ количество_миллисекунд_перезагрузки _);  // ;)
EscapeCommFunction(Com1Port, SETRTS);
EscapeCommFunction(Com1Port, SETDTR);
« Последнее редактирование: 25-11-2011 22:14 от v2 » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 26-11-2011 09:20 » 

v2, а это сработает, если порт кем-то занят?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 26-11-2011 10:05 » 

Sla, так надо сперва это выяснить. Улыбаюсь
Мы вот третий хрустальный шар уже теряем, а ТС все молчит.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
v2
Помогающий

ua
Offline Offline

« Ответ #7 : 26-11-2011 14:31 » 

v2, а это сработает, если порт кем-то занят?
Это полушутя, но у ТС есть вот такое:
Цитата
if(Com1Port==INVALID_HANDLE_VALUE)  ShowMessage("Порт COM5 занят ");

Скорее всего или rs485 или девайс (что более правдоподобно), который на нем, "меняют" режим работы.
А перезагрузка? - дефолтные настройки порта и немного дергает ноги.

Кроме того настораживает " dcb.EofChar  = '}' "

Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 26-11-2011 15:09 » 

v2, иначе говоря, ты склоняешься к изъянам в протоколе обмена?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
v2
Помогающий

ua
Offline Offline

« Ответ #9 : 26-11-2011 16:16 » 

Скорее к недокументированности девайсов.
Ну и код попилить немного.

Досмотрел, что у ТС нет

dcb.DCBlength = sizeof (dcb);

и вместо SetCommState (помню были проблемы с IR и/или BT устройствами ) лучше

SetCommConfig
Записан
Zlatoust
Интересующийся

ua
Offline Offline

« Ответ #10 : 27-11-2011 04:47 » 

Ребята, извините за молчание, но попасть на работу в выходные я не могу. (периметр, охрана, лаборатория закрыта). Самому хочется попробовать все то, что вы подсказали.
А насчет - '}' , так это нормально. Символ указывает на конец посылки.
С "другой стороны" порта "прицеплен" ADAM-5051, там тоже "крутится" программа, которая управляет работой установки и периодически выдает информацию на верхний уровень.
Плата портов нормальная (Advantech ), драйвер - "родной". Через этот порт еще работает синхронизатор.
Давайте доживем до понедельника. Как только получу новую информацию, обязательно поделюсь результатами.
Записан
DneprSMV
Помогающий

kz
Offline Offline
Пол: Мужской

« Ответ #11 : 28-11-2011 16:21 » 

Zlatoust,
как вариант, посмотри функции API для платы и управление ею. Возможно коллега накручивает режим порта платы (к примеру режим обмена или работу-размер-режим очереди) а на умолчательный не возвращает.
Записан

"Не слушайте никаких советов, в том числе и этот" (Сократ ?)
Zlatoust
Интересующийся

ua
Offline Offline

« Ответ #12 : 01-12-2011 04:13 » 

Добрый день, знатоки! Извините за столь долгое молчание. Все мои попытки не увенчались успехом. Я снимаю свой вопрос. Пока не готов к написанию программ для работы с портом. Всем спасибо за помощь.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines