rsln 0 12 июля, 2010 Опубликовано 12 июля, 2010 · Жалоба Здравствуйте! Использую для работы с СОМ портом потоки 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); //активировать поток записи данных в порт Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 29 12 июля, 2010 Опубликовано 12 июля, 2010 · Жалоба Попробуйте поиграться с флажком fnull структуры DCB Помнится, были с ним проблемы, правда, при приёме Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 12 июля, 2010 Опубликовано 12 июля, 2010 · Жалоба Попробуйте поиграться с флажком 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). Заменил эту функцию явным количеством символов посылки, все заработало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 12 июля, 2010 Опубликовано 12 июля, 2010 (изменено) · Жалоба Запретите формирование ошибки по приёму frame error. Иначе, пока не считаете состояние ошибок (сбравсываются они при этом) все операции ввода-вывода на ком-порте завершаются с ошибкой. За образец пока не поздно предлагаю взять программу из аттачмента. зы: только сейчас заметил что проблема не в передаче нуля как символа с нулём в стоп-бите... но в исходники копните. Изменено 12 июля, 2010 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 12 июля, 2010 Опубликовано 12 июля, 2010 · Жалоба Всё гораздо проще. Стринги в языке 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]); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 12 июля, 2010 Опубликовано 12 июля, 2010 · Жалоба конструкция: WriteFile(COMport, bufwr, strlen(bufwr), &temp, &overlappedwr); так же оказывается завязана на функцию strlen(), поскольку именно она вычисляет число передаваемых байт. Отсюда и ваша ошибка. Эко вы всё здорово объяснили. Только вот кому? Автор темы в конце цитируемого вами сообщения пишет: А в ней для определения длины посылки используеться функция strlen(bufwr). Заменил эту функцию явным количеством символов посылки, все заработало. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rsln 0 13 июля, 2010 Опубликовано 13 июля, 2010 · Жалоба Че-то затормозил, жара достала. Спасибо всем! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться