参考海创STM32视频。
一、定时器简介
F103系列单片机最多有8个定时器,分为高级定时器、通用定时器和基本定时器。
计数器类型
- 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
- 向下计数模式:计数器从自动加载值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
- 中心对齐模式:计数器从0开始计数到(TIMx ARR-1),产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件。
时钟源→控制器→时基单元
若我们需要溢出时间(1s)
晶振振动一个周期的时间:(PSC+1)/fck
振动的次数:arr+1(从0开始计数,所以要加1)
晶振振动一个周期的时间*振动的次数=溢出时间
溢出时间=(PSC+1)(arr+1)/fck
在上一节中
TIM3_Init()函数两个参数分别是arr和psc。
(7199+1)/72 000 000hz*(9999+1)=1s
二、定时器配置
以TIME3定时为例。
- 使能定时器时钟 RCC_APB1PeriphClockCmd();
- 初始化定时器 TIM_TimeBaseInit();
- 定时器中断配置 TIM_ITConfig();
- 使能定时器 TIM_Cmd();
- 编写中断服务函数 TIM3_IRQHandle();
TIM_GetITStatus(TIM3,TIM_IT_Update); //判断状态寄存器
返回值只能为0或1。
RESET = 0; SET = 1
判断返回值是否为1,为1则发生中断。
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除标志位
三、定时器3功能实现
timer3.h
#ifndef __TIMER3_H__
#define __TIMER3_H__
#include "stm32f10X.h"
void TIM3_Init(u16 arr,u16 psc);
#endif
timer3.c
#include "timer3.h"
/********************
①使能定时器时钟。
RCC_APB1PeriphClockCmd();
②初始化定时器,配置ARR,PSC。
TIM_TimeBaseInit();
③开启定时器中断,配置NVIC。
void TIM_ITConfig();
NVIC_Init();
④使能定时器。
TIM_Cmd();
⑥编写中断服务函数。
TIMx_IRQHandler();
*****************/
void TIM3_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStruct;//定义结构体变量
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;//所选中断源
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority =2;//子优先级/响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
}
void TIM3_IRQHandler(void) //TIM3中断
{
static u8 i =0 ;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
switch (i)
{
case 0:GPIO_ResetBits(LED_GPIO_PORT, LED_GPIO_PIN);i++;break;
case 1:GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);i=0;break;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
}
}