AnsweredAssumed Answered

Center aligned PWM interrupt

Question asked by espepe on Mar 19, 2013
Latest reply on Jan 2, 2014 by Gigi
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);
}


Outcomes