Данные с com порта

 
0
 
C++
ava
Alexey68 | 06.11.2016, 19:37
Здравствуйте 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.
Прошу Вашей помощи.
Kommentare (8)
ava
mega | 07.11.2016, 10:38 #
скорее всего, это происходит из-за "дополнения до единицы"
можно проверить:

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

так ни чего лишнего не выводит?
ava
Alexey68 | 08.11.2016, 13:45 #
GremlinProg, Да, всё в порядке.
Благодарю.
ava
feodorv | 08.11.2016, 18:25 #
Если Вы планируете использовать функцию strlen (вместо простой и внятной передачи длины сообщения в качестве параметра функции Write_Com_3), то Вы обязаны завершить передаваемый этой функции буфер символом '\0' (и это ещё не говоря о возможности встретить нулевой символ в актуальных данных буфера). Ни command1, ни command2 не завершены нулём. Код не правилен.


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


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


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

//длина массива 1 (неправильно)

Вот совершенно не понятна длина массива. Ничто не предвещает единицы  


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

char command2[] = {0x88, 0x11, 0x34, 0x0c, 0x28, 0x08};
Write_Com_3(command2);//длина массива 1 (неправильно)
ava
xvr | 10.11.2016, 18:11 #
Цитата (Alexey68 @  9.11.2016,  18:50 findReferencedText)
почему не понятно, 6 байт: 

Это вам понятно, а функции strlen - непонятно. Она ищет в поданном массиве 0, где нашла, там и конец строки. В вашем массиве никаких 0 нет, так что где именно она его найдет (где то в памяти после массива) - неизвестно
ava
Alexey68 | 10.11.2016, 21:47 #
если я добавлю 0, то принимающая сторона не поймёт команду (пробовал) Write_Com_3(command2+'\0');
ava
feodorv | 10.11.2016, 22:56 #
Цитата (Alexey68 @  10.11.2016,  21:47 findReferencedText)
если я добавлю 0, то принимающая сторона не поймёт команду (пробовал)

Мы говорим о разных нулях. Я и xvr - о нуле, завершающим строчку:
Цитата (Alexey68 @  9.11.2016,  18:50 findReferencedText)
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);
}
Чем это плохо?
ava
xvr | 11.11.2016, 11:41 #
Цитата (Alexey68 @  10.11.2016,  21:47 findReferencedText)
(пробовал) Write_Com_3(command2+'\0'); 

Если вы думете, что эта конструкция добавит ноль в конец вашей строки, то вы сильно ошибаетесь. Смотрите арифметику указателей в языке С
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
  mega   xvr ava  feodorv   Alexey68
advanced
Absenden