一、STM32定时器资源介绍
TIMXCLK来源:


简化理解:

- 2个基本定时器(类似于51单片机中的定时器)
- 4个通用定时器TIM2~4(每个定时器可输出4路PWM控制舵机等)
- 两个高级定时器
二、工程实现
新建文件夹及文件:

C文件添加到工程组中:

包含头文件路径:

添加定时器相关库文件到工程组中:

移除不必要的工程组文件:
exti.c key.c
定时器中断使用步骤:
1.初始化配置:
-
使能TIM时钟,定时器外设是挂在APB1总线上的
-
TIM_TimeBaseInit初始化(配置计时时间、计数模式)
-
使用定时器的某个中断类型作为NVIC的中断(如TIM_IT_Update更新中断)
-
TIM_ClearITPendingBit清除 TIM 的中断待处理位
-
初始化NVIC(设置两组优先级)
-
TIM_Cmd开启定时器
2.中断服务函数实现: -
TIM_GetITStatus检查指定的 TIM 某一类型中断发生与否
-
中断发生则实现具体操作
-
清除 TIM 的指定中断待处理位,函数退出
time.h#ifndef __TIME_H
#define __TIME_H#include "system.h"
void TIM4_Init(u16 per, u16 psc);
#endif
time.c
#include "time.h"
void TIM4_Init(u16 per, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//1.使能时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟,定时器外设是挂在APB1总线上的
//2.初始化TIM
//中断触发时间T = 自动重装载寄存器值per * 计数一次对应的时间 = 自动重装载寄存器值per * ((psc+1)/(CLK))s,其中CLK为72M。
//以500ms为例:T = 1000 * ((35999+1)/(72000000))s = 1000 * (1/2000)s = 0.5s = 500ms
//TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在 0x0000 和0xFFFF 之间。这里由参数传入
TIM_TimeBaseStructure.TIM_Period = per;
//TIM_Prescaler 设置了用来作为 TIMx 时钟频率除数的预分频值。它的取值必须在 0x0000 和 0xFFFF 之间,即设置分频系数
TIM_TimeBaseStructure.TIM_Prescaler = psc;
//这里一般配置为TIM_CKD_DIV1
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//计数模式设置为向上计数
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
//3.开启定时器中断,即使用定时器4的更新中断作为NVIC的中断源,如计数器到达设定自动重装载寄存器值时,触发更新中断
TIM_ITConfig(TIM4,TIM_IT_Update, ENABLE);
//4.清除 TIM4 的中断待处理位
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
//5.初始化NVIC
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //在"stm32f10x.h"查看
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级设为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级设置为2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
//6.开启定时器
TIM_Cmd(TIM4, ENABLE);
}
//实现中断服务函数
void TIM4_IRQHandler(void)
{
//检查指定的 TIM4 TIM_IT_Update更新中断发生与否
if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
{
PCout(1) = !PCout(1); //LED2状态取反
}
//清除 TIM4 的更新中断待处理位
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
main.c
#include "system.h" //已经包含了"stm32f10x.h" 以及定义了位带操作的宏,后续只包含该头文件就可以了
#include "SysTick.h" //使用delay_ms和delay_us
#include "key.h"
#include "led.h" //需要调用Led_Init()对8个LED GPIO初始化
#include "time.h" //TIM4_Init()调用
//这里不用定义SystemInit函数,是因为在system_stm32f10x.c中已有实现
int main()
{
u8 i = 0;
SysTick_Init(72); //72为SYSCLK delay_ms延时函数需要使用
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组2:2 在使用中断回调函数时都需要调用
Led_Init();
////以500ms为例:T = 1000 * ((35999+1)/(72000000))s = 1000 * (1/2000)s = 0.5s = 500ms
TIM4_Init(1000, 35999); //定时器4初始化以及实现中断回调
while(1)
{
i++;
if(i%20 == 0)
{
PCout(4) = !PCout(4); //LED5状态取反 20*10ms = 100ms
}
delay_ms(10);
}
}
编译烧录验证:LED2每隔500ms交替闪烁。