cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L Discovery PWM

klemen
Associate II
Posted on December 16, 2013 at 11:28

Hello,

I tried to post this to the following thread, since this was my initial guidance to configure PWM, but was unsuccessful due to some permission error: https://my.st.com/public/STe2ecommunities/mcu/Lists/STM32VLDiscovery/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2FSTM32VLDiscovery%2FExample%20PWM%20on%20STM32-Discovery%20Blue%20LED&FolderCTID=0x01200200770978C69A1141439FE559EB459D758000491D59B8574F8049B5DFA3E8B21CBA51&currentv... Anyway, I am trying to enable PWM on the two LED's on the STM32L discovery board. I can confirm that the LED's work with the following code:

int main(void)
{ 
/*!< 
At
this stage the microcontroller clock setting is already configured, 
this is done through SystemInit() function which is called from startup
file (startup_stm32l1xx_md.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32l1xx.c file
*/ 
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// Enable HSI Clock
RCC_HSICmd(ENABLE); 
// Wait till HSI is ready
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
// SysTick 1 msec interrupts (
1000
= 
1ms
, 
100
= 10 ms ...) 
if(SysTick_Config(SystemCoreClock / 1000))
{
// capture error
while(1); 
}
// Enable clock for GPIOB
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
// Enable clock for TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitStructure.GPIO_Pin
= 
GPIO_Pin_6
| GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_OUT
; // GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
; 
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_40MHz
; 
GPIO_Init(GPIOB,&GPIO_InitStructure); 
//GPIO_PinAFConfig(GPIOB,GPIO_Pin_6 | GPIO_Pin_7,GPIO_AF_TIM3);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision
= 
TIM_CKD_DIV4
;
TIM_TimeBaseInitStruct.TIM_Period
= 
1000
- 1; 
TIM_TimeBaseInitStruct.TIM_Prescaler
= 
240
- 1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct); 
TIM_OCInitStruct.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStruct.TIM_OCMode
= 
TIM_OCMode_PWM1
; 
TIM_OCInitStruct.TIM_Pulse
= 
0
;
TIM_OC3Init(TIM3,&TIM_OCInitStruct);
TIM_OC4Init(TIM3,&TIM_OCInitStruct); 
TIM_Cmd(TIM3,ENABLE);
while(1) {
// TIM3->CCR3 = 800;
// TIM3->CCR4 = 0;
GPIOB->BSRRL = GPIO_Pin_6;
GPIOB->BSRRH = GPIO_Pin_7;
Delay(1000);
// TIM3->CCR3 = 0;
// TIM3->CCR4 = 800; 
GPIOB->BSRRH = GPIO_Pin_6;
GPIOB->BSRRL = GPIO_Pin_7;
Delay(1000); 
} 
}

If I change the code to (AF pin mode and change the mapping of the pins):

int main(void)
{ 
/*!< 
At
this stage the microcontroller clock setting is already configured, 
this is done through SystemInit() function which is called from startup
file (startup_stm32l1xx_md.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32l1xx.c file
*/ 
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// Enable HSI Clock
RCC_HSICmd(ENABLE); 
// Wait till HSI is ready
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
// SysTick 1 msec interrupts (
1000
= 
1ms
, 
100
= 10 ms ...) 
if(SysTick_Config(SystemCoreClock / 1000))
{
// capture error
while(1); 
}
// Enable clock for GPIOB
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
// Enable clock for TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitStructure.GPIO_Pin
= 
GPIO_Pin_6
| GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_AF
; // GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
; 
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_40MHz
; 
GPIO_Init(GPIOB,&GPIO_InitStructure); 
GPIO_PinAFConfig(GPIOB,GPIO_Pin_6 | GPIO_Pin_7,GPIO_AF_TIM3);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision
= 
TIM_CKD_DIV4
;
TIM_TimeBaseInitStruct.TIM_Period
= 
1000
- 1; 
TIM_TimeBaseInitStruct.TIM_Prescaler
= 
240
- 1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct); 
TIM_OCInitStruct.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStruct.TIM_OCMode
= 
TIM_OCMode_PWM1
; 
TIM_OCInitStruct.TIM_Pulse
= 
0
;
TIM_OC3Init(TIM3,&TIM_OCInitStruct);
TIM_OC4Init(TIM3,&TIM_OCInitStruct); 
TIM_Cmd(TIM3,ENABLE);
while(1) {
TIM3->CCR3 = 800;
TIM3->CCR4 = 0;
// GPIOB->BSRRL = GPIO_Pin_6;
// GPIOB->BSRRH = GPIO_Pin_7;
Delay(1000);
TIM3->CCR3 = 0;
TIM3->CCR4 = 800; 
// GPIOB->BSRRH = GPIO_Pin_6;
// GPIOB->BSRRL = GPIO_Pin_7;
Delay(1000); 
} 
}

Nothing happens. What am I doing wrong in the initialization? Thank you and best regards, K
7 REPLIES 7
Posted on December 16, 2013 at 13:29

GPIO_PinAFConfig(GPIOB,GPIO_Pin_6 | GPIO_Pin_7,GPIO_AF_TIM3);

Doesn't work like that, you must use the PinSource form, and configure each pin separately.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
klemen
Associate II
Posted on December 17, 2013 at 07:51

Dear Mr.clive1,

thank you for the answer. I have changed the code (using PWM only on one pin) and still nothing happens:

int main(void)
{ 
/*!< 
At
this stage the microcontroller clock setting is already configured, 
this is done through SystemInit() function which is called from startup
file (startup_stm32l1xx_md.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32l1xx.c file
*/ 
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// Enable HSI Clock
RCC_HSICmd(ENABLE); 
// Wait till HSI is ready
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
// SysTick 1 msec interrupts (
1000
= 
1ms
, 
100
= 10 ms ...) 
if(SysTick_Config(SystemCoreClock / 1000))
{
// capture error
while(1); 
}
// Enable clock for GPIOB
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
// Enable clock for TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitStructure.GPIO_Pin
= 
GPIO_Pin_6
;
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_AF
; // GPIO_Mode_OUT; 
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
; 
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_40MHz
; 
GPIO_Init(GPIOB,&GPIO_InitStructure); 
GPIO_PinAFConfig(GPIOB,GPIO_Pin_6,GPIO_AF_TIM3);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision
= 
TIM_CKD_DIV4
;
TIM_TimeBaseInitStruct.TIM_Period
= 
1000
- 1; 
TIM_TimeBaseInitStruct.TIM_Prescaler
= 
240
- 1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct); 
TIM_OCInitStruct.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStruct.TIM_OCMode
= 
TIM_OCMode_PWM1
; 
TIM_OCInitStruct.TIM_Pulse
= 
0
;
TIM_OC3Init(TIM3,&TIM_OCInitStruct);
TIM_Cmd(TIM3,ENABLE);
while(1) {
TIM3->CCR3 = 800; 
// GPIOB->BSRRL = GPIO_Pin_6;
// GPIOB->BSRRH = GPIO_Pin_7;
Delay(1000);
TIM3->CCR3 = 0; 
// GPIOB->BSRRH = GPIO_Pin_6;
// GPIOB->BSRRL = GPIO_Pin_7;
Delay(1000); 
} 
}

So, still having no luck (well I know this is not related to luck, but to my inability to find the problem). Best regards, K
Posted on December 17, 2013 at 13:13

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM3);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
klemen
Associate II
Posted on December 17, 2013 at 18:14

Oh. Sorry for missing that.

It looks like you are saving my skin on a daily basis. Truly appreciate the responsivnes and all the help.

I will try this tommorow and get back to you.

Best regards,

K

klemen
Associate II
Posted on December 18, 2013 at 08:27

Hello,

I have resolved my issue. I configured the wrong AF (TIM3 instead of TIM4) for the LED pins. I am posting the code of the initialization in case it helps someone in the future:

int main(void)
{ 
/*!< 
At
this stage the microcontroller clock setting is already configured, 
this is done through SystemInit() function which is called from startup
file (startup_stm32l1xx_md.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32l1xx.c file
*/
GPIO_InitTypeDef GPIO_InitStructure; 
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
// Enable HSI Clock
RCC_HSICmd(ENABLE); 
// Wait till HSI is ready
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET) {}
RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
// SysTick 1 msec interrupts (
1000
= 
1ms
, 
100
= 10 ms ...) 
if(SysTick_Config(SystemCoreClock / 1000))
{
// capture error
while(1); 
}
// Enable clock for GPIOB
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
// Enable clock for TIM4
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin
= 
GPIO_Pin_6
| GPIO_Pin_7; //GREEN AND BLUE LED (CHECK DOCUMENTATION ON AF)
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_AF
; 
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
; 
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_40MHz
; 
GPIO_Init(GPIOB,&GPIO_InitStructure); 
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_TIM4);
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
TIM_TimeBaseInitStruct.TIM_ClockDivision
= 
TIM_CKD_DIV4
;
TIM_TimeBaseInitStruct.TIM_Period
= 
1000
- 1; 
TIM_TimeBaseInitStruct.TIM_Prescaler
= 
240
- 1;
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);
TIM_OCStructInit(&TIM_OCInitStruct); 
TIM_OCInitStruct.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStruct.TIM_OCMode
= 
TIM_OCMode_PWM1
; 
TIM_OCInitStruct.TIM_Pulse
= 
0
;
TIM_OC1Init(TIM4,&TIM_OCInitStruct);
TIM_OC2Init(TIM4,&TIM_OCInitStruct);
TIM_Cmd(TIM4,ENABLE);
while(1) {
TIM4->CCR1= 1000;
TIM4->CCR2= 1000;
Delay(200);
TIM4->CCR1 = 800;
TIM4->CCR2 = 800;
Delay(200);
TIM4->CCR1 = 600;
TIM4->CCR2 = 600;
Delay(200);
TIM4->CCR1 = 400;
TIM4->CCR2 = 400;
Delay(200); 
TIM4->CCR1 = 200;
TIM4->CCR2 = 200;
Delay(200);
TIM4->CCR1 = 0;
TIM4->CCR2 = 0;
Delay(200); 
TIM4->CCR1 = 200;
TIM4->CCR2 = 200;
Delay(200);
TIM4->CCR1 = 400;
TIM4->CCR2 = 400;
Delay(200);
TIM4->CCR1 = 600;
TIM4->CCR2 = 600;
Delay(200);
TIM4->CCR1 = 800;
TIM4->CCR2 = 800;
Delay(200); 
} 
}

Best regards, K
jg20482048
Associate
Posted on August 21, 2015 at 04:56

Hello Clive..

Can u give code for pwm for stm32l0 discovery Board of timer 22 with 16mhz sysclock

Posted on August 21, 2015 at 05:23

The thread deals more with the L1 series parts, using the Standard Peripheral Library. I'm not actively using the L0 parts, your options there are to use the HAL/Cube libraries, or the Snippets library.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..