2014-04-05 09:30 PM
Hi all!
I want to control 3 phase motor (I get HDD motor from old HDD), and now I can generate 3 PWM signal on 3 channels but they are same, notshift phase
120 degree! Please help me! I use STM32F4 discovery board and Keil! Thanks all2014-09-22 02:14 AM
2014-09-22 02:25 AM
#include ''main.h''
int i=0, j=0;GPIO_InitTypeDef bhutta;void gpio();void gpio() { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE,ENABLE ); bhutta.GPIO_Mode=GPIO_Mode_AF; bhutta.GPIO_OType=GPIO_OType_PP; bhutta.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13; bhutta.GPIO_Speed=GPIO_Speed_50MHz; bhutta.GPIO_PuPd=GPIO_PuPd_NOPULL; GPIO_Init(GPIOE,&bhutta); GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_2); GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_2); GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_2); } TIM_TimeBaseInitTypeDef pwm_specification; TIM_OCInitTypeDef oc;int clk=72e6;const int tim_freq =10000; int prescaler=((72e6/tim_freq)-1);const int pwm_freq=1; const int pwm_period= tim_freq/pwm_freq; //int ms=(float)pwm_period / (1000.0/pwm_freq); // for 200Hz we get: 10000 / (1/200 * 1000) = 2000void timer_init(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); pwm_specification.TIM_ClockDivision=0; pwm_specification.TIM_CounterMode=TIM_CounterMode_Up; pwm_specification.TIM_Period=pwm_period-1; pwm_specification.TIM_Prescaler=prescaler-1; //initilize channel TIM_TimeBaseInit(TIM1,&pwm_specification); oc.TIM_OCMode=TIM_OCMode_Toggle; oc.TIM_OCPolarity=TIM_OCPolarity_High; oc.TIM_OutputState=TIM_OutputState_Enable ; oc.TIM_Pulse=(pwm_period/6);TIM_OC1Init(TIM1, &oc);oc.TIM_Pulse=(pwm_period/3)+(pwm_period/3);TIM_OC2Init(TIM1, &oc);oc.TIM_Pulse=(pwm_period/3)+(( pwm_period* 2) / 3);TIM_OC3Init(TIM1, &oc);TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); }int main(){ gpio(); timer_init(); while(1) { TIM_SetCompare1(TIM1,1000); TIM_SetCompare2(TIM1,1000); TIM_SetCompare3(TIM1,1000); }}#ifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */ /* Infinite loop */ while (1) { }}#endif2014-09-22 06:37 AM
2014-09-22 06:40 AM
hye. clive sr .. please tell me about phase diff. 120 degree in 3 pwm channels of TIM1 of STM32F3
2014-09-22 08:06 AM
clive1 sir please tell me about the 120 degree phase shift in 3 pwm channels using TIM1 .i have posted my code , but there is no delay in pwm,s in oscilloscope.. plz find mistake in my code .
You set the compare points of all three channels to be the same (1000), and consequently all the edges will be placed at the same point, you have to infer the phase shift by placing the compare points at the points in the period rotation where you want the edges to fall. Think of it like the dial on a clock, if you set everything at 10 o'clock that's when they all trigger. You'd want them at 1, 5 and 9 for example.2014-09-22 08:49 AM
yes . now phase shift has been added. sir can u plz tell me that how can i put dead time between these 3 channels and thier ciorresponding N (invert ) channels . (between channel and channelN and so for other 2 channels)
2014-09-22 09:05 AM
Yeah, I don't know why you didn't port the code as I presented it, it was pretty clean and portable. TIM1 you'd need to pay attention to the extra fields in the OC structure, and enable the PWM Output.
2014-09-22 09:33 AM
yes . now phase shift has been added. sir can u plz tell me that how can i put dead time between these 3 channels and their corresponding N (invert ) channels . (between channel and channelN and so for other 2 channels)
That's really not my area, you'll need to review the documentation thoroughly to understand your options here. STM32F3-Discovery_FW_V1.0.0\Project\Peripheral_Examples\TIM_ComplementarySignals\main.c ?? This was my quick port to the STM32F3-Discovery board.// STM32F3-Discovery TIM1 Triphase Output PE.9, PE.11 and PE.13 - sourcer32@gmail.com
#include ''stm32f30x.h''
//******************************************************************************
void RCC_Configuration(void)
{
/* enable peripheral clock for TIM1 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOE clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
}
//******************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOE Configuration: TIM1 on PE9/PE11/PE13 LED */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Connect TIM1 pin */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_2); // PE9 TIM1_CH1 LD3 RED
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_2); // PE11 TIM1_CH2 LD7 GREEN
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_2); // PE13 TIM1_CH3 LD10 RED
}
//******************************************************************************
void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
int Prescaler, Period;
Prescaler = (SystemCoreClock / 360000); // 360 KHz timebase, assumes APB2 H/1 TIMCLK1 H/1
Period = 36000; // 10 Hz -> 5 Hz
// The toggle halves the frequency
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel 1, 2 and 3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
/* Default unused fields TIM1 more sensitive */
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
/* Don't want to set 0 or Period, but have 3 points at 120 degrees from each other */
TIM_OCInitStructure.TIM_Pulse = ((Period * 1) / 3) - 1;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = ((Period * 2) / 3) - 1;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = ((Period * 3) / 3) - 1;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
/* Enable pins, TIM1 more sensitive */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
}
//******************************************************************************
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
while(1); /* Infinite loop */
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d
'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
2014-09-22 09:52 AM
Complementary
// STM32F3-Discovery TIM1 Triphase Output PE.9, PE.11 and PE.13 - sourcer32@gmail.com
// Plus complementary on PE.8, PE.10 and PE.12
#include ''stm32f30x.h''
//******************************************************************************
void RCC_Configuration(void)
{
/* enable peripheral clock for TIM1 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* GPIOE clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);
}
//******************************************************************************
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOE Configuration: TIM1 on PE8/PE9/PE10/PE11/PE12/PE13 LED */
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Connect TIM1 pin */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_2); // PE8 TIM1_CH1N LD4 BLUE
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_2); // PE9 TIM1_CH1 LD3 RED
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_2); // PE10 TIM1_CH2N LD5 ORANGE
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_2); // PE11 TIM1_CH2 LD7 GREEN
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_2); // PE12 TIM1_CH3N LD9 BLUE
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_2); // PE13 TIM1_CH3 LD10 RED
}
//******************************************************************************
void TIM1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
int Prescaler, Period;
Prescaler = (SystemCoreClock / 360000); // 360 KHz timebase, assumes APB2 H/1 TIMCLK1 H/1
Period = 36000; // 10 Hz -> 5 Hz
// The toggle halves the frequency
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = Period - 1;
TIM_TimeBaseStructure.TIM_Prescaler = Prescaler - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel 1, 2 and 3 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
/* Default unused fields TIM1 more sensitive */
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
/* Don't want to set 0 or Period, but have 3 points at 120 degrees from each other */
TIM_OCInitStructure.TIM_Pulse = ((Period * 1) / 3) - 1;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = ((Period * 2) / 3) - 1;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OCInitStructure.TIM_Pulse = ((Period * 3) / 3) - 1;
TIM_OC3Init(TIM1, &TIM_OCInitStructure);
/* Enable pins, TIM1 more sensitive */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
}
//******************************************************************************
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
TIM1_Configuration();
while(1); /* Infinite loop */
}
/**************************************************************************************/
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf(''Wrong parameters value: file %s on line %d
'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
2014-10-17 11:58 AM
hye clive sir.
how we can perform logic AND operation of PWM Channel 1 of TIM1 and pwm Channel 1 of TIM3 internally (using progmming)?