Перейти к содержанию
    

RS232 и передача 0

Здравствуйте!

Использую для работы с СОМ портом потоки WINAPI и функции ResumeThread(), SuspendThread(). За основу взята программа с сайта http://www.piclist.ru/S-COM-THREAD-RUS/S-COM-THREAD-RUS.html. Разные значения отсылаются, но если есть где-то в посылке нолевое значение - отправка прерывается. Как можно передать 0? Дайте совет, пожалуйста.

Код передачи:

//peredacha - 10 byte
   memset(bufwr,0,BUFSIZE);            //очистить программный передающий буфер, чтобы данные не накладывались друг на друга
   PurgeComm(COMport, PURGE_TXCLEAR);           //очистить передающий буфер порта
   for(unsigned char icd=0;icd<10;icd++){bufwr[icd]=comand[icd];}
   ResumeThread(writer);               //активировать поток записи данных в порт

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте поиграться с флажком fnull структуры DCB

Помнится, были с ним проблемы, правда, при приёме

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте поиграться с флажком fnull структуры DCB

Помнится, были с ним проблемы, правда, при приёме

Разрешение на прием 0 есть:

dcb.fNull = FALSE;//разрешить приём нулевых байтов

Может где-то тут покопаться:

reader = CreateThread(NULL, 0, ReadThread, NULL, 0, NULL);//создаём поток чтения, который сразу начнёт выполняться (предпоследний параметр = 0)
writer = CreateThread(NULL, 0, WriteThread, NULL, CREATE_SUSPENDED, NULL);//создаём поток записи в остановленном состоянии (предпоследний параметр = CREATE_SUSPENDED)

 

Нашел:

//главная функция потока, выполняет передачу байтов из буфера в COM-порт
DWORD WINAPI WriteThread(LPVOID)
{DWORD temp, signal;    //temp - переменная-заглушка
overlappedwr.hEvent = CreateEvent(NULL, true, true, NULL);         //создать событие
while(1)
  {WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);  //записать байты в порт (перекрываемая операция!)
    signal = WaitForSingleObject(overlappedwr.hEvent, INFINITE);      //приостановить поток, пока не завершится перекрываемая операция WriteFile
   if((signal == WAIT_OBJECT_0) && (GetOverlappedResult(COMport, &overlappedwr, &temp, true)))    //если операция завершилась успешно
     {
      Form1->StatusBar1->Panels->Items[0]->Text  = "Передача прошла успешно";    //вывести сообщение об этом в строке состояния
     }
   else {Form1->StatusBar1->Panels->Items[0]->Text  = "Ошибка передачи";}     //иначе вывести в строке состояния сообщение об ошибке
   SuspendThread(writer);
  }
}

В этой функции используеться функция

WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);  //записать байты в порт (перекрываемая операция!)

А в ней для определения длины посылки используеться функция strlen(bufwr). Заменил эту функцию явным количеством символов посылки, все заработало.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Запретите формирование ошибки по приёму frame error. Иначе, пока не считаете состояние ошибок (сбравсываются они при этом) все операции ввода-вывода на ком-порте завершаются с ошибкой.

 

За образец пока не поздно предлагаю взять программу из аттачмента.

 

зы: только сейчас заметил что проблема не в передаче нуля как символа с нулём в стоп-бите... но в исходники копните.

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё гораздо проще. Стринги в языке C по определению заканчиваются нулем, который сам за символ не считается (нуль-терминированная строка). Отсюда следует очевидное следствие - строка символов не может содержать нуля, а буде такой в строку ставлен, то это привело бы лишь к тому, что строка стала бы короче, будучи обрезанной по первому же встреченному нулю.

 

То же касается функции strlen(), определяющей длину стринга. Она возвращает не число сиволов, которые вы туда понатыкали, а число ненулевых символов, начиная с нуля. Поэтому конструкция:

WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);

так же оказывается завязана на функцию strlen(), поскольку именно она вычисляет число передаваемых байт. Отсюда и ваша ошибка.

Исправлять положение следует явным указанием числа передаваемых байт. Элегантным способом реализации которого может быть вариант создания специальной функции, помещающей байт в буфер, вместо механического копирования. Такая функция добавляла бы байт, одновременно инкрементируя счетчик. Этот же счетчик впоследствии использовался бы при сбросе буфера на вывод, после которого счетчик обнулялся.

Например так:

 

// глобальные переменные:
char bufwr[1024];
int counter = 0; 

void PushBuffer( char symbol)
{
  bufwr[counter++] = symbol;
}

При желании эту функцию можно объявить inline, тем самым превратив ее в прямую подстановку. А обнуление counter вставить в WriteThread() после успешного завершения передачи. А саму передачу производить так:

WriteFile(COMport, bufwr, counter, &temp, &overlappedwr);

 

Соответственно этому, пихать байты в буфер следует не так:

for(unsigned char icd=0;icd<10;icd++){bufwr[icd]=comand[icd];

а вот так:

for(unsigned char icd=0;icd<10;icd++) PushBuffer(comand[icd]);

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

конструкция:

WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);

так же оказывается завязана на функцию strlen(), поскольку именно она вычисляет число передаваемых байт. Отсюда и ваша ошибка.

Эко вы всё здорово объяснили. Только вот кому? Автор темы в конце цитируемого вами сообщения пишет:

А в ней для определения длины посылки используеться функция strlen(bufwr). Заменил эту функцию явным количеством символов посылки, все заработало.

:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...