Доброго всем времени суток! Очень прошу откликнуться lamerokа!!! И всех соображающих в этой области тоже прошу помочь!
Пожалуйста помогите кто работал с HART модемом.
Мне необходимо прочитать с датчика давления ABB Kent-Teylor серийный номер. Воспользовался кодом lamerokа. Ответ от датчика есть, только если посылаем фрейм с командой 0. Приходят данные в виде цифр:254,255,255...8,5,2.... (на посланные мной 11 байт приходит 27байт), как преобразовать в нормальный вид (допустим в цифры серийного номера или значение переменной)???.Если посылаю другие команды(1 или 0х01,2 или 0х02 и т.д.),то ответа нет.В чем дело??? Может я не правильно пишу код команды? Программу пишу на С++ Builder6.
Привожу код:
HANDLE hCom;
DCB dcb={0};
COMSTAT comStat;
COMMTIMEOUTS ct;
DWORD dwWrite, dwFactWrite, dwWait, dwRead=0, dwErr, dwNumB, dwRMask=EV_TXEMPTY;
OVERLAPPED Sync={0};
String strPC="PC: ", strABB="ABB: ";
//**************код lamerokа********************************************************
BYTE sbuf[100] = {0};
int max_send = 0;
BYTE devN = 0;
BYTE rbuf[100] = {0};
BYTE CalculateCRC(BYTE* buff, int buff_len)
{
BYTE crc = 0;
for (int i=0; i<buff_len; i++)
crc ^= buff;
return crc;
}
void FillShortFrame(int preamble_size, BYTE dest, BYTE cmd, BYTE* data, BYTE data_len, BYTE* sbuf, int& nSend)
{
// преамбула
for (int i=0; i<preamble_size; i++) sbuf = 0xFF;
sbuf[preamble_size] = 0x02; // короткий кадр, master-to-slave
BYTE addr = 0x80;
addr |= (dest & 0x80);
sbuf[preamble_size+1] = addr;
sbuf[preamble_size+2] = cmd;
sbuf[preamble_size+3] = data_len;
memcpy(sbuf+preamble_size+4, data, data_len);
BYTE crc = CalculateCRC(sbuf+preamble_size, data_len+4);
sbuf[preamble_size+4+data_len] = crc;
nSend = data_len + 5 + preamble_size;
}
//**************************************************************************************
//***********Кнопка открытия порта***********************************************
void __fastcall TForm1::bOpenPortClick(TObject *Sender)
{
hCom=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if (hCom==INVALID_HANDLE_VALUE)
{MessageDlg("Ошибка открытия порта",mtError,TMsgDlgButtons()<<mbOK,0);
return;}
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = CBR_1200;
dcb.Parity = ODDPARITY;
dcb.fBinary = 1;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_TOGGLE;
ct.ReadIntervalTimeout = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.ReadTotalTimeoutConstant = 1000;
ct.WriteTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 1000;
SetCommState(hCom,&dcb))
SetCommMask(hCom, EV_TXEMPTY))
EscapeCommFunction(hCom,SETDTR))
SetCommTimeouts(hCom,&ct))
}
//***********Кнопка записи и чтения сообщения*******************************
void __fastcall TForm1::bSendToPortClick(TObject *Sender)
{
//*****************************WRITING THE DATA*****************************
// Очищаем буферы приема/передачи
PurgeComm(hCom, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR)
Sync.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
/////////////////////////////////////////////////////////////////////////////
BYTE cmd = 0;//!!! вот здесь меняю команду и в ответ ничего не приходит !!!
FillShortFrame(6, devN, cmd, NULL,0 , sbuf, max_send);
/////////////////////////////////////////////////////////////////////////////
WriteFile(hCom,sbuf,max_send,&dwFactWrite,&Sync)
CloseHandle(Sync.hEvent);
//*****************************READING THE DATA*****************************
Sync.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
if (!WaitCommEvent(hCom,&dwRMask,&Sync))
{
if (GetLastError()==ERROR_IO_PENDING)
{
dwWait=WaitForSingleObject(Sync.hEvent, TIMEOUT);
switch(dwWait)
{
case WAIT_OBJECT_0:
dwNumB=comStat.cbInQue;// количество байтов в приемном буфере
if(ReadFile(hCom,rbuf,dwNumB,&dwRead,&Sync))
{
//*****В процессе выполнения программа попадает сюда*******//
Memo1->Lines->Add(strABB + rbuf[0]); // сюда вывожу
Memo1->Lines->Add(strABB + rbuf[18]);// часть полученной
Memo1->Lines->Add(strABB + rbuf[19]);// информации
CloseHandle(Sync.hEvent);
return;
}
case WAIT_TIMEOUT:
Memo1->Lines->Add("TimeOut...");
CloseHandle(Sync.hEvent);
return;
default:
MessageDlg("Ошибка выполнения операции WaitForSingleObject (RF)",mtError,TMsgDlgButtons()<<mbOK,0);
CloseHandle(Sync.hEvent);
return;
}
}
else
{MessageDlg("Ошибка в WaitCommEvent",mtError,TMsgDlgButtons()<<mbOK,0);
CloseHandle(Sync.hEvent);
return;}
}
else
{
dwNumB=comStat.cbInQue;
if(ReadFile(hCom,rbuf,dwNumB,&dwRead,&Sync))
{
Memo1->Lines->Add(strABB + rbuf[0]);
CloseHandle(Sync.hEvent);
return;
}
}
}
Многие проверки на ошибки я убрал, чтобы код был поменьше.
С нетерпеньем жду откликов.