This is my first post so excuse my formatting. I am trying to get the can bus interface to work on my Nucleo-F446RE. I have posted my code below and my current issue is that both the TD & RD pins are permanently high (at 3.3V) without actually transmitting data. I have tried to use the SPI interface in the past with the classic MCP2515 module but that also never worked. I have tried so many things and am at a complete loss, I also have a lot of trouble finding documentation for can bus + STM32 intergration so if you have any links that alone would be greatly appreciated. Thanks!
#include "mbed.h"
// #include "mcu1pindef.h"
#if !DEVICE_CAN
#error [NOT_SUPPORTED] CAN not supported for this target
#endif
/** The constructor takes in RX, and TX pin respectively.
* These pins, for this example, are defined in mbed_app.json
*/
#define CanRD PB_8
#define CanTD PB_9
CAN can1(CanRD, CanTD, 500000);
static BufferedSerial pc(USBTX, USBRX,9600);
int messageid = 10;
int counter = 0;
char messagedata[8]{
0x1F,
0x2F,
0x1F,
0x2F,
0x1F,
0x2F,
0x1F,
0x2F
};
int main()
{
while(1){
CANMessage msg;
if (can1.write(CANMessage(messageid,messagedata,8,CANData, CANStandard))){
printf("Message sent: %d\n", counter++);
}
else{
printf("Message failed: %d\n", counter++);
}
// if (can2.read(msg)) {
// printf("Message received: %d\n", msg.data[0]);
// }
}
}
I do not say I am expert, but know something about that because I working with CAN-BUS very often.
You write about Nucleo and MCP2515 (from a past), but both are just CAN controllers and you need also a CAN transceiver like TJA1050 or MCP2551.
I do not see something wrong in code, so I suppose you do not have any transceiver, right?
The Wikipedia is very handy and contains a lot information.
On this LINK you can see an example of a circuit where two stm32f103 are connected via CAN-BUS. This MCU has just on chip CAN controller (like your F446RE) which has RD and TD pins. However, CAN BUS does not have RX line and TX line, it is working with difference pair (CAN-HIGH and CAN-LOW) .
Hi Jan; Thanks for answering so quickly! To clarify,
The MCP2515 that I tried using comes in one package together with a TJA1050.
The project that I’m working on is for a datahub, we have 2 different can bus lines that both have the exact same components connected to the (they are 2 sides in a vehicle that need to be able to work independently) and the task of the datahub is to send the data from can bus line 1 to can bus line 2 and vice versa so it can also monitor the traffic and send global error flags to the ECU.
We also have additional can bus lines coming into it so we need about 5 Can bus ports (which is why I chose the high speed F446RE since we can have 2 standard can bus pins and 3 using SPI to get the 5 we need)
I have tried the following setups, I have checked the bus rate and everything of the like and there isn’t a miss-match there:
Using an arduino UNO and F446RE using arduino code and the MCP255+TAJ1050 module;
Both boards got the connections as stated in the pinout of the boards for SPI and got code uploaded
using the arduino IDE (one read and one write, and afterwards I switched the code on the boards
around to check). And only the UNO actually wrote any can bus data (it also wanted to read, but there
was no data on the bus as the NUCLEO didn’t work. I measured the pins of the NUCLEO and things like the CS pin were behaving as expected and almost the same as when I tried to measure the CS pin on the arduino.
Using Keil Studio Online for the NUCLEO and the same arduino code for the UNO I tried the same thing, now using an MCP2551 transceiver for the nucleo. Nothing was send again… when I measured the output of the NUCLEO pins, I noticed there was no data being sent whatsoever.
So my current question is; do I need to pre-initialize the pins and their function using the STM32CUBEMX software before programming? Or is just calling the pin and the function we want to use enough? I thought just calling the pins would be enough as is the case with arduino and similar architypes, but now I am really doubting myself since I can’t get it to write any data whatsoever using Keil.
One more thing what need to be clarified. This is not related to KeilStudio (IDE) but to MbedOS.
When you are using MbedOS then nope. For basic run you really need just import code from CAN API page - CAN - API references and tutorials | Mbed OS 6 Documentation
But be careful with data read/write with interrupts, It will works just with Bare metal profile because of Mutex in full OS.
I remember the Write method is very sensitive to send data to no where. It means when wires are not connected or the node what should received the msg is not ready for long time.
Nucleo-F767ZI with MbedOS 6.17 and with 6.15 later just for sure
Same program for both boards, see below
Both boards were equipped with “self made” (my colleague did it for me and difference are just support of external power supply) CAN shield based on MCP2551. It also contains jumpers for additional choses like - loop back, add terminator. The CAN shield is primarily for the F767ZI, because we use it for a basic car simulation but with one chanell can be used also for F446RE.
Sorry for the late response. I tried to use your code and it prints the initial board data but nothing after that. I also measured the pins using my oscilloscope and there is nothing happening on any of the data pins, the TX has a 3.2V DC signal over it and the RX has a 5.2V DC.
I also tried to just read CAN data by having a working bus (2 arduino UNOS with can bus modules) and trying to read that, but to no avail. The F446RE is connected to a MCP2551 which is then connected to the bus and since both the data pins are constantly pulled high (even when the can bus is silent) I’m not expecting a hardware issue here from the 2551.
I have no clue why this is happening as it should be sending can bus data to the pins as it looks like they are being addressed properly (else they wouldn’t be high right?). I believe if I can just get the pins to output the data that I am expecting in the code I can figure out the rest but I just do not understand why this isn’t the case currently.
Hopefully you can help me make some sense out of this, I already appreciate your input until now!
that is sad, but let me ask one more thing about wiring between your dev board and the transceiver. How do you have connected those both devices to each other?
According to MCP2551 datasheet the MCP2551 has internall pull up on TX pin. So this seems be strange
My CANTD is directly wired to the TXD pin of the mcp2551 and same for CANRD and RDX, this is what I saw in most examples using these receivers so I just assumed it to be the way to do it. Funnily enough I have never dealt much with internal pullups on pins, could you maybe clarify what this means? It might very well be that the issue is with my hardware setup by the sounds of it.
According to your description it is OK. I asked because some people did a mistake and connect this like an UART RX->TX and so on but this have to be RxD->RxD.
And what about RS pin of MCP2551? It should be connected to Vdd I suppose.
Rs was floating, but the result doesn’t change no matter what I connect it to. It’s also strange that even when only the power is connected to the 2551, the RX and TX pins are 5.2V an 4V respectively. Does this indicate a faulty chip? I tested it with 2 chips and both had the same response.
Any chance you could measure your TX and RX pins with an oscilloscope? Since I believe that my issue lies with that both of them are purely DC which logically results in a DC on the Can bus.
Edit: Made an error measuring and fixed it in the post.
That would be incredibly helpful, In the meantime I will have a look if I can test all components in isolation just to double check that this isn’t just a faulty batch of chips.
Nucleo-F446RE has two CAN controllers so you can try a CAN loop from one controller to second one. And if you want to test it without trancievers then exist also this - CAN bus without transceivers | Mbed
Thanks for the links! I have looked at these types of tests repeatedly and even tried it myself early in my trouble shoot process, my main issue at the moment is that both my RD and TD pins are DC 3.2V no matter the specific pins (since the board has multiple pins you can use for both can busses, all of them have this problem). This means that I am obviously not transmitting any data which in turn cannot be read by the program.
TLDR; My pins are being addressed correctly (so no wrong address calls) but they do not transmit any data and are constant 3.2V.
You are an absolute godsent haha. I tried it with the RS resistor and suddenly it works. It seems I do not quite understand how the Can bus protocol works as now with the RS pin pulled down the TD and RD are getting step wave signals over them unlike when i measured them when they weren’t connected. It would seem the transceiver is a requirement even when just testing if a pin is being programmed to sent can bus…