Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Непонятная работа COM-порта, Непонятная работа COM-порта 
:(
    Опции темы
Alexander06
Дата 26.9.2006, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 90
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Мне необходимо через ком-порт работать с устройством. Отсылать 2 байта команды и получать 4 байта ответ.
Когда посылаю команду, ответ приходит не всегда, а почему-то через раз. То есть на первый запрос ответа нет, а на второй есть.
Опрашиваю их VC++. При работе через специализированный софт LabVIEW железка отвечает на каждый опрос.
Может я как-то неверно работаю с ком-портом?
Работаю с помощью функций работы с файлами.
PM MAIL   Вверх
TimeMan
Дата 26.9.2006, 19:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 26.9.2006

Репутация: нет
Всего: нет



В WIN API есть очень много интересных функций для работы  с СОМ-портом (с хендлом открытым через СreateFile и асоциированным с портом):
BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
DeviceIoControl
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
GetDefaultCommConfig
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetDefaultCommConfig
SetupComm
TransmitCommChar
WaitCommEvent 

Глянь их описание в MS SDK- найдеш много интересного. 
Но в принципе, если ты знаеш, какие настройки должны быть у твоего порта (должны совпадать с настройками порта того устройства с которым работаешь) то можно, для начала сравнить их с теми, которые устанавливаються по дефолту. Для того, чтобы достать параметры уже установленные для порта можно использовать функцию или GetCommState, изменение установленных параметров SetCommState . 
PM MAIL   Вверх
Gremlin
Дата 28.9.2006, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



у меня в принципе тоже самый трабл я в другом топике писал
При выполнении
Код

void CMultiAmp::ReadABuffer(void)
{
    char Command[1024] = "LV1;OE1;";
    strcat(Command, "TS");
    strcat(Command, "\n");
    WriteABuffer(&Command[0], strlen(Command));
    if (!PurgeComm(hPort, PURGE_TXCLEAR && PURGE_RXCLEAR)) 
        MessageBox("Error purging port");
    OVERLAPPED OverRead = {0};
    COMSTAT ComStat;
    DWORD dwMask, dwError;
    char Buf[1024];                         
    DWORD dwRead; 
    if (!SetCommMask(hPort, EV_RXCHAR)) 
        MessageBox("Error setting port mask");
    OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (OverRead.hEvent == NULL) 
        MessageBox("Error creating write event");
    
    if  (!WaitCommEvent(hPort, &dwMask, &OverRead)) 
    {
        if (GetLastError() == ERROR_IO_PENDING)
            WaitForSingleObject(OverRead.hEvent, INFINITE);
        else 
            AfxMessageBox("Error waiting port event");
    }
   
    if (!ClearCommError(hPort, &dwError, &ComStat))
           MessageBox("Error clearing port"); 
    
    dwRead = ComStat.cbInQue; 
    
    if (dwRead > 0) 
    {
        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead)) 
             MessageBox("Error reading port");
    }
    
    // В  Buf находятся прочитанные байты
    // Далее идет  обработка принятых байтов
}

Buf0x00f4f648 "20:0\n\nTММ..." char[1024]
а у меня должно прийти TS8.150 что такое 20:0 вроде я Purge тоесть очищаю все что там есть и почему ловится только один символ Т
если делаю так
Код

while(1){
 if (!ClearCommError(hPort, &dwError, &ComStat))
           MessageBox("Error clearing port"); 
    
    dwRead = ComStat.cbInQue; 
    
    if (dwRead > 0) 
    {
        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead)) 
             MessageBox("Error reading port");
    }
}

то на первой итерации Buf0x00f4f648 "20:0\n\nTММ..." char[1024]
а на второй и последующих Buf0x00f4f648 "S8.150E+00ММ..." char[1024]
почему у меня сразу в буфер не заносится TS8.150E+00 хз не могу разобраться

PM MAIL   Вверх
Romikgy
Дата 29.9.2006, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



скорости правильно установлены?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Gremlin
Дата 29.9.2006, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



2Romikgy: а неее с этим разобрался уже
Вот как сделал
Код

void CMultiAmp::ReadABuffer(void)
{
     
    if (!PurgeComm(hPort, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR) )
        MessageBox("Error purging port");
    
    OVERLAPPED OverRead = {0};
    COMSTAT ComStat;
    DWORD dwMask, dwError;
    char Buf[1024];                         
    DWORD dwRead; 
    if (!SetCommMask(hPort, EV_RXCHAR)) 
        MessageBox("Error setting port mask");
    OverRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (OverRead.hEvent == NULL) 
        MessageBox("Error creating write event");
    
    // задержка для обдумывания команды прибором
    Sleep(150);
    
    if  (!WaitCommEvent(hPort, &dwMask, &OverRead)) 
    {
        if (GetLastError() == ERROR_IO_PENDING)
            WaitForSingleObject(OverRead.hEvent, INFINITE);
        else 
        {
            AfxMessageBox("Error waiting port event");
            return;
        }
    }
    if (!ClearCommError(hPort, &dwError, &ComStat))
        MessageBox("Error clearing port"); 
    
    dwRead = ComStat.cbInQue; 
        
    if (dwRead > 0) 
    {
        if (!ReadFile(hPort, Buf, dwRead, &dwRead, &OverRead)) 
            MessageBox("Error reading port");
    }
    
    // В  Buf находятся прочитанные байты
    // Далее идет  обработка принятых байтов
    for (int i=0; i< strlen(Buf); i++)
    {
        if (Buf[i] == 13)
            break;
        m_BufString.AppendChar(Buf[i]);
    }
        
    MessageBox(m_BufString);
    TransleteCOM();
    
    
}

тока после этого я уже в когда в порт пишу а прибор не реагирует 
есть мысль что я SetCommMask(hPort, EV_RXCHAR) перевел его в чтение а обратно нет! Подскажите в чом может быть трабл и как его поправить.(эта процедура у меня в отдельном потоке)

Это сообщение отредактировал(а) Gremlin - 29.9.2006, 18:26
PM MAIL   Вверх
Romikgy
Дата 29.9.2006, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(Gremlin @  29.9.2006,  17:20 Найти цитируемый пост)
есть мысль что я SetCommMask(hPort, EV_RXCHAR) перевел его в чтение а обратно нет! 

эта ф_ция не переводит никуда, она добаляет событие на срабатывание
и если она у тя в отдельном потоке , зачем те события?

Добавлено @ 21:44 
и что не получается?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Gremlin
Дата 30.9.2006, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 119
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



Код

void CMultiAmp::OnDetect()
{
    // TODO: Add your control notification handler code here
    m_Detect = true;
    if (hPort == NULL)
    {
        MessageBox("Откройте COM порт");
        return;
    }
    //получение данных с первого канала
    char Command[1024] = "LV1;"; 
    strcat(Command, "OE;TS;LP;TC");
    strcat(Command, "\n");
    WriteABuffer(&Command[0], strlen(Command));

    HANDLE hstream  = (HANDLE)_beginthread(StaticReadABuffer,0,(void*)this);
}

Вот я так опрашиваю состояние прибора! И когда я пытаюсь послать какую нибудь другую команду  прибор на нее не реагирует! 
а функция записи 
Код

bool CMultiAmp::WriteABuffer(char* lpBuf, DWORD dwToWrite)
{    
    OVERLAPPED osWrite = {0};
    DWORD dwWritten;
    DWORD dwRes;
    bool fRes;

   // Create this write operation's OVERLAPPED structure's hEvent.
    osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (osWrite.hEvent == NULL)
    {
       // error creating overlapped event handle
        MessageBox("Error creating write event");
        return false; 
    }
    // Issue write.
    if (!WriteFile(hPort, lpBuf, dwToWrite, &dwWritten, &osWrite))
    {    
        if (GetLastError() != ERROR_IO_PENDING) 
        { 
            MessageBox("Error writing port"); 
            fRes = false;
        }
        else
        {
            // Write is pending.
            dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
            switch(dwRes)
            {
                // OVERLAPPED structure's event has been signaled. 
                case WAIT_OBJECT_0:
                    if (!GetOverlappedResult(hPort, &osWrite, &dwWritten, FALSE))
                        fRes = FALSE;
                    else
                    // Write operation completed successfully.
                    fRes = TRUE;
                    break;
                
                default:
                    // An error has occurred in WaitForSingleObject.
                    // This usually indicates a problem with the
                    // OVERLAPPED structure's event handle.
                    fRes = FALSE;
                    break;
            }
        }
    }
    else
    {    
       // WriteFile completed immediately.
        fRes = TRUE;
    }

    CloseHandle(osWrite.hEvent);
    return fRes;
}

Может в функции Read тоже нужно делать CloseHandle?

Это сообщение отредактировал(а) Gremlin - 30.9.2006, 07:44
PM MAIL   Вверх
ATN
Дата 12.5.2008, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.5.2008

Репутация: нет
Всего: нет



Цитата(TimeMan @ 26.9.2006,  19:53)
В WIN API есть очень много интересных функций для работы  с СОМ-портом (с хендлом открытым через СreateFile и асоциированным с портом):
BuildCommDCB
BuildCommDCBAndTimeouts
ClearCommBreak
ClearCommError
CommConfigDialog
DeviceIoControl
EscapeCommFunction
GetCommConfig
GetCommMask
GetCommModemStatus
GetCommProperties
GetCommState
GetCommTimeouts
GetDefaultCommConfig
PurgeComm
SetCommBreak
SetCommConfig
SetCommMask
SetCommState
SetCommTimeouts
SetDefaultCommConfig
SetupComm
TransmitCommChar
WaitCommEvent 

Глянь их описание в MS SDK- найдеш много интересного. 
Но в принципе, если ты знаеш, какие настройки должны быть у твоего порта (должны совпадать с настройками порта того устройства с которым работаешь) то можно, для начала сравнить их с теми, которые устанавливаються по дефолту. Для того, чтобы достать параметры уже установленные для порта можно использовать функцию или GetCommState, изменение установленных параметров SetCommState .

Да, но только там нет ответа на вопрос, почему при установке события: ev_txempty в setcommmask waitcommevent возвращает 4. Ведь если по описанию то это совсем другое событие, а я ничего кроме ev_txempty  не ставлю. smile 
PM MAIL   Вверх
xvr
Дата 12.5.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Во первых зачем тебе Overlapped IO, если его возможности не используются? Используй обычные блокирующие ReadFile и WriteFile.
Во вторых, рекомендуется выставлять timeout'ы на порт (по крайней мере для приема)
Так же возможны разные варианты с нарезкой принятых байтов по вызовам ReadFile - никто не гарантирует, что ответ придет за одно чтение, так же никто не гарантирует, что начало ответа не будет принято сразу после окончание предыдущего в одном вызове ReadFile (за исключением протокола работы с прибором, но это уже дело самого прибора)

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.