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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Данные с com порта, Данные с com порта 
:(
    Опции темы
Alexey68
Дата 6.11.2016, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Alexey
*


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

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



Здравствуйте All!
При чтении с ком порта к байту впереди добавляются "лишние" байты FFFFFF, из-за чего это происходит?
Код

#include <stdio.h>
#include <windows.h>


HANDLE hComm;
bool Status;


void main()
{
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(hComm, &dcbSerialParams);



dcbSerialParams.BaudRate = CBR_9600;  // Setting BaudRate = 9600
dcbSerialParams.ByteSize = 8;         // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
dcbSerialParams.Parity   = NOPARITY;  // Setting Parity = None

SetCommState(hComm, &dcbSerialParams);


COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout         = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant    = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier  = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant   = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds




  hComm = CreateFile("\\\\.\\COM4",                //port name
                      GENERIC_READ | GENERIC_WRITE, //Read/Write
                      0,                            // No Sharing
                      NULL,                         // No Security
                      OPEN_EXISTING,// Open existing port only
                      0,            // Non Overlapped I/O
                      NULL);        // Null for Comm Devices

  if (hComm == INVALID_HANDLE_VALUE)
      printf("Error in opening serial port\n");

  else
      printf("opening serial port successful\n");
  char lpBuffer[] = {0xAA,0x23,0x43,0x27,0x86,0x55};
  DWORD dNoOFBytestoWrite;         // No of bytes to write into the port
  DWORD dNoOfBytesWritten = 0;     // No of bytes written to the port
  dNoOFBytestoWrite = sizeof(lpBuffer);

  Status = WriteFile(hComm,        // Handle to the Serial port
                   lpBuffer,     // Data to be written to the port
                   dNoOFBytestoWrite,  //No of bytes to write
                   &dNoOfBytesWritten, //Bytes written
                   NULL);


Status = SetCommMask(hComm, EV_RXCHAR);
DWORD dwEventMask; 
Status = WaitCommEvent(hComm, &dwEventMask, NULL);

char TempChar; //Temporary character used for reading
char SerialBuffer[256];//Buffer for storing Rxed Data
DWORD NoBytesRead;
int i = 0;

do
 {
   ReadFile( hComm,           //Handle of the Serial port
             &TempChar,       //Temporary character
             sizeof(TempChar),//Size of TempChar
             &NoBytesRead,    //Number of bytes read
             NULL);

   SerialBuffer[i] = TempChar;// Store Tempchar into buffer
printf("%02x", SerialBuffer[i]);// здесь выводит на консоль то что описал выше
system("pause");
   i++;
  }

while (NoBytesRead > 0);
CloseHandle(hComm);//Closing the Serial Port
system("pause");
}

Пример ответа:
90
FFFFFF43
76
FFFFFF32
88
FFFFFF29

Причём ответ с порта правильный, если бы не добавляемые FFFFFF.
Прошу Вашей помощи.

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


Эксперт
****


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

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



скорее всего, это происходит из-за "дополнения до единицы"
можно проверить:
Код

printf("%02x", (unsigned int)(unsigned char)SerialBuffer[i]);

так ни чего лишнего не выводит?


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


Alexey
*


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

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



GremlinProg, Да, всё в порядке.
Благодарю, у меня ещё вопрос:
Правилен ли следующий код:
Код

void Write_Com_3(char WriteData[])
{
DWORD dNoOfBytesWritten = 0;
DWORD dNoOFBytestoWrite = 0;

  dNoOFBytestoWrite = strlen(WriteData);
  printf("Size bytes = %d\n", dNoOFBytestoWrite);

  Status = WriteFile(hSerial,        // Handle to the Serial port
                   WriteData,     // Data to be written to the port
                   dNoOFBytestoWrite,  //No of bytes to write
                   &dNoOfBytesWritten, //Bytes written
                   NULL);

memset(WriteData, 0, strlen(WriteData));                   
}

при передаче массива байт например:
Код

char command1[] = {0x56, 0x80, 0x01, 0x11, 0x34, 0x11, 0x98};
Write_Com_3(command1);//длина массива 7 (правильно)

char command2[] = {0x88, 0x11, 0x34, 0x0c, 0x28, 0x08};
Write_Com_3(command2);//длина массива 1 (неправильно)






Это сообщение отредактировал(а) Alexey68 - 8.11.2016, 13:58
PM MAIL   Вверх
feodorv
Дата 8.11.2016, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Если Вы планируете использовать функцию strlen (вместо простой и внятной передачи длины сообщения в качестве параметра функции Write_Com_3), то Вы обязаны завершить передаваемый этой функции буфер символом '\0' (и это ещё не говоря о возможности встретить нулевой символ в актуальных данных буфера). Ни command1, ни command2 не завершены нулём. Код не правилен.


Цитата(Alexey68 @  8.11.2016,  13:45 Найти цитируемый пост)
//длина массива 1 (неправильно)
Вот совершенно не понятна длина массива. Ничто не предвещает единицы smile 


Цитата(Alexey68 @  8.11.2016,  13:45 Найти цитируемый пост)
memset(WriteData, 0, strlen(WriteData));
Зачем второй strlen, если есть результат первого, да ещё и сохраненный в переменную?


Цитата(Alexey68 @  8.11.2016,  13:45 Найти цитируемый пост)
DWORD dNoOFBytestoWrite = 0;
Почему результат выполнения WriteFile, содержащийся в этой переменной, не проверен? Возможна же неполная передача данных буфера.



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
Alexey68
Дата 9.11.2016, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Alexey
*


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

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



Цитата(feodorv @  8.11.2016,  18:25 Найти цитируемый пост)
Цитата(Alexey68 @  8.11.2016,  13:45 )
//длина массива 1 (неправильно)
Вот совершенно не понятна длина массива. Ничто не предвещает единицы  

почему не понятно, 6 байт: 
Код

char command2[] = {0x88, 0x11, 0x34, 0x0c, 0x28, 0x08};
Write_Com_3(command2);//длина массива 1 (неправильно)

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


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alexey68 @  9.11.2016,  18:50 Найти цитируемый пост)
почему не понятно, 6 байт: 

Это вам понятно, а функции strlen - непонятно. Она ищет в поданном массиве 0, где нашла, там и конец строки. В вашем массиве никаких 0 нет, так что где именно она его найдет (где то в памяти после массива) - неизвестно

PM MAIL   Вверх
Alexey68
Дата 10.11.2016, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Alexey
*


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

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



если я добавлю 0, то принимающая сторона не поймёт команду (пробовал) Write_Com_3(command2+'\0');
PM MAIL   Вверх
feodorv
Дата 10.11.2016, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alexey68 @  10.11.2016,  21:47 Найти цитируемый пост)
если я добавлю 0, то принимающая сторона не поймёт команду (пробовал)

Мы говорим о разных нулях. Я и xvr - о нуле, завершающим строчку:
Цитата(Alexey68 @  9.11.2016,  18:50 Найти цитируемый пост)
char command2[] = {0x88, 0x11, 0x34, 0x0c, 0x28, 0x08,0x0};
Тогда strlen(command2) вернет 6 (Вы ведь этого хотите, я никак не могу понять, или не этого?) И завершающий строчу ноль не будет передан по сети в качестве данных, портя команду. Но загадкой для меня остаётся использование strlen вообще, и для бинарных данных в частности. Так почему не так:
Код
void Write_Com_3(char WriteData[], int dNoOFBytestoWrite)
{
DWORD dNoOfBytesWritten = 0;
  Status = WriteFile(hSerial,        // Handle to the Serial port
                   WriteData,     // Data to be written to the port
                   dNoOFBytestoWrite,  //No of bytes to write
                   &dNoOfBytesWritten, //Bytes written
                   NULL);
memset(WriteData, 0, dNoOFBytestoWrite);
}
Чем это плохо?



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
xvr
Дата 11.11.2016, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Alexey68 @  10.11.2016,  21:47 Найти цитируемый пост)
(пробовал) Write_Com_3(command2+'\0'); 

Если вы думете, что эта конструкция добавит ноль в конец вашей строки, то вы сильно ошибаетесь. Смотрите арифметику указателей в языке С

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.1502 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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