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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Программирование интерфейса RS232 
:(
    Опции темы
Gremlin
Дата 20.9.2006, 08:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 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 находятся прочитанные байты
    // Далее идет  обработка принятых байтов
}

заметил что переводит в состояние Ожидание байтов, и даже после выполнения функции и завершения потока я не могу записать в порт. поэтому в конце я стал ставить  
Код

if (!SetCommMask(hPort, 0)
        MessageBox("Error setting port mask");

тогда все нормально!
Но вот проблема начинается в другом! Задача у меня следующая: Есть кнопки Старт и Стоп. Нажимаю Старт и открывается поток с функией Write которая причом в цикле посылает команду опрашивать текущее значение!
Нажимаю клавишу Стоп цыкл останавливается. Сразу после открытия потока Write открывается поток с Read
Код

void CKistlerMeasuringHardwareDlg::OnStart()
{
    // TODO: Add your control notification handler code here
    HANDLE hstream  = (HANDLE)_beginthread(StaticWriteCOM,0,(void*)this);
    HANDLE hstreamr  = (HANDLE)_beginthread(StaticReadCOM,0,(void*)this);
}

Но в buf ничего не приходит тк ком порт занят Write, подскажите как мне разрулить эти два потока!

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


Шустрый
*


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

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



вот так реализован цикл
Код

void CKistlerMeasuringHardwareDlg::WriteCOM(void)
{
    if (!PurgeComm(hPort, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR) )
        MessageBox("Error purging port");
    
    MultiAmpT1.hPort = hPort;

    CountMeasuring = 0;
    char CommandStart[5]= "RO1";
    char CommandStop[5]= "RO0";
    char Command[100] = "";
    if (!hPort)
    {
        MessageBox("Нет открытых портов!");
        return;
    }
    
    if(!MultiAmpT1.WriteABuffer(&CommandStart[0], strlen(CommandStart)))
        return;
    if (MultiAmpT1.m_Status1 == true)
        strcat(Command, "LV1;V=;");
    if (MultiAmpT1.m_Status2 == true)
        strcat(Command, "LV2;V=;");
    if (MultiAmpT1.m_Status3 == true)
        strcat(Command, "LV3;V=;");
    if (MultiAmpT1.m_Status4 == true)
        strcat(Command, "LV4;V=;");
    // Активизация кнопок 
    CButton* start = (CButton*) GetDlgItem(IDC_START);
    start->EnableWindow(false);
    CButton* stop = (CButton*) GetDlgItem(IDC_STOP);
    stop->EnableWindow(true);
    while (StopFlag == false)
    {
        MultiAmpT1.WriteABuffer(&Command[0], strlen(Command));
        Sleep(100);
        CountMeasuring++;
    }
    
    
    start->EnableWindow(true);
    stop->EnableWindow(false);

    StopFlag = false;
    CString str;
    str.Format("%i",CountMeasuring);
    
    //MessageBox(str);
    if (!SetCommMask(MultiAmpT1.hPort, 0)) 
        MessageBox("Error setting port mask");
    if(!MultiAmpT1.WriteABuffer(&CommandStop[0], strlen(CommandStop)))
        return;
    return;
}


Это сообщение отредактировал(а) Fixin - 7.10.2006, 09:03
PM MAIL   Вверх
Gremlin
Дата 8.10.2006, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Это сообщение отредактировал Fixin - 7.10.2006, 09:03 ????????
PM MAIL   Вверх
Gremlin
Дата 8.10.2006, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 и еше вопрос почему чтобы получить коректно данные мне приходится вводить Sleep и подбирать милисекунды хотя поидее назначая маску EV_RXCHAR (событие получение символа) а потом идет (!WaitCommEvent(hPort, &dwMask, &OverRead))  тоесть ждать до наступления события маски дак почему мне приходится искуственно вводить задержку?
PM MAIL   Вверх
GremlinProg
Дата 8.10.2006, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



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

Добавлено @ 22:07 
поток, по сути нужен только для того, чтобы винду не вешать во время чтения.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Gremlin
Дата 9.10.2006, 05:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



дак мне тогда придется чтобы послать кнопочку старт жать smile ведь мне нужно чтобы команды постоянно посылались до того момента пока я не выключу а как это реализовать без цыкла?????

Добавлено @ 05:30 
я то делаю поток на Write  именно для того чтоб из основного потока смог остановить цыкл и завершить поток
PM MAIL   Вверх
GremlinProg
Дата 9.10.2006, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

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



Это-то понятно, но в любом случае, на каждую команду записи нужно дождаться отклика. Это можно сделать 2-мя способами:

1.  Использовать события. Создай 2 события с помощью функций CreateEvent, допустим hReadCommand и hAbort. В потоке чтения, после того как отклик получен, поднимаешь событие hReadCommand, на которое реагирует поток записи, он проверяет флаг fStopped и если флаг опущен, то посылает очередной запорс в железку. В конце программы поднимай событие hAbort, на которое реагируют оба потока, они по этому событию будут выходить из цикла, тем самым, савершая потоки. После того, как в основной программе поднимаешь событие hAbort, жди оба потока с помощью функции WaitForMultiplyObjects. Можно завести 3-тье событие hWriteCommand, вместо флага fStopped, которое поднимается при нажатии кнопки "Пролдолжить" и "Старт". На это событие будет реагировать поток записи, оно будет сигнализировать, чтобы начать цикл посылки команд в железо.

2. Использовать сообщения. То же самое, но только заводишь не события а дополнительные сообщения(либо с помощью RegisterWindowMessage, либо просто WM_USER + 500), которые обрабатываешь в основном окне, а вместо сигнализации посылаешь из потока чтения SendMessage самому себе, либо крутишь PostMessage. В этом случае достаточно и 1 потока.

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

ЗЫ: мусор в буфере как раз и обуславливается бесконечной посылкой в железо команд: в то время, как первая команда начинает ложится в буфер, приходит вторая, в буфере собирается кусок первой и кусок второй и т.д., в конечном счете ни одну команду толком разобрать не можешь, поэтому и ставишь искусственно задержку слипом, не хорошо.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Gremlin
Дата 19.10.2006, 07:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



"В конце программы поднимай событие hAbort, на которое реагируют оба потока, они по этому событию будут выходить из цикла, тем самым, савершая потоки. "
Не понял как это реализовать тоесть потоки должны робить и одновременно ожидать этого события! Следовательно по аналогии с hReadCommand WaitForSingleObject(hAbort, 2000) использовать нельзя дак как мне в любом месте выполнения потока отловить это сообщение и закрыть потоки/циклы?


Это сообщение отредактировал(а) Gremlin - 29.10.2006, 10:04
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.

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


 




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


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

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