cancel
Showing results for 
Search instead for 
Did you mean: 

Center aligned PWM interrupt

stumpf
Associate
Posted on March 19, 2013 at 09:57

I would like to implement a three phase PWM strategy using an IHM033V1 board (with a STM32F100CB microcontroller) and a IHM027V1 power board.

I use the TIM1 timer to generate the PWM signal in center aligned mode. I would like to update the CCRx registers both when the counter overflow/underflow. I implemented a Space Vector Modulation algorithm with switcing freqeuncy 4 kHz, which works fine. My problem is that, the interrupt (which calculates the duty ratios) is not generated at every overflow/underflow, only after approx 100 period (around 40 Hz). I do not know, what the problem is. Could you help me? How can I generate interrupt at each underflow/overflow of the timer? The code:

#include ''stm32f10x_conf.h''
#define ARM_MATH_CM3
#define MAX_PWM 3000
#include ''arm_math.h''
void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM1_Configuration(void);
void USART_Configuration(void);
void NVIC_Configuration(void);
void SVM(void);
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
NVIC_Configuration();
USART_Configuration();
while(1)
{ 
}
}
void RCC_Configuration(void)
{
RCC_PCLK1Config(RCC_HCLK_Div1);
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOB, ENABLE);
// clock for TIM1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; //upper switches
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ; //lower switches
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //RX,TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
GPIO_PinRemapConfig(GPIO_NoRemap_TIM1, ENABLE);
}
void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM1_TimeBaseStructure;
TIM_OCInitTypeDef TIM1_OCInitStructure;
TIM_BDTRInitTypeDef TIM1_BDTRInitStructure;
// TIM1_Pulse = 1 us
// @ 24 MHz
TIM1_TimeBaseStructure.TIM_Prescaler = 0; // 24 MHz / 1 = 24 MHz
TIM1_TimeBaseStructure.TIM_Period = MAX_PWM - 1; // 24 MHz / 3000 / 2 = 4 kHz
TIM1_TimeBaseStructure.TIM_ClockDivision = 0;
TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned3;
TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure);
//Clearing not used field
TIM_OCStructInit(&TIM1_OCInitStructure);
TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM1_OCInitStructure.TIM_Pulse = 1;
TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM1, &TIM1_OCInitStructure);
TIM_OC2Init(TIM1, &TIM1_OCInitStructure);
TIM_OC3Init(TIM1, &TIM1_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM1, ENABLE);
//Dead time
TIM1_BDTRInitStructure.TIM_DeadTime = 40; 
TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);
// turning on TIM1 and PWM outputs
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
// TIM IT enable
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the TIM1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM16_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM1_UP_TIM16_IRQHandler(void)
{
if (TIM_GetFlagStatus(TIM1, TIM_FLAG_Update) == SET)
{
SVM(); 
TIM_ClearFlag(TIM1, TIM_FLAG_Update);
}
}
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 38400;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
}

#tim1-interrupt
4 REPLIES 4
stumpf
Associate
Posted on March 20, 2013 at 15:16

I did not set the Repetition counter...

sachin
Associate
Posted on October 21, 2013 at 12:25

Hello,

          I am trying to implement Space Vector Modulation using stm32f407 microcontroller. Do i need to add a PWM firmware library to proceed or is it possible to implement it without this library? If it is needed could you please let me know from where can i get it? I went through your code and came across SVM function. So what exactly have you defined in this function? Waiting for your reply.

Gigi
Senior
Posted on January 02, 2014 at 09:55

Ciao Espepe

To generate the interrupts on both each overflow and underflow you have to set the repetition counter to 0.

Ciao

Gigi

Gigi
Senior
Posted on January 02, 2014 at 10:09

Ciao Sachin,

You can find the PWM firmware driver and examples in the ''standard periperal drivers for STM32'' provided in the ST.com.

http://www.st.com/web/catalog/tools/FM147/CL1794/SC961/SS1743/PF257901#

. Click the ''Download'' button on the bottom of the page.

You can take the TIM example as starting point for the SVM development.

Ciao

Gigi