STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器。
本节学习通用定时器 TIM3
STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。
STM3 的通用 TIMx (TIM2、 TIM3、 TIM4 和 TIM5)定时器功能包括:
1)16 位向上、向下、向上/向下自动装载计数器( TIMx_CNT)。
2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~
65535 之间的任意数值。
3) 4 个独立通道( TIMx_CH1~4),这些通道可以用来作为:
A.输入捕获
B.输出比较
C. PWM 生成(边缘或中间对齐模式)
D.单脉冲模式输出
4)可使用外部信号( TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外
一个定时器)的同步电路。
5)如下事件发生时产生中断/DMA:
A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
C.输入捕获
D.输出比较
E.支持针对定位的增量(正交)编码器和霍尔传感器电路
F.触发输入作为外部时钟或者按周期的电流管理
本实验是实现TIM3的更新中断。
TIM3相关配置文件 timer.c
#include "led.h" #include "timer.h" //arr:自动重装值。 //psc:时钟预分频数 void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_ist; NVIC_InitTypeDef NVIC_ist; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //①时钟 TIM3 使能 //定时器 TIM3 初始化 TIM_ist.TIM_Period = arr; //设置自动重装载寄存器周期的值 TIM_ist.TIM_Prescaler =psc; //设置时钟频率除数的预分频值 TIM_ist.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割 TIM_ist.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数 TIM_TimeBaseInit(TIM3, &TIM_ist); //②初始化 TIM3 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //③允许更新中断 NVIC_ist.NVIC_IRQChannel=TIM3_IRQn; NVIC_ist.NVIC_IRQChannelPreemptionPriority=0; NVIC_ist.NVIC_IRQChannelSubPriority=3; NVIC_ist.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_ist); TIM_Cmd(TIM3, ENABLE); //⑤使能 TIM3 } //中断服务程序 void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除 TIM3 更新中断标志,(<span style="color:#ff6600;">很重要的</span>) LED1=!LED1; } }
定时器的溢出时间计算公式如下:
Tout(溢出时间)= ((arr+1)*(psc+1))/Tclk;
Tclk为TIM3 的输入时钟频率(单位为 Mhz)(72Mhz)。
假如我们传入的参数为arr=4999 psc=7199 得到的溢出时间为500ms 意味着每500ms变会触发一次更新中断(LED1闪烁)当TIM3溢出后就会重新加载0,然后在向上计数(在初始化函数中选了向上计数模式)直到溢出后又会发生更新中断。。
timer.h
#ifndef _TIMER_ #define _TIMER_ #include "sys.h" void TIM3_Int_Init(u16 arr,u16 psc); void TIM3_IRQHandler(void); #endif
主函数
#include "led.h" #include "sys.h" #include "timer.h" #include "delay.h" #include "usart.h" void init(void) { delay_init(); LED_Init(); NVIC_Configuration(); uart_init(9600); TIM3_Int_Init(4999,7199);//溢出时间为500ms } int main(void) { init(); while(1) { LED0=!LED0; delay_ms(250); } }
最终会看到LED0和LED1 一直闪烁,但LED0的闪烁频率比LED1高(一倍)