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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> 9-бит через COM port 
:(
    Опции темы
GreatShogun
Дата 12.8.2012, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Решил написать програмку, в которой COM port будем общаться с контроллером шаговых двигателей) ну собсно спецификация у контроллера такова что есть 9-й бит который сообщает о том адрес в 8 битах перед ним или нет! вопрос в том как это реализовать! пробывал использовать паритет, но ничего путного пока не вышло! 
PM MAIL   Вверх
GremlinProg
Дата 13.8.2012, 07:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



если доступно кодить на обеих сторонах,

чем не устраивает 8-битный трансфер на обеих сторонах: контроллер набирает 8 бит, шлет их в UART, 1 бит оставляет в буфере,
следующие 7 бит склеивает с оставшимся, посылает их и оставляет в буфере 2 бита и т.д., пока в очередь с буфером, в сумме не придет 16 бит, после чего буфер опустошается и все начинается по новой

на приемной стороне точно так же

Добавлено через 1 минуту и 34 секунды
нужно только предусмотреть команду flush, которая очищает текущий буфер, дополняя его биты нулями и посылая в UART


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


Новичок



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

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



В том то и дело что перепрограмировать контроллер нет никакой возможности) надо реализовать именно 9-ти битную) 
PM MAIL   Вверх
GremlinProg
Дата 13.8.2012, 10:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



есть реализации UART, которые понимают 9 бит, и если контроллер, использует именно такой UART, то на приемной стороне надо выставить в DCB::ByteSize значение 9, если же контроллер ничего не знает об UART и шлет импульсы в "провод" по своему усмотрению, то по моему без дополнительного преобразователя не обойтись


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


Новичок



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

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



дополнительный преобразователь?
PM MAIL   Вверх
GremlinProg
Дата 13.8.2012, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(GreatShogun @  13.8.2012,  12:41 Найти цитируемый пост)
дополнительный преобразователь?

еще один контроллер, который понимает эти 9 бит и ретранслирует их в обычные 8


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


Опытный
**


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

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



Цитата(GremlinProg @ 13.8.2012,  11:15)
Цитата(GreatShogun @  13.8.2012,  12:41 Найти цитируемый пост)
дополнительный преобразователь?

еще один контроллер, который понимает эти 9 бит и ретранслирует их в обычные 8

Ребят сума сошли что за грабли когда есть возможность на компе организовать UART 8 и 9.... Мы будем посылать 8 и преборазовывать в 9....

Настрой ки ком порта , приношу извинения за то что это на борланде и нет описаний чек боксов и т.д

Код


HANDLE HanPORT = 0;
DCB dcb;

memset(&dcb,0,sizeof(dcb));
dcb.DCBlength=sizeof(dcb);


HanPORT = CreateFile(&NamePort[1], GENERIC_READ|GENERIC_WRITE, 0, NULL,OPEN_EXISTING, 0,NULL);



    if(HanPORT!=INVALID_HANDLE_VALUE)
    { Form1->Memo1->Lines->Add("Порт открыт");}
    else
    { Form1->Memo1->Lines->Add("Порт не открылся"); return;}



    if (!GetCommState(HanPORT,&dcb))
    {Form1->Memo1->Lines->Add("Не считались настройки"); return;}else
    {Form1->Memo1->Lines->Add("считались настройки");}

    dcb.BaudRate=StrToInt(ComboBox2->Text);
    dcb.ByteSize=StrToInt(ComboBox3->Text);;
    dcb.Parity=0;//Form1->CheckBox1->Checked;
    dcb.StopBits=ONESTOPBIT;//Form1->CheckBox2->Checked;
 //   dcb.fDtrControl = DTR_CONTROL_ENABLE;
 //   dcb.fRtsControl = RTS_CONTROL_DISABLE;

    if (!SetCommState(HanPORT,&dcb))
    {Form1->Memo1->Lines->Add("Не записались настройки"); return;}else
    {Form1->Memo1->Lines->Add("записались настройки");}

  COMMTIMEOUTS  CommTimeouts;
  GetCommTimeouts(HanPORT, &CommTimeouts); //получаем структуру CommTimeouts что бы не заполнять все вручную
  CommTimeouts.ReadIntervalTimeout =MAXDWORD;  //функция ReadFile возвращает
  CommTimeouts.ReadTotalTimeoutMultiplier = 0; //немедленно все имеющиеся
  CommTimeouts.ReadTotalTimeoutConstant = 0;   //байты в приемном буфере
  CommTimeouts.WriteTotalTimeoutMultiplier = 0;//общий тайм-аут для
  CommTimeouts.WriteTotalTimeoutConstant = 0;  //операции записи не используется.
  SetCommTimeouts(HanPORT, &CommTimeouts); //записываем измененную структуру





И смотрите напрямую микроконтроллер нельзя соединить с ком портом компьютера..... Насколько помню надо max232 ставить.


PM MAIL   Вверх
GremlinProg
Дата 13.8.2012, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



успокойся, bass, преобразователь нужен только если это не UART, как я уже сказал


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


Опытный
**


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

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



Цитата(GremlinProg @ 13.8.2012,  11:32)
успокойся, bass, преобразователь нужен только если это не UART, как я уже сказал

Преобразователь сигналов с компа по документации +-12в точно не помню а микроконтроллер воспринимает +- 5в...... И потом соглосовать на какой скорости работает микроконтроллер и все его настройки..... Если схема не твоя то слоноватенько будет....

а вот сопряжение микроконтроллера.
http://my-avr.at.ua/publ/1-1-0-12 

Прочитал повнимательнее ТС. У него контроллер уже со спецификацией, пусть в студию даст ее и посмотрим нужно ли согласование, и какие настроички выставить.... 

dcb.ByteSize= 9;

Это сообщение отредактировал(а) bass - 13.8.2012, 11:59
PM MAIL   Вверх
GremlinProg
Дата 13.8.2012, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(bass @  13.8.2012,  13:55 Найти цитируемый пост)
Прочитал повнимательнее ТС.

с этого и надо было начинать
Цитата(GremlinProg @  13.8.2012,  12:37 Найти цитируемый пост)
надо выставить в DCB::ByteSize значение 9

Цитата(bass @  13.8.2012,  13:55 Найти цитируемый пост)
dcb.ByteSize= 9

читать умеем - уже хорошо,
осталось - перестать флудить smile


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


Новичок



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

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



bass, то есть достаточно просто задать размер байта для компорта равным 9? и совать туда вместо char, 9-битную переменную? 
PM MAIL   Вверх
bass
Дата 13.8.2012, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Код

WriteFile(HanPORT,&Buffer,1,&Bytes,0);

Для восми битного так.
Код

WriteFile(HanPORT,&Buffer,2,&Bytes,0);

Должно вот так заработать, только может придеться  поставить в проге однобайтовое выравнивание надо пробовать.

Асцилограф есть под рукой???

Могу ради интереса попробывать только вечерком часиков в 11.

А вот и ответ http://www.gotdotnet.ru/forums/2/83741/675592/

Это сообщение отредактировал(а) bass - 13.8.2012, 12:38
PM MAIL   Вверх
GreatShogun
Дата 13.8.2012, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну я с паритетом пробывал) ща еще покавыряю) если к 11 часам сделаю напишу тут!) а если нет то помощь мне не повредит!))

Добавлено через 3 минуты и 26 секунд
А может у меня в коде где то косяк! 

Код

bool SerialPort::CreateCOM(string name)
{
    LPCWSTR NameCom = StdStrToLpt(name);
    hCom = CreateFile(NameCom, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

    SetReadTimeout(1);
    SetWriteTimeout(1);
    SetSpeed(9600);
    SetParity(4);
    SetOtherSettings();

    SetupComm(hCom, 2000, 2000);

    PurgeComm(hCom, PURGE_RXCLEAR);

    if (hCom == INVALID_HANDLE_VALUE)
    {
        return false;
    }
    return true;
}

bool SerialPort::DestroyCOM()
{
    CloseHandle(hCom);
    return true;
}

bool SerialPort::CheckPortOpen()
{
    if (hCom == INVALID_HANDLE_VALUE)
    {
        return false;
    }
    return true;
}

void SerialPort::InitReadOverllaped()
{
    overlapped.hEvent = CreateEvent(NULL, true, true, NULL);    //создать сигнальный объект-событие для асинхронных операций
    SetCommMask(hCom, EV_RXCHAR);                            //установить маску на срабатывание по событию приёма байта в порт
}

void SerialPort::InitWriteOverllaped()
{
    overlappedwr.hEvent = CreateEvent(NULL, true, true, NULL);      //создать событие
}

void SerialPort::SetReadTimeout(int time)
{
    COMMTIMEOUTS touts;
    GetCommTimeouts(hCom, &touts);
    touts.ReadIntervalTimeout =  time * 1000;
    touts.ReadTotalTimeoutMultiplier = time * 1000;
    touts.ReadTotalTimeoutConstant = time * 1000;
    SetCommTimeouts(hCom, &touts);
}

void SerialPort::SetWriteTimeout(int time)
{
    COMMTIMEOUTS touts;
    GetCommTimeouts(hCom, &touts);
    touts.WriteTotalTimeoutMultiplier = time * 1000;
    touts.WriteTotalTimeoutConstant = time * 1000;
    SetCommTimeouts(hCom, &touts);
}

void SerialPort::SetSpeed(int speed)
{
    DCB dcb;

    bool wasChange = GetCommState(hCom, &dcb);


    if(speed == 9600)
    {
        dcb.BaudRate = CBR_9600;
    }
    else if (speed == 19200)
    {
        dcb.BaudRate = CBR_19200;
    }
    else if (speed == 38400)
    {
        dcb.BaudRate = CBR_38400;
    }
    else if (speed == 57600)
    {
        dcb.BaudRate = CBR_57600;
    }
    else if (speed == 115200)
    {
        dcb.BaudRate = CBR_115200;
    }
    else
    {
        dcb.BaudRate = CBR_9600;
    }

    if(wasChange)
    {
        wasChange = SetCommState(hCom, &dcb);
    }

}

void SerialPort::SetParity(int parity)
{
    DCB dcb;

    bool wasChange = GetCommState(hCom, &dcb);

    dcb.Parity = parity;

    if(wasChange)
    {
        wasChange = SetCommState(hCom, &dcb);
    }

}

void SerialPort::SetOtherSettings()
{
    DCB dcb;

    bool wasChange = GetCommState(hCom, &dcb);

    dcb.fBinary = FALSE;                                   //включаем двоичный режим обмена
    dcb.fParity = TRUE;                                   // разрешение контроля четности
    dcb.fOutxCtsFlow = FALSE;                              //выключаем режим слежения за сигналом CTS
    dcb.fOutxDsrFlow = FALSE;                              //выключаем режим слежения за сигналом DSR
    dcb.fDtrControl = DTR_CONTROL_DISABLE;                 //отключаем использование линии DTR
    dcb.fDsrSensitivity = FALSE;                           //отключаем восприимчивость драйвера к состоянию линии DSR
    dcb.fTXContinueOnXoff = FALSE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fErrorChar = FALSE;
    dcb.fNull = FALSE;                                     //разрешить приём нулевых байтов
    dcb.fRtsControl = RTS_CONTROL_DISABLE;                 //отключаем использование линии RTS
    dcb.fAbortOnError = FALSE;                             //отключаем остановку всех операций чтения/записи при ошибке
    dcb.ByteSize = 8;                                      //задаём 9 бит в байте
    //dcb.Parity = 0;                                        //отключаем проверку чётности
    dcb.StopBits = 0;                                      //задаём один стоп-бит


    if(wasChange)
    {
        wasChange = SetCommState(hCom, &dcb);
    }
}

void SerialPort::ParityONOFF(bool logic)
{
    DCB dcb;

    bool wasChange = GetCommState(hCom, &dcb);

    if(logic)
    {
        dcb.fParity = TRUE;
    }
    else
    {
        dcb.fParity = FALSE;
    }


    if(wasChange)
    {
        wasChange = SetCommState(hCom, &dcb);
    }
}

bool SerialPort::WriteToCOM(string mess)
{
    DWORD temp, signal;    //temp - переменная-заглушка

    char* buf = new char[mess.length()];
    memcpy(buf, mess.c_str(), mess.length());
    bool writed = WriteFile(hCom, buf, mess.length(), &temp, &overlappedwr);

    signal = WaitForSingleObject(overlappedwr.hEvent, INFINITE);      //приостановить поток, пока не завершится перекрываемая операция WriteFile
    return !writed;
}

bool SerialPort::ReadFromCOM(string & mess, int bits, int timeout)
{
    COMSTAT comstat;        //структура текущего состояния порта, в данной программе используется для определения количества принятых в порт байтов
    DWORD btr = 1, temp, mask, signal;    //переменная temp используется в качестве заглушки

    timeout *= 1000;
    Sleep(timeout);

    WaitCommEvent(hCom, &mask, &overlapped);                //ожидать события приёма байта (это и есть перекрываемая операция)
    signal = WaitForSingleObject(overlapped.hEvent, 1);    //приостановить поток до прихода байта
    if(signal == WAIT_OBJECT_0)                        //если событие прихода байта произошло
    {
        if(GetOverlappedResult(hCom, &overlapped, &temp, true)) //проверяем, успешно ли завершилась перекрываемая операция WaitCommEvent
        {
            if((mask & EV_RXCHAR)!=0)                    //если произошло именно событие прихода байта
            {
                ClearCommError(hCom, &temp, &comstat);        //нужно заполнить структуру COMSTAT
                btr = comstat.cbInQue;                           //и получить из неё количество принятых байтов

                if(btr)                                  //если действительно есть байты для чтения
                {
                    int leng = (int)btr;
                    char* buf = new char[leng];
                    string bufer = "";
                    for(int i = 0; i < leng; i++)
                    {
                        ReadFile(hCom, buf, 1, &temp, &overlapped);     //прочитать байты из порта в буфер программы
                        bufer += buf[0];
                    }
                    counter += leng;                                          //увеличиваем счётчик байтов
                    mess = string(bufer);
                    //mess = mess.substr(0, mess.length()-3);

                    if(bits < mess.length());
                    {
                        mess = mess.substr(0, bits-1);
                    }


                    return true;                          //вызываем функцию для вывода данных на экран и в файл
                }
             }
         }
     }

     return true;
}

void SerialPort::CloseReadOverllaped()
{
    CloseHandle(overlapped.hEvent);
}

void SerialPort::CloseWriteOverllaped()
{
    CloseHandle(overlappedwr.hEvent);
}

void SerialPort::PurgeCOM()
{
    PurgeComm(hCom, PURGE_RXCLEAR);
    PurgeComm(hCom, PURGE_TXCLEAR);             //очистить передающий буфер порта
}

PM MAIL   Вверх
bass
Дата 13.8.2012, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Сейчас не могу посмотреть все....

но в глаза килаеться... SerialPort::WriteToCOM(BYTE mess)

Зачем стринг??????

Если 8 бит передача то BYTE.....

Код

bool writed = WriteFile(hCom, mess, 1, &temp, &overlappedwr);

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


Новичок



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

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



лучше по одному байту слать? string для более удобного взаимодействия с интерфейсом.

Добавлено через 5 минут и 45 секунд
так то 9-бит просто я паритет пытался тут использовать) то есть девятый бит - бит четности

PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0999 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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