TIM定时器

一、定时器

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。STM32共有8个定时器,分别为两个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和两个基本定时器(TIM6、TIM7),两个高级定时器接在PB2总线上,其余都接在APB1总线。

二、基本定时器

基本定时器包括时钟源、控制器和时基单元三部分。

预分频器、计数器和自动重装载寄存器构成时基单元 

预分频器PSC:PSC写0,表示不分频,输出频率=输入频率=72MHz

                         PSC写1,表示二分频,输出频率=输入频率=36MHz

                         际分频系数=预分频器的值+1

计数器CNT:对预分频后的计数时钟进行计数,计数时钟每来一个上升沿,计数器的值加1,计数器是16位,计数范围0-65535,计数器在运行过程中会不断自增运行,当自增运行到目标值时,产生中断,完成了定时的任务。

自动重装载寄存器:16位,计数目标,当计数器值等于自动重装寄存器值,产生一个更新中断或更新事件

计数器计数频率:CK_CNT=CK_PSC/(PSC+1)

CK_PSC:预分频器的输入时钟,内部时钟一般为72MHz

CNT_EN:计数器使能,高电平计数器正常运行,低电平停止运行

CK_CNT:计数器时钟,预分频器的时钟输出,计数器的时钟输入

预分频器缓冲机制:某时刻将与分频寄存器从0改为1,如若立刻改变分频系数,会导致在一个技术周期内,前半部分和后半部分频率不一样,预分频缓冲器:如果在一个周期内改变了预分频寄存器的值,这个变化不会立刻生效,而是等到本次计数周期结束产生更新时间后生效

三、常用库函数

以通用定时器TIM2为例,定时中断函数。

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能时钟
	
	TIM_InternalClockConfig(TIM2);  //选择内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;  //时基单元结构体
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //滤波器时钟分频系数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数模式
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;  //周期,ARR自动重装器的值 0-65535
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;  //PSC预分频器的值
	// CK_CNT_OV 定时频率= = CK_PSC(系统时钟) / (PSC + 1) / (ARR + 1)   
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;  //重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);  //初始化结构体
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);  //手动清除标志位,避免复位后立刻进入中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  //开启中断通道
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //NVIC分组
	
	NVIC_InitTypeDef NVIC_InitStructure;  //NVIC结构体
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //选择中断通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //通道使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //相应优先级
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC
	
	TIM_Cmd(TIM2, ENABLE);  //使能定时器
}

void TIM2_IRQHandler(void)  //定时器中断函数
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)  //判断标志位
	{
		 //主函数
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除标志位
	}
}

四、PWM输出

        OC(Output Compare)输出比较,可以通过比较CNT与CCR捕获比较寄存器值的关系,来输出电平进行置1、置0和翻转的操作,用于输出一定频率和占空比的PWM波形。

        每个高级定时器和通用定时器都拥有4个输出比较通道,高级定时器前3个通道额外拥有死去省城和互补输出的功能。

1.PWM(脉冲宽度调制)

PWM(Pulse Width Modulation)脉冲宽度调制,在具有惯性的系统中,可以通过一系列脉冲的宽度进行调制,来等效获得需要的模拟参量,常用于电机控制等领域。

PWM参数:

1.频率:1s内信号从高电平到低电平再回到高电平的次数(一个周期),即1s内有多少个周期

1/Ts   (ts:一个周期时间)

2.占空比:Ton/Ts  高电平时间相对于整个周期时间的比例,占空比80%,一个周期内高电平占80%

3.分辨率:占空比变化步距  占空比变化的程度

输出比较模式:

模式       描述
冻结CNT=CCR时,REF保持为原状态
匹配时置有效电平CNT=CCR时,REF置有效电平
匹配时置无效电平CNT=CCR时,REF置无效电平
匹配时电平翻转CNT=CCR时,REF电平翻转
强制为无效电平CNT与CCR无效,REF强制为无效电平
强制为有效电平CNT与CCR无效,REF强制为有效电平
PWM模式1

向上计数:CNT<CCR,REF有效,CNT≥CCR,REF无效

向下计数:CNT>CCR,REF无效,CNT≤CCR,REF有效

PWM模式2

向上计数:CNT<CCR,REF无效,CNT≥CCR,REF有效

向下计数:CNT>CCR,REF有效,CNT≤CCR,REF无效

 

 蓝色线是CNT的值,黄色线是ARR的值,红色线是CCR的值。

PWM频率:Freq = CK_PSC/(PSC+1)/(ARR+1)

PWM占空比:Duty = CCR/(ARR+1)

PWM分辨率:Reso = 1/(ARR+1)

相关代码

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启定时器时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启GPIO时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;  //GPIO初始化
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //使用PWM需设置为复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_0;  //PA1 P10
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM2);  //TIM2使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; 
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 20000 - 1;		//ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;		//PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;  
	TIM_OCStructInit(&TIM_OCInitStructure);  //预设值
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  // 选择PWM1模式 
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //高电平触发
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //使能
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR寄存器的值  
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //初始化OC寄存器
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //可以同时配置多个通道
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
}

void PWM_SetCompare2(uint16_t Compare)  //修改CCR寄存器的值
{
	TIM_SetCompare2(TIM2, Compare);
	TIM_SetCompare1(TIM2, Compare);
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值