I am trying to configure the CAN baud on my Nucleo F303RE, although all examples I see online do not match how Iv read to calculate them. From what I understand, the Clock rate for the ABP is 36Mhz, want a sample point of about 75-90% with a SJW of 1.
For example, using this site for the calcs for 1000kbit/s: http://www.bittiming.can-wiki.info/
We get..
Prescaler 2
Seg1 = 15
Seg2 = 2
tq = 15+2+1 =18
Now to calculate the baud using these details, we do:
36000000/ ((Swj+Seg1+Seg2)*Prescaler)
36000000/ 18*2 = 1,000,000b/s = 1000kb/s
Sample point = 15+1/18 = 88.9%
So.. this makes sense and works.. now using the exmaple from ST found here which is setup for 1000kbit/s also for a F3 device: https://github.com/eleciawhite/STM32Cub ... Src/main.c
It uses (See image below for clock setup):
CanHandle.Init.SJW = CAN_SJW_1TQ;
CanHandle.Init.BS1 = CAN_BS1_6TQ;
CanHandle.Init.BS2 = CAN_BS2_8TQ;
CanHandle.Init.Prescaler = 2;
So, this results in:
36000000/ (1+6+8)*2 = 36000000/30 = 1,200,000b/s = 1.2kb/s
Sample point would be Seg1+Sjw/Tq.. so this is 7/15 = 46.7%
Am I just really screwing up on the calculations.. or is the example out??
CANBus using ST Official Library on STM32F303RE
Re: CANBus using ST Official Library on STM32F303RE
Hi @Tazzi
This forum is more dedicated to stuff around STM32 usage in Arduino.
I guess you should better ask on ST community.
I'm not a CAN expert so could not really on this anyway is someone has some clue.
You could also check the latest official example here:
https://github.com/STMicroelectronics/S ... Networking
If you have a doubt on it then open an issue to this GitHub.
This forum is more dedicated to stuff around STM32 usage in Arduino.
I guess you should better ask on ST community.
I'm not a CAN expert so could not really on this anyway is someone has some clue.
You could also check the latest official example here:
https://github.com/STMicroelectronics/S ... Networking
If you have a doubt on it then open an issue to this GitHub.
Re: CANBus using ST Official Library on STM32F303RE
@fpiSTM Thanks for the reply!
I am using the Arduino framework for the Nucleo F303RE. To be more specific, I am using Visual Code with the platformio plugin installed which then allows using the Arduino framework (But with all the usual visual studio error code markups ect).
Within the Arduino framework, I am using the HAL libraries that ST include.
I ended up figuring it out and the calculation I did is correct.
On a F303 processor (And basically anything running 72Mhz) will use a prescaler of 2 for the ABP, which means APB1 runs at 36Mhz.
The general calculations are:
Desired CAN Speed = APB1 speed/(Prescaler*(SWJ+Seg1+Seg2))
Based on ST's ref manual, SWJ is assumed one. The previous link I provided for calculating Prescaler/Seg/Seg2 works well.
I tested reliability, and left it running over night requesting a basic CAN frame (7E0 01 20) from an ECU I have on bench, and sent over a million requests without a single drop or miss of reply.
For those looking to add canbus, the following is required:
- Create CAN_HandleTypeDef instance, select the CAN and baud options. I recommend enabling TransmitFifoPriority, AutoRetransmission and AutoBusOff.
- Call HAL_CAN_Init, this will return HAL_OK if successful.
- make a function in your main sketch called void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan). This function gets called FROM within the above init function. Need to enable the required can clk, then setup the GPIO pins for CAN RX and TX using HAL_GPIO_Init. Finally set the priority and enable the peripheral interrupts for CAN_TX_IRQn and CAN_RX0_IRQn.
- Configure Filter/s using HAL_CAN_ConfigFilter
- Start CAN using HAL_CAN_Start
Missing any of the above results in it not working at all.
For reading a frame (Through polling method)
- Request HAL_CAN_GetRxFifoFillLevel and check if its greater then 0 (Meaning frame available(
- Call HAL_CAN_GetRxMessage to get the message
For writing a frame
- Pass frame to HAL_CAN_AddTxMessage
- Verify it sends by checking if HAL_CAN_GetTxMailboxesFreeLevel is < 3. If it is 3, this means all TX mailboxes are free meaning message was sent.
I am using the Arduino framework for the Nucleo F303RE. To be more specific, I am using Visual Code with the platformio plugin installed which then allows using the Arduino framework (But with all the usual visual studio error code markups ect).
Within the Arduino framework, I am using the HAL libraries that ST include.
I ended up figuring it out and the calculation I did is correct.
On a F303 processor (And basically anything running 72Mhz) will use a prescaler of 2 for the ABP, which means APB1 runs at 36Mhz.
The general calculations are:
Desired CAN Speed = APB1 speed/(Prescaler*(SWJ+Seg1+Seg2))
Based on ST's ref manual, SWJ is assumed one. The previous link I provided for calculating Prescaler/Seg/Seg2 works well.
I tested reliability, and left it running over night requesting a basic CAN frame (7E0 01 20) from an ECU I have on bench, and sent over a million requests without a single drop or miss of reply.

For those looking to add canbus, the following is required:
- Create CAN_HandleTypeDef instance, select the CAN and baud options. I recommend enabling TransmitFifoPriority, AutoRetransmission and AutoBusOff.
- Call HAL_CAN_Init, this will return HAL_OK if successful.
- make a function in your main sketch called void HAL_CAN_MspInit(CAN_HandleTypeDef *hcan). This function gets called FROM within the above init function. Need to enable the required can clk, then setup the GPIO pins for CAN RX and TX using HAL_GPIO_Init. Finally set the priority and enable the peripheral interrupts for CAN_TX_IRQn and CAN_RX0_IRQn.
- Configure Filter/s using HAL_CAN_ConfigFilter
- Start CAN using HAL_CAN_Start
Missing any of the above results in it not working at all.
For reading a frame (Through polling method)
- Request HAL_CAN_GetRxFifoFillLevel and check if its greater then 0 (Meaning frame available(
- Call HAL_CAN_GetRxMessage to get the message
For writing a frame
- Pass frame to HAL_CAN_AddTxMessage
- Verify it sends by checking if HAL_CAN_GetTxMailboxesFreeLevel is < 3. If it is 3, this means all TX mailboxes are free meaning message was sent.