2025-01-06 07:12 AM - last edited on 2025-01-07 06:33 AM by SofLit
Hi
I am trying to communicate CAN. I am using two boards Nucleo-G474RE and Nucleo-H755ZI-Q and two MCP2551 as transceiver.
On either side, program works for External loop back configuration. ( I did step by step debug to ensure the transmitting data is getting received or not).
But I am not getting the interrupt when in normal mode. I also tried using a single board with shorting tx and rx of the transceiver and also using two boards.
What might be the issue?
I have only attached the IOC file and main.c file for Nucleo-H755ZI-Q and it is similar for Nucleo-G474RE also.
2025-01-06 07:23 AM
Hello,
Better to share the two projects for G4 and H7.
To me, I have a doubt regarding the bitrate:
Are you sure this is the intended CAN bitrate? 115440 ? this is not a regular CAN bitrate.
if yes do you have the same bitrate on both CAN nodes?
Also, it's not recommended to use HSI for CAN communication. You need an external precise clock either a crystal or crystal oscillator:
Need also to share your schematics including the transceiver.
2025-01-06 11:50 AM
If you can get it to work in loopback mode but not normal mode, then it probably a hardware issue.
You have not indicated if you used terminating resistors when connecting the MCP2551?
2025-01-06 09:46 PM
Hi
Thanks for the reply.
Sorry I didn't use the terminating resistor. Let me try with that and update you.
Just a small query, this project is to test the CAN communication. Is it possible to do this with one board and 2 transceiver ( loopbacking TX and RX of the second transceiver so that whatever data you transmit is getting received ) ?
its a hand-drawn schematic.
2025-01-06 10:57 PM
Yes you can use 1 Nucleo that has at least 2 CAN controllers. You can't loop the TX and RX on the CAN transceiver. Technically you need two 120 ohm resistors on either ends of the CAN bus lines.
This link has an image showing the terminating resistors at each end with Node A and Node B connected to the bus.
https://www.rs-online.com/designspark/a-can-bus-primer-part-1-introduction
2025-01-07 12:11 AM
How am I supposed to check the communication? I don't have any logic analyzers. I can check whether the transmitted data is getting received.
I apologize for asking too much question. Did you mean to say that this might work? 1 nucleo and 2 CAN controllers.
2025-01-07 12:22 AM - edited 2025-01-07 02:30 AM
Hello;
No this is not the right HW connection:
@Aswin wrote:
.
Here you connected two transceivers to the same CAN instance. You need two CAN/FDCAN instances for example CAN1 and CAN2 and two transceivers. For both MCUs you have two CAN instances each.
This is the minimum hardware and connection to establish between two CAN nodes:
You can use two CAN instances of the same board.
You didn't attach your two projects for both boards and you didn't tell if you changed the clock source from HSI to HSE.
As you are using Nucleo board, you can read this article how to use STLINK MCO as a precise clock source for CAN.
2025-01-07 08:39 AM
@Aswin wrote:How am I supposed to check the communication? I don't have any logic analyzers. I can check whether the transmitted data is getting received.
I apologize for asking too much question. Did you mean to say that this might work? 1 nucleo and 2 CAN controllers.
CAN Controllers (FDCAN1 and FDCAN2) is not the same as CAN Transceivers (two MCP2551).
On the Nucleo-H755, you can enable FDCAN1 and FDCAN2 and connect 1 CAN Transceiver (MCP2551) to pin PD0 and PD1. Connect 2nd CAN transceiver (MCP2551) to pins PB12 and PB13 of Nucleo board.
Because you'll get the same interrupt callback for either CAN Controller, you can test which CAN Controller caused the interrupt and save to your specific data buffer
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
if(hfdcan == &hdfdcan1)
{
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader_1, RxData_1) != HAL_OK) // FDCAN1 data buffer
{
// handle error
}
else
{
// Set flag indicating you have data in RxData_1
}
}
else if(hfdcan == &hdfdcan2)
{
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader_2, RxData_2) != HAL_OK) // FDCAN2 data buffer
{
// handle error
}
else
{
// Set flag indicating you have data in RxData_2
}
}
}
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
// handle error
}
}
2025-01-07 08:42 AM
No need for this line in HAL_FDCAN_RxFifo0Callback():
if (HAL_FDCAN_ActivateNotification(hfdcan, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
// handle error
}
2025-01-07 09:15 AM
Yes you are right. I was looking at the OP's attached code and modified it, not thinking that it only needs to be called it once.