Есть две одинаковые платки под управлением lpc1768 каждая.
Платы связаны по CAN 250кбит/с, витая пара 20 см, согласование на обоих концах.
Подпрограммы инициализации и обработки прерываний у плат одинаковые.
Каждая плата посылает другой примерно 5-7 раз в секунду по 10-20 пакетов.
Обмен идет корректно и стабильно, за исключением того, что примерно раз в 3-5
секунд фиксируются ошибки, причем они идут группами. Т.е. 3-5 секунд нет ошибок,
а потом бац и 20 ошибок выскочит.
Статистика за 10 минут например такая :
180000 пакетов принято
61000 пакетов отослано
15000 ошибок передачи
6000 ошибок приема
110 раз контроллер уходил в bus-off
Подавляющее большинство ошибок это Acknowledge Slot и End of Frame.
Я первый раз работаю с CAN, поэтому и спрашиваю: это нормально?
Если нет, то в чем причина ? Надо размазывать отсылку пакетов во времени а не
отсылать сразу группу ? Вроде бы это нелогично, прием идет по прерываниям и тактовая у микроконтроллера 96МГц,
и ничем он больше почти не занят.
Код
__irq void CAN_IRQHandler(void)
{
CanInterruptStatus = dwrCAN1ICR;
if ((CanInterruptStatus&(1<<0))!=0)
{
pInterruptRxFrame = (TCanRxTxFrame*)&(CanRxFrames[CanRxFramePtrReceived]);
pInterruptRxFrame->dwInfo = dwrCAN1RFS;
pInterruptRxFrame->dwIdentifier = dwrCAN1RID;
*(DWORD*)&(pInterruptRxFrame->bData[0]) = dwrCAN1RDA;
*(DWORD*)&(pInterruptRxFrame->bData[4]) = dwrCAN1RDB;
dwrCAN1CMR = (1<<2);
CanRxFramePtrReceived = (CanRxFramePtrReceived+1)%CAN_NUM_RX_FRAMES;
CanRxPacketCounter++;
}
...
}
{
CanInterruptStatus = dwrCAN1ICR;
if ((CanInterruptStatus&(1<<0))!=0)
{
pInterruptRxFrame = (TCanRxTxFrame*)&(CanRxFrames[CanRxFramePtrReceived]);
pInterruptRxFrame->dwInfo = dwrCAN1RFS;
pInterruptRxFrame->dwIdentifier = dwrCAN1RID;
*(DWORD*)&(pInterruptRxFrame->bData[0]) = dwrCAN1RDA;
*(DWORD*)&(pInterruptRxFrame->bData[4]) = dwrCAN1RDB;
dwrCAN1CMR = (1<<2);
CanRxFramePtrReceived = (CanRxFramePtrReceived+1)%CAN_NUM_RX_FRAMES;
CanRxPacketCounter++;
}
...
}