你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32定时器时钟以及中间对齐模式

[复制链接]
STMCU小助手 发布时间:2022-1-23 19:24
在永磁同步电机的控制中,需要对电机的三相定子施加一定的电压,才能控制电机转动。现在用的较多的是SVPWM(SVPWM的具体原理会在后面另写一篇博客说明),要想产生SVPWM波形,需要控制的三相电压呈如下形式,即A、B、C三相的电压是中间对齐的,这就需要用到stm32定时器的中间对齐模式了。
1439959-20181009145135207-365988838.png
1、stm32的时钟树
stm32的时钟树如下图所示,简单介绍一下stm32时钟的配置过程。以外部时钟作为时钟源为例。HSE代表外部时钟(假设为8M)、SYSCLK为系统时钟,经过倍频器之后变成168M、SYSCLK经过AHB预分频器(假设分频系数为1)后变成HCLK时钟等于系统时钟SYSCLKHCLK即AHB外部总线时钟,经过APB预分频器分出APB1时钟(分频系数为2,低速设备SYSCLK/4)与APB2时钟(分频系数为1,高速设备SYSCLK/2
HSE->SYSCLK->HCLK->APB1、APB2。
1439959-20181009145934096-582470711.png
针对stm32f427的配置源码如下
  1. static void SetSysClock(void)
  2. {
  3. #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)
  4. /******************************************************************************/
  5. /*            PLL (clocked by HSE) used as System clock source                */
  6. /******************************************************************************/
  7.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  8.   
  9.   /* Enable HSE */
  10.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  11.   /* Wait till HSE is ready and if Time out is reached exit */
  12.   do
  13.   {
  14.     HSEStatus = RCC->CR & RCC_CR_HSERDY;
  15.     StartUpCounter++;
  16.   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  17.   if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  18.   {
  19.     HSEStatus = (uint32_t)0x01;
  20.   }
  21.   else
  22.   {
  23.     HSEStatus = (uint32_t)0x00;
  24.   }

  25.   if (HSEStatus == (uint32_t)0x01)
  26.   {
  27.     /* Select regulator voltage output Scale 1 mode */
  28.     RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  29.     PWR->CR |= PWR_CR_VOS;

  30.     /* HCLK = SYSCLK / 1*/
  31.     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//AHB时钟  

  32. #if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)      
  33.     /* PCLK2 = HCLK / 2*/
  34.     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//APB2时钟
  35.    
  36.     /* PCLK1 = HCLK / 4*/
  37.     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//APB1时钟
  38. #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */

  39.    
  40.     /* Configure the main PLL */
  41.     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
  42.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

  43.     /* Enable the main PLL */
  44.     RCC->CR |= RCC_CR_PLLON;

  45.     /* Wait till the main PLL is ready */
  46.     while((RCC->CR & RCC_CR_PLLRDY) == 0)
  47.     {
  48.     }
  49.    
  50. #if defined (STM32F427_437xx) || defined (STM32F429_439xx)
  51.     /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
  52.     PWR->CR |= PWR_CR_ODEN;
  53.     while((PWR->CSR & PWR_CSR_ODRDY) == 0)
  54.     {
  55.     }
  56.     PWR->CR |= PWR_CR_ODSWEN;
  57.     while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
  58.     {
  59.     }      
  60.     /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
  61.     FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
  62. #endif /* STM32F427_437x || STM32F429_439xx  */


  63.     /* Select the main PLL as system clock source */
  64.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  65.     RCC->CFGR |= RCC_CFGR_SW_PLL;

  66.     /* Wait till the main PLL is used as system clock source */
  67.     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
  68.     {
  69.     }
  70.   }
  71.   else
  72.   { /* If HSE fails to start-up, the application will have wrong clock
  73.          configuration. User can add here some code to deal with this error */
  74.   }
  75. }
复制代码

2、stm32定时器的时钟
stm32定时器分为高级定时器(TIM1与TIM8)、通用定时器(TIM2-TIM5、TIM9-TIM14)、基本定时器(TIM6、TIM7)。不同的定时器使用不同的时钟。
其中TIM1、TIM8、TIM10、TIM11使用的是APB2时钟,而其余定时器使用的是APB1时钟。
1439959-20181009151652667-444631565.png
在stm32手册中有这么一段话
1439959-20181009151806696-2025482643.png

根据前面RCC配置可以知道TIM1、TIM8、TIM10、TIM11使用的时钟频率为SYSCLK,其他定时器使用的时钟频率为SYSCLK/2
3、stm32定时器1的中间对齐模式
对齐模式的图示如下图所示,可以看到在中心对齐模式下产生的PWM波形的周期比实际计数周期要大1倍,所以假设要使用中间对齐模式,并且需要产生的PWM波频率为20K,那么对应的定时器时基应该设为40K。

1439959-20181009163316621-467293386.png

在SVPWM波的产生过程中使用的是定时器1的3对互补的PWM通道,它的配置如下
  1. static void TIM1_Configuration(void)
  2. {   
  3.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  4.     TIM_OCInitTypeDef  TIM_OCInitStructure;
  5.     TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
  6.    
  7.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//使能定时器1时钟
  8.    
  9.     Time1_Period =  (SystemCoreClock / 40000 );//定时器频率为APB2频率的2倍=HCLK 自动重装载为40K,最大值为4200
  10.    
  11.     Limit_Pluse_Max_Value = Time1_Period * 0.95;
  12.    
  13.   /* TIM1 Peripheral Configuration */
  14.    
  15.   TIM_DeInit(TIM1);

  16.   /* Time Base configuration */
  17.     //配置定时器的计数方式为中间对齐方式,所以产生的PWM波的频率为20K
  18.   TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
  19.   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;//TIM_CounterMode_Up;TIM_CounterMode_CenterAligned1
  20.   TIM_TimeBaseStructure.TIM_Period = Time1_Period - 1;//PERIOD;//定时器时基40K
  21.   TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  22.   TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;

  23.   TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);

  24.   /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  25.   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  26.   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  27.   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;                  
  28.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR1_Val; //占空比50%
  29.   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM_OCPolarity_Low;TIM_OCPolarity_High;
  30.   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//TIM_OCNPolarity_Low;TIM_OCNPolarity_High;         
  31.   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//TIM_OCIdleState_Set;
  32.   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
  33.    
  34.   TIM_OC1Init(TIM1,&TIM_OCInitStructure);

  35.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR2_Val;//占空比50%
  36.   TIM_OC2Init(TIM1,&TIM_OCInitStructure);

  37.   TIM_OCInitStructure.TIM_Pulse = Time1_Period / 2;//CCR3_Val;//占空比50%
  38.   TIM_OC3Init(TIM1,&TIM_OCInitStructure);
  39.    
  40.    
  41. //   /* Channel 4 Configuration in OC */
  42. //   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  43. //   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  44. //   TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
  45. //   TIM_OCInitStructure.TIM_Pulse = 4000;//Time1_Period / 2;            //1500;//PERIOD - 1;
  46. //   
  47. //   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  48. //   TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;         
  49. //   TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  50. //   TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;            
  51.   
  52. //   TIM_OC4Init(TIM1,&TIM_OCInitStructure);   
  53.    
  54.     /* TIMx->CCMR1的bit3设为1:输出比较寄存器预装载使能 */  // PWM占空比改变只在更新事件时生效
  55.   TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);//A相
  56.    
  57.     /* TIMx->CCMR1的bit11设为1:输出比较寄存器预装载使能 */ // PWM占空比改变只在更新事件时生效
  58.   TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);//B相
  59.    
  60.     /* TIMx->CCMR2的bit3设为1:输出比较寄存器预装载使能 */  // PWM占空比改变只在更新事件时生效
  61.   TIM_OC3PreloadConfig(TIM1,TIM_OCPreload_Enable);//C相

  62. //   TIM_OC4PreloadConfig(TIM1,TIM_OCPreload_Enable);//电磁铁
  63.    
  64.   /* Automatic Output enable, Break, dead time and lock configuration*/
  65.   TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  66.   TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  67.   TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
  68.   TIM_BDTRInitStructure.TIM_DeadTime = 50;
  69.   TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//TIM_Break_Enable;
  70.   TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  71.   TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;//TIM_AutomaticOutput_Enable;

  72.   TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);
  73.    
  74.     TIM_SelectOutputTrigger(TIM1,TIM_TRGOSource_Update);
  75.    
  76.   /* TIM1 counter enable */
  77. //   TIM_Cmd(TIM1,ENABLE);

  78.   /* Main Output Enable */
  79.    TIM_CtrlPWMOutputs(TIM1,ENABLE);//由于使用中间对齐模式,PWM频率为20K
  80.    
  81.   //TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);//定时器1的溢出中断
  82. }
复制代码


收藏 评论0 发布时间:2022-1-23 19:24

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版