stm32定时器时钟以及中间对齐模式
在永磁同步电机的控制中,需要对电机的三相定子施加一定的电压,才能控制电机转动。现在用的较多的是SVPWM(SVPWM的具体原理会在后面另写一篇博客说明),要想产生SVPWM波形,需要控制的三相电压呈如下形式,即A、B、C三相的电压是中间对齐的,这就需要用到stm32定时器的中间对齐模式了。
1、stm32的时钟树
stm32的时钟树如下图所示,简单介绍一下stm32时钟的配置过程。以外部时钟作为时钟源为例。HSE代表外部时钟(假设为8M)、SYSCLK为系统时钟,经过倍频器之后变成168M、SYSCLK经过AHB预分频器(假设分频系数为1)后变成HCLK时钟等于系统时钟SYSCLK,HCLK即AHB外部总线时钟,经过APB预分频器分出APB1时钟(分频系数为2,低速设备SYSCLK/4)与APB2时钟(分频系数为1,高速设备SYSCLK/2)
HSE->SYSCLK->HCLK->APB1、APB2。
针对stm32f427的配置源码如下
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 = , HSEStatus = ; /* 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 == ) && (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 << ) | (((PLL_P >> ) -) << ) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << ); /* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON; /* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == )
{
} #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) == )
{
}
PWR->CR |= PWR_CR_ODSWEN;
while((PWR->CSR & PWR_CSR_ODSWRDY) == )
{
}
/* 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定时器的时钟
stm32定时器分为高级定时器(TIM1与TIM8)、通用定时器(TIM2-TIM5、TIM9-TIM14)、基本定时器(TIM6、TIM7)。不同的定时器使用不同的时钟。
其中TIM1、TIM8、TIM10、TIM11使用的是APB2时钟,而其余定时器使用的是APB1时钟。
在stm32手册中有这么一段话
根据前面RCC配置可以知道TIM1、TIM8、TIM10、TIM11使用的时钟频率为SYSCLK,其他定时器使用的时钟频率为SYSCLK/2
3、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 / );//定时器频率为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 - ;//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 / ;//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 / ;//CCR2_Val;//占空比50%
TIM_OC2Init(TIM1,&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Time1_Period / ;//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 = ;
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的溢出中断
}
stm32定时器时钟以及中间对齐模式的更多相关文章
- STM32 ADC多通道转换DMA模式与非DMA模式两种方法(HAL库)
一.非DMA模式(转) 说明:这个是自己刚做的时候百度出来的,不是我自己做出来的,因为感觉有用就保存下来做学习用,原文链接:https://blog.csdn.net/qq_24815615/arti ...
- STM32系列单片机IO口模式设置
STM32单片机的每组IO口都有4个32位配置寄存器用于配置GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR和GPIOx_PUPDR,2个32位数据寄存器用于配置输入和 ...
- STM32基础分析——USART的DMA模式
有关USART的DMA传输模式,其基本的概念和配置,网上有很多博客和教程都有,这里不再赘述,只是记录一下比较容易忽视而造成调试不通的问题. 1. 串口发送和接收分属两个DMA通道 一般方式操作串口时, ...
- stm32 IO口八种模式区别
初学STM32,遇到I/O口八种模式的介绍,网上查了一下资料,下面简明写出这几种模式的区别,有不对的地方请大家多多指正! 上拉输入模式:区别在于没有输入信号的时候默认输入高电平(因为有弱上拉).下拉输 ...
- STM32入门系列-GPIO工作模式及LED电路原理
GPIO工作模式 由于GPIO内部的结构关系,决定了GPIO可配置成以下几种模式. 输入模式 在输入模式时,施密特触发器打开,输出被禁止.可通过输入数据寄存器GPIOx_IDR读取I/O状态.输入模式 ...
- 嵌入式STM32的GPIO口工作模式的介绍
一.输入模式 1. 浮空输入 浮空输入模式下,上拉和下拉两个开关断开,高或低电平通过施密特触发器到达输入数据寄存器,CPU可以通过读取输入数据寄存器从而读取到外部输入的高低电平值. 2. 输入上拉模式 ...
- 使用STM32的USART的同步模式Synchronous调戏SPI【usart模拟spi理论】
[原创出品§转载请注明出处] 出处:http://www.cnblogs.com/libra13179/p/7064321.html 什么东西?? 我们先来看我们平常看到SPI的时序图(呵呵,要是忘记 ...
- STM32:TIMER输出比较模式-PWM
在自己小板子上移植PWM时候又重新学习了一下,加入两点:1,对各种输出比较模式的学习:2,输出模式时加入中断 先写出函数: //TIM4 PWM部分初始化 //PWM输出初始化 //period:输出 ...
- STM32的结构和启动模式
一.STM32F10x功能模块 32位的Cortex-M3微处理器: 可嵌套的向量中断控制器(NVIC)和60个可屏蔽中断且有16个可编程优先级: 内嵌内存: FLASH:最大512K字节 STAM: ...
随机推荐
- centos 下安装mulval工具
我这里采用的是centos 6.5版本系统 MulVAL是企业网络安全分析的工具.它使用漏洞扫描程序(OVAL / Nessus)作为攻击路径生成的数源,其中包括扫描结果和网络可访问性信息. 在这之前 ...
- LDAP目录服务
LDAP目录服务 1.ldap目录服务介绍: 目录是一类为了浏览和搜索数据而设计的特殊的数据库,目录服务是按树状形式存储信息的,目录包含基于属性的描述信息,并且支持高级的过滤功能,一般来说,目录不支持 ...
- 7种清除浮动 (感觉br最好用然而我用的还是overflow)
1.clear清除浮动(添加空div法) 在浮动元素下方添加空div,并给该元素写css样式: {clear:both;height:0;overflow:hidden;} 2.方法:给浮动元素父级设 ...
- IIS日志分析工具-Log Parser
下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=24659 参考链接: https://www.cnblogs.com/fu ...
- FutureTask原理解析
原文链接:http://www.studyshare.cn/blog-front/blog/details/1130 首先写一个简单的Demo public static void main(Stri ...
- wcf_first
WCF包括3部分:client(需要连接到哪里,需要调用什么),service(宿主,及其消息的公开,地址的公开),wcf服务库(提供契约名称,及其怎么干) 步骤: 1.新建wcf库,其中提供一个契约 ...
- mysql 函数获取子节点
DELIMITER $$ USE `topsale`$$ DROP FUNCTION IF EXISTS `getShopIdByUserId`$$ CREATE DEFINER=`root`@`%` ...
- Caused by: java.lang.IllegalArgumentException: argument type mismatch
下面是我的报错信息 at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java: ...
- Ubuntu17.10安装Docker
Ubuntu环境下安装Docker 1. 系统要求 Docker目前只能运行在64位平台上,并且要求内核版本不低于3.10,实际上内核越新越好,过低的内核版本容易造成功能不稳定. 可以通过如下命令检查 ...
- Java_判断文件是否写入完成
/** * 等待文件(非目录)读写完毕,费时的操作,不要放在主线程 * * @param file 文件 */ private void waitForWirtenCompleted(File fil ...