Я добавляю подчиненную связь MODBUS RTU через RS-485 (через чип ADM2587EBRWZ) в существующую программу SAMD21. Реализованы только команды чтения регистра хранения и записи одного регистра, поскольку мне больше не нужно.
Для проверки я использую ПЛК от Microcom в качестве ведущего. Я позволил ему работать несколько часов, но журналы показывают некоторые значения -3333 (Microcom использует -3333, чтобы показать, что произошла ошибка при чтении этого регистра). Проверяя терминал plc, я заметил, что если ответное сообщение заканчивается на 00 00 CRC_lo 00, следующий запрос является ошибкой. При отладке в Atmelstudio ATSAMD21 считывает тот же ответ и определяет его как запрос, выдавая ПЛК ответ с недопустимым адресом данных.
После ответа я делаю usart_reset на порту и очищаю массив сообщений, есть идеи, что это может быть?
2 примечания: я совсем новичок в программировании на C, и английский не мой первый язык.
Изменить: добавлено больше кода, если нужно что-то еще, я могу опубликовать его. Эта часть находится в основном цикле:
while(ReceivedCommand_MODBUS() ==false)
{
UartReadJob_MODBUS();
}
AnalyzeReceiveCommand_MODBUS();
Первая функция:
bool ReceivedCommand_MODBUS()
{
uint16_t CRC=0;
CRC = CRC16(CommandReadBuffer_MODBUS,6);
if ((CommandReadBuffer_MODBUS[CommandReadLength-1] == ((CRC & 0xFF00)>>8)) && (CommandReadBuffer_MODBUS[CommandReadLength-2]) == (CRC & 0x00FF) )
{
return true;
}
if ((CommandReadLength - 1 )>= RS485_COMMAND_LENGTH)
{
CommandReadLength = 0;
memset(CommandReadBuffer_MODBUS, 0, sizeof(CommandReadBuffer_MODBUS));
}
return false;
}
И последний:
void AnalyzeReceiveCommand_MODBUS()
{
uint32_t receiveLength = 0;
uint8_t receiveCommand[COMMAND_READ_BUFFER_LENGTH_MODBUS];
memset(receiveCommand, 0, COMMAND_READ_BUFFER_LENGTH_MODBUS);
ReadCommand_MODBUS(receiveCommand, &receiveLength);
uint16_t CRC = 0;
//Modbus request is read and response generated here
SendMaster_MODBUS(messageData,MessageSize);
delay_ms(10); //delays are for breakpoints
UartReset(&UART1);
for (char i=0;i<=MessageSize+1;i++)
{
UartReceiveBuffer_MODBUS[i]=0;
UartSendBuffer_MODBUS[i]=0;
messageData[i]=0;
}
void ResetBuffer_MODBUS ();
delay_ms(10);
}
Функция ReadCommand_MODBUS:
void ReadCommand_MODBUS(uint8_t* command, uint32_t* length)
{
*length = CommandReadLength;
memcpy(command, CommandReadBuffer_MODBUS, CommandReadLength);
CommandReadLength = 0;
memset(CommandReadBuffer_MODBUS, 0, sizeof(CommandReadBuffer_MODBUS));
}