Почему samd21 читает собственный ответ Modbus как главный запрос?

Я добавляю подчиненную связь 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));
}

person Mick-NKE    schedule 16.07.2020    source источник
comment
Не могли бы вы предоставить код о том, что вы уже пробовали?   -  person cjb110    schedule 16.07.2020
comment
Теперь я проверяю ожидающее сообщение и, если оно имеет такой шаблон, вместо этого меняю его на высокий положительный (чтобы отличить любой другой сбой, представленный как -3333), но это не решение. Я вставил некоторый код в OP, извините, но это также мой первый раз на SO (я читал его несколько раз, но это мой первый пост)   -  person Mick-NKE    schedule 16.07.2020
comment
Добавил некоторый код, надеюсь, это поможет понять проблему. Если кто-то увидит что-то странное не только в ошибке, вы можете сказать мне.   -  person Mick-NKE    schedule 20.07.2020


Ответы (1)


Теперь это работает, вызывая это после отправки ответного сообщения:

void ResetBuffer_MODBUS ()
{
    memset(CommandReadBuffer_MODBUS, 0, sizeof(CommandReadBuffer_MODBUS));
}

Пока нет ошибок, он будет работать какое-то время, но раньше он уже выдал бы пару ошибок.

person Mick-NKE    schedule 21.07.2020