定时器(Timer)

1.时钟
时钟就是一个可以产生周期性信号的设备。
时钟信号就是周期性变化的信号。

T:时钟周期 最小重复的信号单元的时间长度,基本单元为s(秒)
F:时钟频率 1s内有多少个重复的信号单元,单位为Hz
--->T * F = 1

2.为什么需要时钟?
时钟的最主要的目的是为了同步信号。
设备之间的同步是通过时钟信号来进行的。
3.时钟信号是怎么产生的?
在自然界中有一些物体天生就会产生摆动(振动)–>石英晶体
如果想利用石英晶体规则地、周期性的产生方波信号,需要一些电路来保证,如 晶振电路:频率一般比较小,如:12M、8M…
但是晶振电路难以满足现代计算机的高频需求,如:CPU它的频率就会很高。

分频/倍频电路:
	分频:把输入频率变小
	倍频:把输入频率变大

4.STM32F4xx时钟树(时钟系统)

关键词:
	HSE:High Speed External 高速外部时钟 (晶振电路8MHz)
	HSI:High Speed Internal 高速内部时钟 (16MHz RC振荡器)
	LSE:Low Speed External 	低速外部时钟 (32.768KHz)
	LSI:Low Speed Internal	低速内部时钟 (32KHz RC振荡器)

内部时钟:由内部集成的RC震荡电路产生
外部时钟:由晶振产生
SYSCLK(系统时钟频率168MHz) = PLLCLK(锁相环时钟)

位于APB1总线上的定时器的频率42M * 2 = 84MHZ
位于APB2总线上的定时器的频率84M * 2 = 168MHZ

*5.定时器(Timer)
定时器就是用来定时的器件
在STM32上,一般来说,定时器由三部分组成:
1)时基单元(Time Base Unit)

定时器的基本单元,所有的定时器都会具备的单元。

时基单元的工作原理:

将计数器设置为一个值按照一定的时钟频率递减到0,或者按照一定的时钟
频率从0递增到某个值,当计数器溢出后,可以产生一个溢出事件/中断以
此来达到定时的功能。

时基单元 = 计数器 + 重载计数值寄存器 + 定时器预分频器

a.	定时器预分频器Timex_PSC
		用来将定时器的总线时钟进行分频,提供一个合适的频率给计数
器去计数。分频系数介于1到65536之间,是一个16位的寄存器。
b.	重载计数值寄存器Timx_ARR
		用来设定计数值(N值)。如果自动重装载寄存器的值为0,则计数
器停止。
c.	计数器Timx_CNT
		按照预分频器给它提供的频率,从0递增到N,或者从N递减到0,
并且可以在溢出后,产生定时器中断/事件。

比如:假设Timex是位于APB1总线上,那么Fin = 84MHz,一般情况下,为了方便计算,将Timex_PSC设置为83。

 Tcnt = 1/Fcnt = (Timex_PSC + 1) / Fin = (83 + 1)/84M = (10^-6)s = 1us
产生定时器中断的时长t = (N + 1)us

时基单元

2)输入捕获单元
可以对一个或者多个输入信号进行处理。
有些定时器不具备输入捕获单元。

	具体能够捕获多少个输入信号需要看你的定时器有几个通道Channel。
	功能:比如可以计算输入信号的频率

3)输出比较单元
可以输出一个或者多个信号
有些定时器是没有输出比较单元

	具体能够输出多少个信号,就需要看你的定时器有几个通道Channel。
	输出比较:
		主要是用于输出PWM波。
		定时器可以向对应的GPIO引脚(复用功能)输出一个电平状态。
		并且可以根据输出比较寄存器的值,来翻转输出的电平状态。

6.STM32F4xx定时器概述
1)SysTick
时钟嘀嗒定时器–>系统定时器

	在M3/M4中都会内置一个在NVIC中的SysTick定时器。这个定时器
只有时基单元。并且溢出的时候,会产生SysTick中断,执行中断处理函数
SysTick_Handler

为什么需要这样的一个定时器?

	因为大多数的操作系统,都需要一个硬件定时器来产生操作系统需要
的时钟嘀嗒中断,主要用于操作系统计时。

SysTIck定时器作为整个系统的基本的时间单元。
SysTick被集成在NVIC中,他可以产生SysTick中断,其实就是一个简单的24bit的递减定时器,它可以运行在处理器的时钟主频(168MHz)上,也可以运行在外部时钟(8MHz)上。
时钟滴答定时器

寄存器配置步骤:
	a.	Disable SysTick(禁止SysTick)
		将Control and Status寄存器中的bit0-->0
	b.	选择时钟源
		将Control and Status寄存器中的bit2:
			1:168M的系统时钟    <---	  0:8M外部时钟	
	c.	使能中断
		将Control and Status寄存器中的bit1:
		1:SysTick中断使能	0:SysTick中断禁止
	d.	设置N值和计数初值
	e.	Enable SysTick(使能SysTick)

2)基本定时器(TIM6/TIM7)
只有时基单元,没有输入捕获单元/输出比较单元(无输入输出引脚)。

16位自动重装载递增计数器
用途:只能用于定时器中断

3)通用定时器
TIM2~TIM5 / TIMT9 ~TIM14,共10个
TIM2~TIM5

TIM3/TIM4(16bit)、TIM2/TIM5(32bit)计数器。
计数模式可以由软件配置成:
	递增(0-->N)、递减(N-->0)、先递增再递减(0-->N-->0)
多达4个独立通道(可以有4个GPIO引脚复用),可以由软件配置成:
			— 输入捕获
			— 输出比较
			— PWM 生成(边沿和中心对齐模式)
			— 单脉冲模式输出

TIM9~TIM14

16bit的计数器,只能递增计数。
2个独立通道,可以由软件配置成:
			— 输入捕获
			— 输出比较
			— PWM 生成(边沿对齐模式)
			— 单脉冲模式输出

用途:

a.用于定时器中断			--> 配置时基单元
b.用于捕获输入信号	    -->	配置时基单元 + 输入捕获单元
c.用于输出特定的信号(PWM)--> 配置时基单元 + 输出比较单元

4)高级定时器(TIM1 TIM8)

16bit计数器,递增、递减、递增/递减计数。	
多达 4 个独立通道,可用于:
		— 输入捕获
		— 输出比较
		— PWM 生成(边沿和中心对齐模式)
		— 单脉冲模式输出

重复计数器(Timx_RCR):Repeation Counter Register

	如果使用了重复计数,则当计数器重复溢出次数达到了设定的重复
计数器的值+1后才会产生定时器溢出/中断。
	如果不使用重复计数器,在每次计数器溢出后都会产生中断/事件。	
此时就跟通用定时器没什么区别。

5)看门狗 Watch Dog
看门狗的作用就是当系统卡死(跑飞了)之后,会产生复位中断(Reset_Handler)。但是看门狗只不过是忽略了卡死的现象,它并不能帮你解决卡死的问题。

看门狗的原理:
	相当于一个定时器,当定时器的计数溢出后,就会产生溢出中断,这
个中断产生后,就会去执行RESET复位中断服务函数。

看门狗的实现:
1.初始化配置看门狗,比如设置初始值为N
	配置好之后,系统启动同时看门狗也开始运行,就会从N开始递减(从0
开始递增),当减到溢出的时候,就会CPU复位。所以正常情况下,不能让
看门狗减到0,那么为了避免在正常的情况下,看门狗减到0,需要喂狗。
			
2.周期性的喂狗(重置定时器计数值)
比如:假设看门狗的定时时间为50ms。
意味着如果不做任何处理的话,每过50ms产生复位中断。
你必须每隔 < 50ms的时间就必须喂狗一次,以避免它产生复位中断。

喂狗的话不能采用定时器中去喂狗:
	因为定时器中断无论是CPU是否跑飞,都会在溢出后产生中断,用定时
器喂狗,会导致看门狗失去效果。

7.STMF4xx固件库中定时器相关的函数
1)定时器时基单元配置

a.使能定时器时钟总线(定时器都处于APB1或者APB2总线上)
	 RCC_APB1P...
	 RCC_APB2P...
b.初始化定时器时基单元
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)

2)定时器中断配置
当要使用定时器中断时,则需要配置由哪种方式触发定时器中断。

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)
//用于指定触发定时器中断的方式

3)NVIC配置
同时写一个定时器对应的中断服务函数
4)使能定时器

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

输出比较
不同的定时器有2~4个独立的通道,每一个通道都是由GPIO复用而来。因此,如果需要使用输出比较(输入捕获)的话,则需要事先配置通道对应的GPIO(AF模式)口。输入捕获和输出比较因为使用的是同一个寄存器,所以两者不能同时使用。

输出比较的实现步骤:
1.初始化GPIO控制器
	1.1 使能GPIO分组时钟
	1.2 初始化GPIO口(AF模式)
	1.3 配置GPIO复用功能
	void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
2.配置定时器时基单元
	2.1 使能定时器时钟总线(定时器都处于APB1或者APB2总线上)
	2.2 初始化定时器时基单元
3.配置输出比较器(各个通道是可以独立配置)
void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)
4.使能定时器
	TIM_Cmd
	
设置输出比较寄存器的值:
	void TIM_SetCompare1(TIM_TypeDef* TIMx, uint32_t Compare1);
	void TIM_SetCompare2(TIM_TypeDef* TIMx, uint32_t Compare2);
	void TIM_SetCompare3(TIM_TypeDef* TIMx, uint32_t Compare3);
	void TIM_SetCompare4(TIM_TypeDef* TIMx, uint32_t Compare4);

输入捕获

  • 2
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
Linux 定时器 timer_list 是一个内核数据结构,用于管理内核中的定时器。它是一个双向链表,每个节点表示一个定时器timer_list 的定义位于 `<linux/timer.h>` 头文件中。 每个 timer_list 节点的定义如下: ```c struct timer_list { struct list_head entry; // 定时器节点的链表指针 unsigned long expires; // 定时器的到期时间 void (*function)(unsigned long); // 定时器回调函数 unsigned long data; // 传递给回调函数的参数 struct tvec_base *base; // 定时器所属的时间轮 int slack; // 定时器的松弛时间 }; ``` 其中,`entry` 是一个 `list_head` 结构,用于将节点连接到定时器链表中。`expires` 表示定时器的到期时间,以 jiffies 单位表示。`function` 是定时器的回调函数,在定时器到期时被调用。`data` 是传递给回调函数的参数。`base` 表示定时器所属的时间轮,`slack` 是定时器的松弛时间,用于处理定时器的精度。 在使用 timer_list 时,可以使用以下函数进行初始化和操作: - `timer_setup(struct timer_list *timer, void (*function)(unsigned long), unsigned int flags)`:初始化一个定时器,并指定回调函数和标志。 - `init_timer(struct timer_list *timer)`:初始化一个定时器。 - `add_timer(struct timer_list *timer)`:将定时器添加到定时器链表中。 - `del_timer(struct timer_list *timer)`:从定时器链表中删除定时器。 - `mod_timer(struct timer_list *timer, unsigned long expires)`:修改定时器的到期时间。 这些函数可以通过 `<linux/timer.h>` 头文件中的宏来调用。通过操作 timer_list,可以实现在 Linux 内核中的定时器功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_60265426

都是好兄弟

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值