STM32入门12讲 (3)定时器的概念和应用

 基本定时器分为三个部分
(1)时钟源:时钟源来自RCC的TIMXCLK,就是内部时钟(CK_INT)直接经过控制器传给时基单元充当CK_PSC
(2)控制器:控制定时器的复位、使能、计数、DAC触发
(3)时基单元(最基本的计数计时电路):
a、预分频器:分频、得到计时器的时钟,即CNT计数1次所需要的时间,预分频器时16位的寄存器、所以可分频为1-65536
b、计数器:用来计数、基本定时器的CNT计数器只能向上计数
c、自动装载寄存器ARR:CNT加到ARR的值之后,会产生一个事件或中断或DMA请求,中断用得比较多

预分频器
基本定时器只能选择内部时钟,故预分频器直接输入端,即内部时钟CK_INT(一般为72MHz)

预分频器(PSC)写0(1分频或者不分频):则SK_CNT输出72MHz,

写1(2分频):输出36MHz,写2(3分频):输出24MHz

故实际分频系数=预分配系数+1(分频器是16位,故最大位65525)

计数器


对预分频后的计数时钟进行计数,计数时钟每来一个上升沿,计数器的值就+1,计数器是16位的,故当中的值可为0~65535,65535后若再加,则又从0开始。

计数器计数到目标值后,就会产生中断

时基单元模块箭头

向上折线箭头:会产生中断信号,像计数值等于自动重装值时产生的中断,一般叫做更新中断,更新中断后会通向NVIC,我们再配置好NVIC的定时器通道,那定时器的更新中断就能得到CPU的响应

向下的箭头:代表会产生一个事件,称为"更新事件",更新事件不会触发中断,但可以触发内部其他电路的工作
简单说,定时器只需要知道。定时频率=72M/(预分频器+1)/(ARR+1)

代码演示
#include "stm32f10x.h"  // 包含STM32固件库的头文件

void Timer_Init(void)
{
	// 第一步:RCC开启时钟
	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自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;  // PSC预分频器的值
	// 预分频对72M进行7200分频,得到10K的计数频率,在10k的频率下,计数10k个数,就是1s
	// 可以预分频给少点,自动重装给多一点,这样就是以一个比较高的频率计比较多的数,反之则反
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;  // 重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

	// 第四步:配置输出中断控制,允许更新中断输出到NVIC
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);  // 清除向上溢出中断标志
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // 使能更新中断

	// 第五步:配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 选择分组2

	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  // 中断通道,定时器2的通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  // 设置抢占优先级为2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  // 设置响应优先级为1
	NVIC_Init(&NVIC_InitStructure);

	// 第六步:启动定时器
	TIM_Cmd(TIM2, ENABLE);
}

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"
 
uint16_t Num;
 
int main(void)
{
	OLED_Init();
	Timer_Init();
	
	OLED_ShowString(1, 1, "Num:");
	
	while (1)
	{
		OLED_ShowNum(1, 5, Num, 5);
		OLED_ShowNum(2, 5, TIM_GetCounter(TIM2), 5);//计数器的值
		
	}
}
 
 
//对于定时中断而言,中断函数就是为别的文件服务的,故可以移到别的文件中使用
void TIM2_IRQHandler(void)
{
	//获取中断标志位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值