2011-02-12 12:39 PM
Hey,
I just spent a bunch of time sorting out how to get the darn PWM output on the blue LED on the STM32-Discovery board. After a lot of time pouring over the datasheets and forum posts I was finally able to work out the following code. Seems to work very well. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); // Set the Vector Table base address at 0x08000000. NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); // Configure HCLK clock as SysTick clock source. SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK ); // Setup Blue LED on STM32-Discovery Board to use PWM. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Alt Function - Push Pull GPIO_Init( GPIOC, &GPIO_InitStructure ); GPIO_PinRemapConfig( GPIO_FullRemap_TIM3, ENABLE ); // Map TIM3_CH3 to GPIOC.Pin8 // Let PWM frequency equal 100Hz. // Let period equal 1000. Therefore, timer runs from zero to 1000. Gives 0.1Hz resolution. // Solving for prescaler gives 240. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct ); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV4; TIM_TimeBaseInitStruct.TIM_Period = 1000; TIM_TimeBaseInitStruct.TIM_Prescaler = 240; TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStruct ); TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCStructInit( &TIM_OCInitStruct ); TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // Initial duty cycle equals 0%. Value can range from zero to 1000. TIM_OCInitStruct.TIM_Pulse = 0; TIM_OC3Init( TIM3, &TIM_OCInitStruct ); TIM_Cmd( TIM3, ENABLE ); Also, below is a useful macro that sets the PWM duty cycle once the output is running. // Set duty cycle when using TIM3 as a PWM output. &sharpdefine SetTIM3Duty( val ) TIM3->CCR3 = val It's neat to see the blue LED ramping and fading smoothly. #stm32 #pwm #pwm #discovery #stm32f100rb #output2011-02-14 10:03 AM
FYI, These are zero based
TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1; // 0 .. 999 TIM_TimeBaseInitStruct.TIM_Prescaler = 240 - 1; // divide by 2402011-02-17 07:38 AM
... and, if you are interested, that should have been ''poring'' ... unless you were using a jug.
2011-03-17 04:41 AM
Nice code. In addition to Clive's correction, I would suggest updating it with
GPIO_StructInit(&GPIO_InitStructure); // Reset init structure
as this can catch beginners who have already defined and partially filled GPIO_InitStructure elsewhere can get caught up on this.
2011-03-17 06:27 PM
I'm so thankful that someone posted a PWM signal example because I was having trouble figuring out how to do it. I really would like to use this code to drive some stepper motors. To test it, I tried just copying and pasting the code to my main function. However, when building the compiler said that GPIO_InitStructure was undeclared. What am I missing?
2011-03-17 06:48 PM
What am I missing?
GPIO_InitTypeDef GPIO_InitStructure; Note also that the FW library comes with some examples, and both IAR and Keil have more extensive examples from the earlier 2.0 library which are also quiet instructive.2011-03-17 06:58 PM
This should be a fairly complete version, integrating all the additional suggestions. I think I've previously posted some other TIM3 and TIM4 examples, but this forum is so busted and external Google search might be more effective. Thanks to JimK for posting his version.
#include ''stm32F10x.h'' #include ''STM32vldiscovery.h'' int main(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE ); RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); // Set the Vector Table base address at 0x08000000. NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 ); NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); // Configure HCLK clock as SysTick clock source. SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK ); GPIO_StructInit(&GPIO_InitStructure); // Reset init structure // Setup Blue LED on STM32-Discovery Board to use PWM. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // Alt Function - Push Pull GPIO_Init( GPIOC, &GPIO_InitStructure ); GPIO_PinRemapConfig( GPIO_FullRemap_TIM3, ENABLE ); // Map TIM3_CH3 to GPIOC.Pin8 // Let PWM frequency equal 100Hz. // Let period equal 1000. Therefore, timer runs from zero to 1000. Gives 0.1Hz resolution. // Solving for prescaler gives 240. TIM_TimeBaseStructInit( &TIM_TimeBaseInitStruct ); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV4; TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1; // 0..999 TIM_TimeBaseInitStruct.TIM_Prescaler = 240 - 1; // Div 240 TIM_TimeBaseInit( TIM3, &TIM_TimeBaseInitStruct ); TIM_OCStructInit( &TIM_OCInitStruct ); TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // Initial duty cycle equals 0%. Value can range from zero to 1000. TIM_OCInitStruct.TIM_Pulse = 0; // 0 .. 1000 (0=Always Off, 1000=Always On) TIM_OC3Init( TIM3, &TIM_OCInitStruct ); TIM_Cmd( TIM3, ENABLE ); while(1); // Do not exit return(0); // System will implode }2011-04-11 03:22 AM
2011-04-11 10:57 AM
Try picking a 50% duty cycle (500), instead of OFF all the time?
// Initial duty cycle equals 0%. Value can range from zero to 1000. TIM_OCInitStruct.TIM_Pulse = 0; // 0 .. 1000 (0=Always Off, 1000=Always On)2011-04-20 01:51 PM
We are new to STM32F103ZE i think its similar to STM32VL.. i copy paste the code and change the LED port but it is not working. Is there other way to use timer of our board. We cannot make our any timer program running in this board. If you have any program related to our board which use timer please post it here..
Looking forward for your mail.
Thanks,
Sujit