在永磁同步電機的控制中,須要對電機的三相定子施加必定的電壓,才能控制電機轉動。如今用的較多的是SVPWM(SVPWM的具體原理會在後面另寫一篇博客說明),要想產生SVPWM波形,須要控制的三相電壓呈以下形式,即A、B、C三相的電壓是中間對齊的,這就須要用到stm32定時器的中間對齊模式了。app
一、stm32的時鐘樹fetch
stm32的時鐘樹以下圖所示,簡單介紹一下stm32時鐘的配置過程。之外部時鐘做爲時鐘源爲例。HSE表明外部時鐘(假設爲8M)、SYSCLK爲系統時鐘,通過倍頻器以後變成168M、SYSCLK通過AHB預分頻器(假設分頻係數爲1)後變成HCLK時鐘等於系統時鐘SYSCLK,HCLK即AHB外部總線時鐘,通過APB預分頻器分出APB1時鐘(分頻係數爲2,低速設備SYSCLK/4)與APB2時鐘(分頻係數爲1,高速設備SYSCLK/2)ui
HSE->SYSCLK->HCLK->APB一、APB2。this
針對stm32f427的配置源碼以下spa
static void SetSysClock(void) { #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) /******************************************************************************/ /* PLL (clocked by HSE) used as System clock source */ /******************************************************************************/ __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Select regulator voltage output Scale 1 mode */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; /* HCLK = SYSCLK / 1*/ RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//AHB時鐘 #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) /* PCLK2 = HCLK / 2*/ RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//APB2時鐘 /* PCLK1 = HCLK / 4*/ RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//APB1時鐘 #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */ /* Configure the main PLL */ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); /* Enable the main PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till the main PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } #if defined (STM32F427_437xx) || defined (STM32F429_439xx) /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ PWR->CR |= PWR_CR_ODEN; while((PWR->CSR & PWR_CSR_ODRDY) == 0) { } PWR->CR |= PWR_CR_ODSWEN; while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) { } /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; #endif /* STM32F427_437x || STM32F429_439xx */ /* Select the main PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= RCC_CFGR_SW_PLL; /* Wait till the main PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } }
2、stm32定時器的時鐘code
stm32定時器分爲高級定時器(TIM1與TIM8)、通用定時器(TIM2-TIM五、TIM9-TIM14)、基本定時器(TIM六、TIM7)。不一樣的定時器使用不一樣的時鐘。blog
其中TIM一、TIM八、TIM十、TIM11使用的是APB2時鐘,而其他定時器使用的是APB1時鐘。事件
在stm32手冊中有這麼一段話ip
根據前面RCC配置能夠知道TIM一、TIM八、TIM十、TIM11使用的時鐘頻率爲SYSCLK,其餘定時器使用的時鐘頻率爲SYSCLK/2同步
三、stm32定時器1的中間對齊模式
對齊模式的圖示以下圖所示,能夠看到在中心對齊模式下產生的PWM波形的週期比實際計數週期要大1倍,因此假設要使用中間對齊模式,而且須要產生的PWM波頻率爲20K,那麼對應的定時器時基應該設爲40K。
在SVPWM波的產生過程當中使用的是定時器1的3對互補的PWM通道,它的配置以下
static void TIM1_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//使能定時器1時鐘 Time1_Period = (SystemCoreClock / 40000 );//定時器頻率爲APB2頻率的2倍=HCLK 自動重裝載爲40K,最大值爲4200 Limit_Pluse_Max_Value = Time1_Period * 0.95; /* TIM1 Peripheral Configuration */ TIM_DeInit(TIM1); /* Time Base configuration */ //配置定時器的計數方式爲中間對齊方式,因此產生的PWM波的頻率爲20K TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//TIM_CounterMode_Up;TIM_CounterMode_CenterAligned1 TIM_TimeBaseStructure.TIM_Period = Time1_Period - 1;//PERIOD;//定時器時基40K TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0; TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR1_Val; //佔空比50% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_Low;TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM_OCNPolarity_Low;TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1,&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR2_Val;//佔空比50% TIM_OC2Init(TIM1,&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR3_Val;//佔空比50% TIM_OC3Init(TIM1,&TIM_OCInitStructure); // /* Channel 4 Configuration in OC */ // TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; // TIM_OCInitStructure.TIM_Pulse = 4000;//Time1_Period / 2; //1500;//PERIOD - 1; // // TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; // TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; // TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; // TIM_OC4Init(TIM1,&TIM_OCInitStructure); /* TIMx->CCMR1的bit3設爲1:輸出比較寄存器預裝載使能 */ // PWM佔空比改變只在更新事件時生效 TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//A相 /* TIMx->CCMR1的bit11設爲1:輸出比較寄存器預裝載使能 */ // PWM佔空比改變只在更新事件時生效 TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);//B相 /* TIMx->CCMR2的bit3設爲1:輸出比較寄存器預裝載使能 */ // PWM佔空比改變只在更新事件時生效 TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);//C相 // TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);//電磁鐵 /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 50; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;//TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure); TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update); /* TIM1 counter enable */ // TIM_Cmd(TIM1,ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1,ENABLE);//因爲使用中間對齊模式,PWM頻率爲20K //TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//定時器1的溢出中斷 }