2021-10-22 03:15 AM
I’m currently working on a project where I write software for an STM32F072 that will control a couple of stepper motor drivers via PWM with a bit of precision. I’m therefore using TIM2 and TIM3 to control two separate PWM outputs where I can regulate the period time in microseconds.
The board will also be connected to a CAN bus, mainly for receiving messages, but also to send some status messages. I’ve configured settings as far as possible using CubeMX and generated the project from there. After that I’ve coded in IAR EmbeddedWorkbench, which is our main coding environment for embedded.
1. I started by getting the CAN bus up an running, very basic functionality, just by polling via HAL functions. I could receive messages and bounce back replies. Everything was fine.
2. After that I set up TIM2 and TIM3 in CubeMX to use ‘Internal Clock’ as clock source and give PWM as output. I also setup the prescaler to get microsecond count for both timers.
3. I’m using the autoreload-register to set the period time for the PWM output (how often the stepper motor should take a step) and set the ‘On’-time for the PWM-signal using the Pulse register to 50 (i.e. 50 µs). The Pulse value was set directly in CubeMX.
4. When I had gotten the PWM-signals to behave the way I wanted, I noticed that CAN-reception was no longer functional.
I’ve tested this in small steps to localize precisely when this happens and reached the following conclusion. I can set everything up except for the Pulse register (which is set to zero by default) so that CAN is active and TIM2 and TIM3 count and give interrupts, but do not set their output pins high, since Pulse is still zero. If I then change the Pulse value for either TIM2 or TIM3 to something other than zero, CAN-reception stops working. I don’t even seem to get messages into the FIFO.
This is really quite strange, since the Pulse register is in the middle of a lot of settings for TIMx, nowhere near the settings for the CAN peripheral. I have as a final attempt tried activating interrupts for CAN reception. The result here was the same, though. With both Pulse registers (TIM2 and TIM3) set to zero CAN Rx/Tx is working, but with any or both of the Pulse registers non-zero, CAN Rx fails.
Hoping someone can point me in the right direction.
2021-10-22 06:26 AM
Could be that the PWM is causing noise in the system which is corrupting the data. I would look at the CAN lines on a scope to verify signal integrity.
2021-10-25 01:57 AM
Thanks for the reply!
Indeed, the steppers do generate a lot of noise. Enough so that the STLink loses its connection when they start stepping. But I've been running this with the stepper outputs disconnected. I'm not at work today, so I can't look at the CAN lines, but I have noticed something else that contradicts the noise theory.
I had the idea to start with the Pulse value set to zero (in CubeMX) and consequently with fully working CAN connection, and then, after the PWM has been running for a while with zero DC, change the Pulse value to 50. The idea was to pause execution before and after Pulse was set to 50, to detect changes in the CAN registers. However, when having programmed the board, I first noticed that CAN reception was working both before and after the value had been set.
This means that CAN-reception indeed does work, even with the motor connected (I tested) and all the noise that comes with that. It seems therefore, that something else causes CAN-reception to die, when the Pulse register for TIM2 or TIM3 is set to non-zero value in CubeMX.
Anyone with an STM32F072 on a board with a CAN-transceiver should be able to verify that a working CAN setup will fail to receive messages when either of these timers Pulse register is set to 50, as long as that value is set in CubeMX, and the project is generated from there.
2021-10-25 06:39 AM
> I can set everything up except for the Pulse register (which is set to zero by default) so that CAN is active and TIM2 and TIM3 count and give interrupts, but do not set their output pins high, since Pulse is still zero. If I then change the Pulse value for either TIM2 or TIM3 to something other than zero, CAN-reception stops working.
> The idea was to pause execution before and after Pulse was set to 50, to detect changes in the CAN registers. However, when having programmed the board, I first noticed that CAN reception was working both before and after the value had been set.
Don't these two statements contradict each other?
It's unlikely there is a silicon issue which causes the CAN peripheral to fail depending on values in the independent TIM peripheral.
2021-10-25 03:02 PM
The statements contradict each other, but only because I expressed my meaning terribly poorly in the first one. What I meant to say by "If I then change the Pulse value for either TIM2 or TIM3..." was really "if I then change the Pulse value for either TIM2 or TIM3 to non-zero in CubeMX, regenerated and rebuilt the whole project..."
To clarify, I have two different scenarios:
A) I have Pulse set to zero for both timers in CubeMX, CAN working fine -> I change Pulse to 50 for either timer in CubeMX, rebuild and reprogram the board, CAN reception fails.
B) I have Pulse set to zero for both timers in CubeMX, CAN working fine -> I change Pulse to 50 using '__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 50);' after a while (22,5 seconds to be quasi-exact) and CAN is still working perfectly.
> It's unlikely there is a silicon issue which causes the CAN peripheral to fail depending on values in the independent TIM peripheral.
Exactly! This is precisely my point, and why I must circle back to my original query. But I'm strongly suspecting, when Pulse is set in CubeMX, there is maybe something else happening with the CAN settings. Something that would preferably not happen. When I'm back at work, I'll try to figure out what that is, unless someone here has already enlightened me to this flaw in CubeMX, or (as is highly more likely) to the error that I've made myself.
2021-10-25 03:48 PM
A straightforward approach is to compare the CAN and TIM register settings in the "working" and "not working" scenarios. Registers tell the whole story as far as hardware goes so no chance of missing something. There could still be bugs in your software which may not be reflected in register values.
2021-11-08 10:28 PM
Here is a copy of the CAN registers. To the left is what I get when I set Pulse = 50 for TIM3 in CubeMX. When I instead change that to 0 in CubeMX and set it to 50 by putting '__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 50);' in code, I get the scenario on the right, which is when CAN Rx is working.
2021-11-10 04:50 AM
left field...
I found a pullup on Can Rx processor pin helps.
also ABOM (Automatic bus-off management) has to be ON..