您的位置 首页 动态

STM32单片机通用定时器的编程设计

STM32单片机通用定时器的编程设计-STM32系列的CPU,有多达8个定时器,其中TIM1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动,它们的时钟由APB2的输出产生。其它6个为普通定时器,时钟由APB1的输出产生。

一、STM32通用定时器原理

STM32系列的CPU,有多达8个定时器,其间TIM1和TIM8是能够产生三对PWM互补输出的高档定时器,常用于三相电机的驱动,它们的时钟由APB2的输出产生。其它6个为一般定时器,时钟由APB1的输出产生。

下图是STM32参考手册上时钟分配图中,有关定时器时钟部分的截图:

STM32单片机通用定时器的编程规划

从图中能够看出,定时器的时钟不是直接来自APB1或APB2,而是来自于输入为APB1或APB2的一个倍频器,图中的蓝色部分。

下面以通用定时器2的时钟阐明这个倍频器的效果:当APB1的预分频系数为1时,这个倍频器不起效果,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起效果,定时器的时钟频率等于APB1的频率两倍。

可能有同学仍是有点不理解,OK,咱们举一个比方阐明。假定AHB=36MHz,因为APB1答应的最大频率为36MHz,所以APB1的预分频系数能够取恣意数值;

当预分频系数=1时,APB1=36MHz,TIM2~7的时钟频率=36MHz(倍频器不起效果);

当预分频系数=2时,APB1=18MHz,在倍频器的效果下,TIM2~7的时钟频率=36MHz。

有人会问,已然需求TIM2~7的时钟频率=36MHz,为什么不直接取APB1的预分频系数=1?答案是:APB1不光要为TIM2~7供给时钟,并且还要为其它外设供给时钟;设置这个倍频器能够在确保其它外设运用较低时钟频率时。

Stm32外设用户手册,如图:

STM32单片机通用定时器的编程规划

再举个比方:当AHB=72MHz时,APB1的预分频系数有必要大于2,因为APB1的最大频率只能为36MHz。假如APB1的预分频系数=2,则因为这个倍频器,TIM2~7依然能够得到72MHz的时钟频率。能够运用更高的时钟频率,无疑提高了定时器的分辨率,这也正是规划这个倍频器的初衷。

二、STM32通用定时器编程

定时器编程,便是中止的编程。因为运用定时器必定要运用到中止。

进程一:RCC_Configuration();//设置体系时钟,包含时钟RCC的装备,倍频到72MHZ。

进程二:GPIO的装备,运用函数为GPIO_cfg();,该函数的完成如下:

voidGPIO_cfg()

{

GPIO_InitTypeDefGPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//挑选引脚6

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//输出频率最大50MHz

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//带上拉电阻输出

GPIO_Init(GPIOC,&GPIO_InitStructure);

}

实际上定时器的解说,不需求装备GPIO的引脚,仅仅咱们在定时器试验中,

运用每隔一秒点亮一次LED灯来做试验,所以需求装备对应GPIO的引脚。

进程三:嵌套中止控制器的装备,咱们照样运用函数NVIC_Config();仅仅初始化的进程略有不同。这儿咱们也把函数完成列出来:

从以上函数完成来看,实际上仅仅改动了结构体成员NVIC_IRQChannel的值,现在需求的通道是TIM2的通道,因而初始化值为TIM2_IRQChannel。从这儿也能够看出,这个函数实际上能够看做一个模型,能够拿去其他程序中改动后直接运用。

voidNVIC_cfg()

{

NVIC_InitTypeDefNVIC_InitStructure;

//挑选中止分组1

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

//挑选TIM2的中止通道

NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQChannel;

//抢占式中止优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

//呼应式中止优先级设置为0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

//使能中止

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

进程四:定时器的初始化装备,运用Timer_Config();。OK,要害部分出来了。

咱们来看下完成进程:

TIMER_cfg();//定时器的装备

//敞开定时器2

TIM_Cmd(TIM2,ENABLE);

voidTimer_Config(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

TIM_DeInit(TIM2);

TIM_TimeBaseStructure.TIM_Period=2000-1;//主动重装载寄存器的值

TIM_TimeBaseStructure.TIM_Prescaler=(36000-1);//时钟预分频数

TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//采样分频

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数形式

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

TIM_ClearFlag(TIM2,TIM_FLAG_Update);//铲除溢出中止标志

TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

TIM_Cmd(TIM2,ENABLE);/敞开时钟

}

咱们每个句子都来解释一下。首要咱们想运用定时器,就有必要使能定时器的时钟,这便是函数RCC_APB1PeriphClockCmd();,通过它敞开RCC_APB1Periph_TIM2。

TIM_DeInit(TIM2);该函数首要用于复位TIM2定时器,使之进入初始状况。

然后咱们对主动重装载寄存器赋值,TIM_Period的巨细实际上表明的是需求通过TIM_Period次计数后才会产生一次更新或中止。接下来需求设置时钟预分频数TIM_Prescaler,这儿有一个公式,咱们举例来阐明:例如时钟频率=72MHZ/(时钟预分频+1)。阐明当时设置的这个TIM_Prescaler,直接决议定时器的时钟频率。浅显点说,便是一秒钟能计数多少次。比方算出来的时钟频率是2000,也便是

一秒钟会计数2000次,而此刻假如TIM_Period设置为4000,即4000次计数后就会中止一次。因为时钟频率是一秒钟计数2000次,因而只需2秒钟,就会中止一次。

再往后的代码,还有一个需求留意的,TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;便是咱们一般选用向上计数形式,即每次计数就会加1,直到寄存器溢出产生中止停止。最终别忘了,需求使能定时器!!

产生中止时刻=(TIM_Prescaler+1)* (TIM_Period+1)/FLK

用上述公式可算出:产生中止时刻 (2000-1+1)*(36000-1+1)/72000000=1 秒

进程五:编写中止服务程序。相同需求留意的,一进入中止服务程序,第一步要做的,便是铲除去中止标志位。因为咱们运用的是向上溢出形式,因而运用

的函数应该是:TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);。

STM32开发板完成的中止服务程序如下:

每隔一秒,产生中止时,进入此中止函数履行程序,让LED闪一下,此中止程序地点文件stm32f10x_it.c

*FunctionName:TIM2_IRQHandler

*Description:ThisfunctionhandlesTIM2globalinterruptrequest.

*Input:None

* Output : None
来历;21ic

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/dongtai/344077.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部