Can't produce 20 ms PWM for servo
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 6:54 AM
Hi. I am quite new to STM32.
I would like to produce 20ms square PWM with adjustable duty cycle for controlling 2 servo position. MCU = stm32f103ret6 Using GNU ARM toolchain on Eclipse cdt. Use Timer5 Ch1,2 (PA0, PA1 for servo signal). Here is the code I write so far. // For GPIO Initializationvoid GPIO_Init_Mode_50MHz(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIOMode_TypeDef mode) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin; GPIO_InitStructure.GPIO_Mode = mode; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOx, &GPIO_InitStructure);}void InitTimer5_servoPWM(bool bCH1, bool bCH2){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure;ss /* TIM5 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 63; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 20000; // period in usec TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; RCC_AHBPeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Timer5_CH1(PA0) Timer5_CH2(PA1) if (bCH1) { GPIO_Init_Mode_50MHz(GPIOA, GPIO_Pin_0, GPIO_Mode_AF_PP); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OC1Init(TIM5, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable); TIM5->CCR1 = 0; } if (bCH2) { GPIO_Init_Mode_50MHz(GPIOA, GPIO_Pin_1, GPIO_Mode_AF_PP); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OC2Init(TIM5, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM5, TIM_OCPreload_Enable); TIM5->CCR2 = 0; } TIM_ARRPreloadConfig(TIM5, ENABLE); // output enable for TIM5 only TIM_CtrlPWMOutputs(TIM5, ENABLE); TIM_Cmd(TIM5, ENABLE); } // For changing dutycycle void SetTimer5PWM(int16_t ch, int16_t pwm) { switch(ch) { case 1 : TIM5->CCR1 = pwm; break; case 2 : TIM5->CCR2 = pwm; break; }} #stm32f103-pwm #stm32f103-pwm #!adxl345- Labels:
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 7:27 AM
Timer runs? (verify e.g. looking at TIM_CNT in debugger)
JW- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 7:30 AM
If you are not getting 20ms period what are you getting? What aspect of this is ''not working'' ?
I'd recommend not using the 50MHz slew-rate setting on a signal below 1MHzUp vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 7:48 AM
you'll need these lines where you're configuring the GPIO:
GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_??); GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_??); I'm not sure exactly which GPIO_AF_* number you'll need to use as the help docs are a little obtuse for the STM32F1* series :(- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 7:55 AM
The F1 series doesn't support GPIO_PinAFConfig as the AF options are peripheral rather than pin mapped.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 8:12 AM
oops - yes, was somehow looking at F0 :(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-25 6:36 PM
CNT is 0. It doesn't increase.
When I check with scope, it shows a funny wave that changes between 40k-250kHz and sometimes 1MHz. Is there a need to do something like pin map for Timer5 and PA0, PA1? The address of TIM5 is not available in my GPIO firmware library for mapping.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-26 12:20 AM
Then you need to enable it by setting CEN bit in TIMx_CR1. I don't use any of the ''libraries'' but there must be a function or macro for this, refer to your ''library'''s manual.
JW- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2016-10-26 6:15 AM
The TIM5_CH1/2 are default mappings for PA0/PA1 but there are several other peripherals sharing this, and they might need to be remapped if they conflict.
You'd need to check the data-sheet for the specific F1 part to see which TIMx it supports. Generally if the TIM is not present all TIMx->registers will be zero, and the clock enable bit for the APB will be stuck-at-zero. I've posted numerous servo examples, review older forum posts. Consider also what else on the board is connected to or using these pins.Up vote any posts that you find helpful, it shows what's working..
