Насколько я понимаю, соответствие RS-485 будет обеспечено терминалом при передаче (если порт правильно настроен), а соответствие стандарту Modbus и правильность ответа проверяет уже скрипт.
Вот новая функция, проверить по-прежнему нет возможности
Код:
const BYTES_PER_REG = 2;
const N_RETRIES = 3;
const RETRY_TIMEOUT = 1000; //ms
BOOL MWrites(int comID, int staID, int objType, int add1, int regs, void* pRegs) {
BYTE bSend[256], bRecieve[256], i;
WORD bBytesToSend = 0, bBytesRecieved = 65535;
BYTE nRetry = N_RETRIES; //Количество попыток повтора
BYTE offset_PSW_log;
int CrcSum;
switch (comID) {
case DOWNLOAD:
offset_PSW_log = 60;
break;
case PLC:
offset_PSW_log = 70;
break;
default:
return Writes(comID, staID, objType, add1, regs, pRegs); //don't know what to do
}
bSend[0] = staID;
switch (objType) {
case MODBUS_RTU_REGS_4X:
bSend[1] = 0x10;
break;
default:
return Writes(comID, staID, objType, add1, regs, pRegs); //don't know what to do
}
bSend[2] = HIBYTE(add1);
bSend[3] = LOBYTE(add1);
bSend[4] = HIBYTE(regs);
bSend[5] = LOBYTE(regs);
bSend[6] = regs * BYTES_PER_REG;
bBytesToSend = 7;
for (i=0; i<regs*2; i++) {
bSend[bBytesToSend] = ((BYTE*)pRegs)[i];
bBytesToSend++;
}
CrcSum = Crc(bSend, bBytesToSend);
bSend[bBytesToSend] = LOBYTE(CrcSum);
bSend[bBytesToSend + 1] = HIBYTE(CrcSum);
bBytesToSend += 2;
if (bBytesToSend > 256)
return FALSE;
Enter(comID);//Захватить порт PLC
do {
if (bBytesRecieved != 65535) { //Была ошибка связи
PSW[offset_PSW_log+1]++;
if (bBytesRecieved != 0) // Ошибка данных
PSW[offset_PSW_log+3]++;
//else //Таймаут
// PSW[offset_PSW_log+2]++;
}
Send(comID, bSend, bBytesToSend);//Отправить команду
bBytesRecieved = Receive(comID, bRecieve, 256, RETRY_TIMEOUT, 6);//Получить ответ (тайм-аут 1000мс)
} while ((bBytesRecieved == 0 || //Если данные получены
bRecieve[0] != staID || //От правильного устройства
bRecieve[1] != bSend[1] || //Правильной функцией
MAKEWORD(bRecieve[3], bRecieve[2]) != add1 || // По правильному адресу
MAKEWORD(bRecieve[5], bRecieve[4]) != regs || // Правильное количество регистров
Crc(bRecieve, bBytesRecieved) != 0 //Контрольная сумма в порядке
) && (nRetry--)>0); //... то всё ок, иначе отнимаем попытку и, если они остались, пытаемся ещё
Leave(comID);//Освободить порт
if (nRetry>0) { //Если попытки остались, значит, последняя попытка связи была успешной
PSW[offset_PSW_log]++;
return TRUE;
} else
return FALSE;
}