cancel
Showing results for 
Search instead for 
Did you mean: 

PWM with TIM1 lags

zexx86
Associate II
Posted on February 10, 2012 at 20:00

Hello

STM32RBT6 should control 1 servo with PWM output. For all TIM2 - TIM4 I tested it seems to be OK, but for TIM1 Channel 1 which is one I need it is working only occasionally what is very strange.

Sometime I just recompile same code and it is working correctly, until I recompile it again.

Well, it works, but output is very laggy - cca 1 second shoots.

It should control brushless regulator, it use same output as servos, so I testing it with some servos ..

Here is my code 

http://pastebin.com/hN2EsGH7

There are 2 servos, one with TIM2 which works smoothly as expected, second with TIM1. Notice, that it is controlled by same code.

I wonder TIM1 CH1 is used by something, but I can't find what, when throttle_init() is called right after RCC_APB2PeriphClockCmd() in main()..

Next thing, TIM1 CH1 servo don't react at all without TIM_CtrlPWMOutputs (TIM1, ENABLE);

Somebody know, where could be a problem ?

#tim1-channel-1-pwm
17 REPLIES 17
Posted on February 10, 2012 at 20:27

If you see unpredictable problems you should probably actively clear local/automatic variables first, and also consider the phase of the timer before reprogramming them, or changing control parameters.

So are these 50 Hz (20 ms) servos? I posted some code for controlling RC type servos, basically 4 from a single timer. Not all the timers use the same cell, so initializing the more complex ones takes more care. If the servos expect some different kind of PWM, please cite a data sheet for reference.

[DEAD LINK /public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Servo control using STM32VLDiscovery&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000491D59B8574F8049B5DFA3E8B21CBA51&TopicsView=https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/AllItems.aspx&currentviews=397]https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fSTM32VLDiscovery%2fServo%20control%20using%20STM32VLDiscovery&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000491D59B8574F8049B5DFA3E8B21CBA51&TopicsView=https%3A%2F%2Fmy.st.com%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32VLDiscovery%2FAllItems.aspx¤tviews=397

I have similar code for the STM32F4, and have that working on multiple timers.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
zexx86
Associate II
Posted on February 10, 2012 at 21:08

Thanks

I checked your code, actually I written very similar code to your with TIM3 for 4 servos and it is working pretty good.

My servos can handle 333Hz (coreless motor), so there is no issue with servos, I am sure something is wrong with code, compiler or std library.

But for now, I need working servo on PA8 pin, is there a way to use another TIMer ?

I guess I cant remap another one (channel) to this pin.

Posted on February 10, 2012 at 22:08

You don't have remapping options to connect it to other timers, PA8's usability will depend on what it's wired to on the board. On the VL-Discovery it is free.

This works on the VL, you should be able to change the frequency to suit.

#include ''stm32F10x.h''
#include ''STM32vldiscovery.h''
/**************************************************************************************/
void RCC_Configuration(void)
{
// clock for GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// clock for TIM1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// PA.08 TIM1_CH1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/**************************************************************************************/
void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1; // 24 MHz / 24 = 1 MHz
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; // 1 MHz / 20000 = 50 Hz (20 ms)
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Enable TIM1 Preload register on ARR */
TIM_ARRPreloadConfig(TIM1, ENABLE);
/* TIM PWM1 Mode configuration */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 600 + 900; // 1500 us Servo Top Centre
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Output Compare PWM1 Mode configuration: Channel1 PA.08 */
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
}
/**************************************************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
while(1);
}
/**************************************************************************************/

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
zexx86
Associate II
Posted on February 11, 2012 at 00:08

This code does not work at all - no PWM output with TIM1 CH1, with other it works OK.

I have to change:

    TIM_oc.TIM_OCMode = TIM_OCMode_PWM1;

 

    TIM_oc.TIM_OutputState = TIM_OutputState_Enable;

 

    TIM_oc.TIM_Pulse = 600 + 900; // 1500 us Servo Top Centre

 

    TIM_oc.TIM_OCPolarity = TIM_OCPolarity_High;

 

to

    TIM_oc.TIM_OCMode = TIM_OCMode_PWM1;

 

    TIM_oc.TIM_OutputState = TIM_OutputState_Enable;

 

    TIM_oc.TIM_OutputNState = TIM_OutputNState_Disable;

 

    TIM_oc.TIM_Pulse = 1520;

 

    TIM_oc.TIM_OCPolarity = TIM_OCPolarity_High;

 

    TIM_oc.TIM_OCNPolarity = TIM_OCPolarity_High;

 

    TIM_oc.TIM_OCIdleState = TIM_OCIdleState_Reset;

 

    TIM_oc.TIM_OCNIdleState = TIM_OCNIdleState_Reset;

 

It does not matter what TIM_Pulse is configured when it is in servo range.  

Then it at least working as before, but servo is changing its position only every cca 1s, so it is not delayed, there are missing only updates of position. And again, TIM2 CH4 and other TIM/CH with same code is working correctly, TIM1 CH1 no :(

Posted on February 11, 2012 at 01:44

I don't know, the code worked on a ST32F100, and scoped with the expected signal. It was using the VL library.

I guess you need to consider if PA8 is being used for some other purpose on your board, or if it is blown out. Do you have a schematic or board description.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
zexx86
Associate II
Posted on February 11, 2012 at 09:18

I checked it is definitive a software problem.

I tested it on more boards, what I designed so I know exactly wiring for PA08 (TIM1 CH1) is same like PA03 (TIM2 CH4) - there is just 10K resistor in line for each wire separately.

It must be a sw problem, when it sometime work and mostly not (after next firmware flash).

I created new fresh project and does not help.

So I considering to use another (version) STD library.

EDIT: I tested another STD library (very old) with old timer syntax, etc, TIM2 CH4 works, TIM1 CH1 not. Maybe compiler problem ?

gcc version 4.5.1 (Sourcery G++ Lite 2010.09-51)

flyer31
Senior
Posted on February 11, 2012 at 12:32

You observed, that TIM 1 (and 😎 in difference to all the other timers have the MOE bit - this bit must be set, otherwise it will stop operating. They also have break functionality which must be setup correctly. With the lib timer functions I think this is a bit complicated (unless you rely on some TIM1 example of ST). Perhaps better set all bits separately (avoid the lib functions).

Posted on February 11, 2012 at 13:59

The fact the code behaviour changes when you recompile it is a bit disturbing. If you have optimization turned on, try building without.

I used the 4.23 Keil evaluation, and the VL-Discovery firmware library (V3.3.0)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
zexx86
Associate II
Posted on February 11, 2012 at 18:15

Finally it works !

For the first time with -O0 it just behaves in same way, but now I switched to older compiler (newer 4.6.1 don't compile ST's std library at all) and it is working with -O0, with -O2 positon updates are each cca 2s than with older compiler 🙂 I hope it'll work for longer time now.

Thanks again