реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> RS232 и передача 0, не получаеться передать 0
kolisnichenko_r
сообщение Jul 12 2010, 12:16
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Здравствуйте!
Использую для работы с СОМ портом потоки 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);               //активировать поток записи данных в порт
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jul 12 2010, 12:21
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Jul 12 2010, 13:16
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Цитата(MrYuran @ Jul 12 2010, 15:21) *
Попробуйте поиграться с флажком 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). Заменил эту функцию явным количеством символов посылки, все заработало.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jul 12 2010, 19:06
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



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

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

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

Сообщение отредактировал Genadi Zawidowski - Jul 12 2010, 19:09
Go to the top of the page
 
+Quote Post
Xenia
сообщение Jul 12 2010, 21:27
Сообщение #5


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Всё гораздо проще. Стринги в языке 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]);
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jul 12 2010, 21:36
Сообщение #6


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Xenia @ Jul 13 2010, 03:27) *
конструкция:
WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr);
так же оказывается завязана на функцию strlen(), поскольку именно она вычисляет число передаваемых байт. Отсюда и ваша ошибка.

Эко вы всё здорово объяснили. Только вот кому? Автор темы в конце цитируемого вами сообщения пишет:
Цитата(kolisnichenko_r @ Jul 12 2010, 19:16) *
А в ней для определения длины посылки используеться функция strlen(bufwr). Заменил эту функцию явным количеством символов посылки, все заработало.

smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
kolisnichenko_r
сообщение Jul 13 2010, 07:52
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482



Че-то затормозил, жара достала.
Спасибо всем!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 03:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.0519 секунд с 7
ELECTRONIX ©2004-2016