概念
什么是定时器,简单而言,定时器就是用来做时间定时的,一般我们生活中可以看到的定时器的例子有秒表和闹钟,这两样就是我们经常能够见到的定时器案例。
定时器一共有14个,可以分成三类,这三类一般分成基本定时器(TIM6、TIM7)、通用定时器(TIMx)、高级控制定时器(TIM1、TIM8)。
再者,我们先从最简单的基本的定时器开始,
这里是基本定时器的几个功能,前三个功能构成了这个定时器的主要功能。
特性
由于通用定时包含了基本定时器的所有功能,所以这里介绍通用定时器就好了,高级定时器的话,比较复杂,这里先不详诉,后面会进行系统的总结。另外,我们这一块板子(M4)性能不支持基本定时器如果没有基本定时器那么我们想使用基本的定时功能应该怎么做?--- 使用更高一级的定时器.
通用定时器详解
计数器---16位---0~65535
计数模式 向上计数
向下计数
中央对齐
预分频-----时钟频率----72Mhz----1s-72M
重装载值-----2^16---0~65535
设置定时器1秒溢出
如何计算定时时间 如何定时一秒?
假设预分频系数为72 那么定时器计数频率为1M 计一个数1us 16位的定时器最大可以计65535us = 65ms (us级别)
假设预分频系数为720 那么定时器计数频率为100k 计一个数10us 16位的定时器最大可以计655350us = 655ms (百ms级别)
假设预分频系数为7200 那么定时器计数频率为10k 计一个数100us 16位的定时器最大可以计6553500us = 6553ms (秒级别)
定时器溢出公式:Tous(s) = (arr+1) *(psc+1) /Ft
Tous(s) = (arr+1) *(psc+1) /Ft = Tous(s) = (9999+1) *(7199+1) /72M= 1
最大重装载值不变 (定时器的位数) 预分频系数越大 最大定时时间越久
假设PSC为任意值 只要ARR结果不超过65535即可。
三种定时器之间的区别
TIM1和TIM8定时器的功能包括【增强型】:
● 16位向上、向下、向上/下自动装载计数器
● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值
● 多达4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出
● 死区时间可编程的互补输出
● 使用外部信号控制定时器和定时器互联的同步电路
● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获 ─ 输出比较─ 刹车信号输入
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
TIMx主要功能通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括【通用型】:
● 16位向上、向下、向上/向下自动装载计数器
● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值
● 4个独立通道: ─ 输入捕获 ─ 输出比较 ─ PWM生成(边缘或中间对齐模式) ─ 单脉冲模式输出
● 使用外部信号控制定时器和定时器互连的同步电路
● 如下事件发生时产生中断/DMA: ─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发) ─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) ─ 输入捕获 ─ 输出比较
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
TIM6和TIM7定时器的主要功能包括【精简型】:
● 16位自动重装载累加计数器
● 16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536之间的任意数值分频
● 触发DAC的同步电路 注:此项是TIM6/7独有功能.
● 在更新事件(计数器溢出)时产生中断/DMA请求
代码实现
1:添加TIM3时钟
2:使用基本定时器配置
3:使能定时器中断 这样定时溢出的时候就会产生溢出更新中断
4: 配置NIVC 使用自然优先级默认
5:使能TIM3定时器进行工作
6:编写定时器中断服务函数
7:主函数调用TIM3初始化开始定时
tim.c
#include "Time.h"
u32 time_ms=0,time_us=0;
void Time_Init(u8 time)
{
SysTick->CTRL =0;
time_us =time/8;
time_ms =time_us*1000;
}
void delay1_ms(u16 time)
{
u8 i=0,j=0;
i=time/500;
j=time%500;
if(j!=0)
{
SysTick->LOAD =time_ms*j;
SysTick->VAL =0;
SysTick->CTRL |=1<<0;
while((SysTick->CTRL&(1<<16))==0);
SysTick->CTRL &=~(1<<0);
}
while(i!=0)
{
SysTick->LOAD =time_ms*500;
SysTick->VAL =0;
SysTick->CTRL |=1<<0;
while((SysTick->CTRL&(1<<16))==0);
SysTick->CTRL &=~(1<<0);
i--;
}
}
void delay1_us(u16 time)
{
SysTick->LOAD =time_us*time;
SysTick->VAL =0;
SysTick->CTRL |=1<<0;
while((SysTick->CTRL&(1<<16))==0);
SysTick->CTRL &=~(1<<0);
}
tim.h
#ifndef __TIME_H
#define __TIME_H
#include "stm32f4xx.h"
void Time_Init(u8 time);
void delay1_ms(u16 time);
void delay1_us(u16 time);
#endif