单片机中的定时器主要用于控制时间,比如延时、定时等等。而计数器则主要用于统计事件或脉冲信号的数量。通过控制定时器和计数器的中断、清零等操作,我们可以完成各种复杂的定时、计数等操作,实现更加智能化的控制系统。
单片机的定时器一般由计数器、预分频器、中断控制器、基准时钟等部分组成。在使用定时器之前需要对定时器进行初始化设置,通常包括预分频、计数器值、启动定时器等步骤。在运行时,单片机通过定时器的计数达到一定值后触发中断,并执行相应的程序。
STM32F103ZET6的定时器分类
三个定时器的主要功能和区别
定时器的核心参数
定时器时钟源 72MHZ
预分频寄存器(TIMx_PSC) 预分频器的工作的工作原理是,定时器时钟源每tick一次,预分频器计数器值+1,直到达到预分频器的设定值,然后再tick一次后计数器归零,同时,CNT计数器值+1。 如果我们想获取一个精确的1ms中断,如果不分频,72MHz的时钟对应每周期1/72us,十分不利于计算。这时候使用预分频器将其72分频后为1MHz,每周期1us,1000个计时周期即为1ms,这样既便于计算,定时也更加精确。
计数器寄存器(TIMx_CNT)
比较值:PWM1模式、PWM2模式
计数方式:向上计数、向下计数、中心计数
定时时间计算
其中ARR为自动重装载的值(0—65535),tick为定时器时钟源。
定时器的时钟源
时钟树分析:
在我们进行初始化时,我们会选择外部晶振,但是提供的是内部时钟源,并不是外部时钟源,在最右侧,内部时钟源主频72MHZ 经过分频器和倍频给各个外设和APB总线分配时钟,而我们的定时器的外设是挂载到APB1和APB2上面的。
我们来看一下系统架构清楚看到TIM1和TIM8挂载在APB2,TIM2-TIM7挂载在APB1
系统架构:
时钟树:
实验内容
通过定时器使一个LED灯每隔1s亮一次,另一个LED每隔2s亮一次,串口每隔5秒打印一次系统运行时间。
配置过程
1.定时器时钟源选择(选择内部时钟源)
2.定时器参数配置
预分频设置,根据上面定时器定时器公式,要想我们定时器中断每一秒触发一次,我们需要对定时器时钟72MHZ进行分频处理,进行7200-1分频。进行换算得计数器每计数一次的时间为100us=0.0001s(也可以其他分频处理,那么计数周期也要改变)
计数模式:向上计数
计数周期同分频器计算一样,计算得10000-1。
Auto-reload preload 自动重装载 使能一下
3.使能中断.因为我们是普通的中断,选择第二就行。
4.串口设置。我们需要串口打印,所以我们要配置串口
5.LED的配置不再阐述。(普通GPIO)
生成代码分析
初始化定时器参数,设置自动重装值,分频系数,计数方式,选择内部时钟等。
使能中断优先级。
生成对应的中断触发函数
我们进入HAL_TIM_IRQHandler()函数,发现这里调用了HAL_TIM_PeriodElapsedCallback函数这个回调函数。
我们只是配置了定时器,并没有打开定时器,所以我们首先要打开定时器
HAL_TIM_Base_Start_IT()函数,这个函数调用__HAL_TIM_ENABLE_IT这个宏,这个宏使能了中断。
实验代码:
初始化变量
使能定时器
While(1)中进行串口打印操作
回调函数
代码分析
类似与51单片机定时器,定义一个变量Time_Count,中断每(1秒)触发一次,使Time_Count+1;这样很轻松使两个LED,一个一秒亮一次,另一个两秒亮一次,问题是串口怎样每5秒打印一次,回调函数中不允许有延时函数,所以我们可以控制变量Flag,使串口每5秒打印一次。
标签:分频,定时器,HAL,中断,stm32,计数,计数器,时钟 From: https://blog.csdn.net/best_xo/article/details/140373218