一、简介:
不同的STM32系列有不同数量的定时器,针对现在学习的STM32F40x系列总共有14个定时器,针对这14个定时器可以将其分为3类,高级定时器、通用定时器和基本定时器,三种定时器大同小异,下边会针对通用定时器来介绍定时器的原理和应用。对于通用定时器根据位数和计数方式的不同又可以分为3类,相关分类的图表如下:
二、应用:
1、更新:计数器的上溢或下溢。2、事件触发。3、输入捕获。4、输出比较。5、支持针对定位的增量编码和霍尔传感器电路。5、触发输入作为外部时钟或按周期电源管理。下边会针对部分应用做相关介绍和代码分析。
三、框图:
下图是通用定时器TIM2~TIM5的框图,其他定时器的框图和该框图是类似的,只不过是在该框图的基础上做相应的裁剪做出小的变动。
下边对定时器的框图做相关拆解,并对各个部分做相关分析。
四、时钟选择及分频:
这部分的功能由框图的如下图部分产生:
由图中可以发现时钟来源有:1、内部时钟(CK_INT)。2、外部时钟模式1;外部引脚TIx,由输入捕获部分产生。3、外部时钟模式2;外部触发输入ETR。4、内部触发输入ITRx,该时钟是由另一个定时器输出产生的,对应到框图中的TRGO。经过相应的选择后产生时钟CK_PSC。
这部分同时会在相关寄存器设定计时器的计数模式、复位和使能等相关操作。
五、时基单元
时基单元框图如下:
其中包括:1、PSC预分频器;负责对选择的时钟CK_PSC分频,产生最终计数器用到的时钟CK_CNT。2、CNT计数器:负责计数,做为定时器的核心单元。3、自动重载寄存器:负责在相关事件触发后,将寄存器中的值装载到计时器中。
六、输入捕获
对输入捕获功能的基本描述就是;通过检测TIM_CHx上的边沿信号,在信号跳变时,将当前计数器的值存放到相应的捕获/比较寄存器中。该功能部分在框图中如下图所示:
其实这是定时器的4个相关通道,拿出其中一个做相关分析,其中一个通道的框图如下:
TI1为通道输入信号,经过滤波后产生TI1F,再经过边沿检测(上升沿或下降沿),再经过相关选择后产生的信号通过分频器分频后产生最后需要捕获的信号。
对于输入捕获相关库函数介绍如下;
void TIM_ICInit(TIM_TypeDef* TIMx,TIM_ICInitTypeDef* TIM_ICInitStruct); //设置通道的相关参数。
void TIM_OCxPolarityConfig(TIM_TpeDef* TIMx,uint16_t TIM_OCPolarity); //通道极性设置。
uint32_t TIM_GetCapturex(TIM_TypeDef* TIMx); //获取通道捕获值。
七、输出比较
对输出比较功能的描述:在CCRx寄存器中设定相应的值,计数器中的值与该值做比较,根据比较结果和相应的极性和有效性设定,确定输出电压的高低电平状态。和输入捕获相同,拿出其中一个通道进行分析,其中一个通道的框图如下:
通道信号经过输出模式控制器,做出模式、极性以及开关等设置后获得需要的输出信号。CCRx:捕获比较寄存器,用于设定比较值。CCMRx:设置PWM的模式。CCER:CC1P位设置极性有效性。CCER:CC1E位输出使能设定。
对输出比较相关库函数介绍如下:
void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct) //设置相关通道的参数。
void TIM_SetComparex(TIM_TypeDef* TIMx, uint32_t Comparex); //设置比较值。
TIM_OCxPreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); //使能输出比较预装载。
TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, ENABLE);//使能自动重装载预装载寄存器
八、相关初始化实例——输入捕获
//定时器5通道1输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
//初始化TIM5输入捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM5,ENABLE ); //使能定时器5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
}
九、相关初始化实例——PWM输出
//TIM14 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
//初始化TIM14 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能
TIM_Cmd(TIM14, ENABLE); //使能TIM14
}