2013-03-19 01:57 AM
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
2013-03-20 07:16 AM
I did not set the Repetition counter...
2013-10-21 03:25 AM
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.2014-01-02 12:55 AM
Ciao Espepe
To generate the interrupts on both each overflow and underflow you have to set the repetition counter to 0. Ciao Gigi2014-01-02 01:09 AM
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