Qt и СОМ-порт
Пишу программу работы с тепловычислителем на qt, обмен идёт по СОМ-порту, использую функцию CreateFileA для конфигурирования порта и ReadFile, WriteFile для чтения и записи в порт. Программа работает нормально только на компе с установленным qt, если её копировать на какой-нить другой комп, на котором qt не установлен, при обмене с тепловычислителем не могу получить пакет длинной больше 10-ти байт, пакет просто обрезается и CRC не сходится. Есть конечно готовые классы по работе с СОМ-портом, но они используют те же функции для обмена. Кто-нить сталкивался с таким?
P.S. используется Qt Creator 1.2.1 основан на Qt 4.5.2 (32-х битной)
Не думаю что проблема в Qt кода больше покажите.
HANDLE open_and_configure(char *port, int baudrate)
{
COMMCONFIG comm_config;
COMMTIMEOUTS comm_timeouts;
DWORD comm_cfg_size = sizeof(COMMCONFIG);
comm_config.dwSize = comm_cfg_size;
HANDLE fd = CreateFileA(
port,
GENERIC_READ | GENERIC_WRITE,//будем читать и писать в порт
0,
// FILE_WRITE_DATA|FILE_READ_DATA,
// FILE_SHARE_READ|FILE_SHARE_WRITE,//можно совместно читать и писать в порт
NULL , // default security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0,/*FILE_ATTRIBUTE_NORMAL,*///FILE_FLAG_OVERLAPPED, //0, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR);
// configure port settings
GetCommConfig(fd, &comm_config, &comm_cfg_size);
GetCommState(fd, &(comm_config.dcb));
// set baudrate
switch (baudrate)
{
case 9600: comm_config.dcb.BaudRate = CBR_9600;
break;
case 115200: comm_config.dcb.BaudRate = CBR_115200;
break;
}
// flow control off
comm_config.dcb.fOutxCtsFlow = FALSE;
comm_config.dcb.fDtrControl = DTR_CONTROL_ENABLE;
comm_config.dcb.fRtsControl = RTS_CONTROL_ENABLE;//RTS_CONTROL_TOGGLE
comm_config.dcb.fInX = FALSE;
comm_config.dcb.fOutX = FALSE;
// Binary, 8N2
comm_config.dcb.fBinary = TRUE;
comm_config.dcb.fAbortOnError = FALSE;
comm_config.dcb.fNull = FALSE;
comm_config.dcb.ByteSize = 8;
comm_config.dcb.fParity = NOPARITY;
comm_config.dcb.StopBits = 2;
// Set the new options...
SetCommConfig(fd, &comm_config, sizeof(COMMCONFIG));
// timeout, msec
comm_timeouts.ReadIntervalTimeout = 3;//3
comm_timeouts.ReadTotalTimeoutMultiplier = 5;//5
comm_timeouts.ReadTotalTimeoutConstant = 15;//15
comm_timeouts.WriteTotalTimeoutMultiplier = 5;
comm_timeouts.WriteTotalTimeoutConstant = 15;
SetCommTimeouts(fd, &comm_timeouts);
return fd;
}
//функция получения номера эльфа
int get_num_elf(quint8 &addrElf, HANDLE hComm, quint32 *addr_data)
{
//разного рода настройки
for (char count2=0;count2<3;count2++)
{
WriteFile(hComm,&header[0],sizeof(header),&bc,NULL); //посылаем заголовок (7байт)
ReadFile(hComm,&array_in[0],69,&bc,NULL); //принимаем подтверждение (1байт)
if (bc == 0) return -2;//нет ответа от прибора
//если приняли в ответ адрес прибора или широковещательный адрес
if ((bc == 1) && ((array_in[0] == addrElf) || (array_in[0] == 0)|| (array_in[0] == 0xfe)))
{
flag=1;
//если принято подтверждение, то отправляем идентификатор запроса номера
WriteFile(hComm,&idn_number_device[0],sizeof(idn_number_device),&bc,NULL); //(7байт)
ReadFile(hComm,&array_in[0],69,&bc,NULL); //принимаем подтверждение( 1байт)
}else return -3;//ошибка приёма-передачи
if (flag == 1) break;
}
//если приняли в ответ адрес прибора или широковещательный адрес
if ((bc == 1) && ((array_in[0] == addrElf) || (array_in[0] == 0)|| (array_in[0] == 0xfe)))
{
//если подтверждение принято, отправляем байт окончания передачи
WriteFile(hComm,&stop_transfer,1,&bc,NULL);//1 байт
ReadFile(hComm,&array_in[0],69,&bc,NULL); //принимаем пакет-идентификатор (больше 10 байт)
}
//далее идёт расчёт CRC и обработка данных если они верные
}
Код:
char * p=&array_in[0];
int toread=69;//размер пакета который нужно получить
while(toread>0)
{
ReadFile(hComm,p,toread,&bc,NULL);
p+=bc;
toread-=bc;
}
int toread=69;//размер пакета который нужно получить
while(toread>0)
{
ReadFile(hComm,p,toread,&bc,NULL);
p+=bc;
toread-=bc;
}
Можно, конечно, попробовать поставить что нить такое:
ReadFile(hCom,&inArray[0],69,&bc,NULL);
if (bc < 10) ReadFile(hCom,&inArray[bc],69-bc,&bc,NULL);
Между WriteFile и ReadFile sleep(500) попробуйте поставьте, и проверьте.
Как и ожидалось, в результате 2-ого чтения получил в 2 раза больше байтов. В общем направление мысли и работы ясно, спасибо.