一、时钟选择
计数器时钟可由下列时钟源提供:
内部时钟(CM_INT)
外部时钟模式1:外部输入脚(TIx)
外部时钟模式2:外部触发输入(ETR)
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如果可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频处理

二、计数模式
向下计数模式(时钟分频因子=1)

向上计数模式(时钟分频因子=1)

中央对其计数模式(时钟分频因子=1 ARR=6)

三、定时器常用寄存器和库函数
定时器参数初始化:
void TIM_TimeBaseInit(TIM_TypeDef*
TIMx, TIM_TimeBaseInitTypeDef*
TIM_TimeBaseInitStruct);
typedef struct
{
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
}
TIM_TimeBaseInitTypeDef;
定时器使能函数:
void TIM_Cmd(TIM_TypeDef*
TIMx, FunctionalState NewState);
定时器中断使能函数:
void TIM_ITConfig(TIM_TypeDef*
TIMx, uint16_t TIM_IT, FunctionalState NewState);
状态标志位获取和清除:
FlagStatus TIM_GetFlagStatus(TIM_TypeDef*
TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef*
TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef*
TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef*
TIMx, uint16_t TIM_IT);
四、定时器中断实现步骤:
使能定时器时钟。
RCC_APB1PeriphClockCmd();
初始化定时器,配置ARR,PSC.
TIM_TimeBaseInit();
开启定时器中断,配置NVIC
void TIM_ITConfig();
NVIC_Init();
使能定时器
TIM_Cmd();
编写中断服务函数
TIMx_IRQHandler();
例:
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
NVIC_InitTypeDef
NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//时钟使能
//定时器3初始化
TIM_TimeBaseStructure.TIM_Period = arr;
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc;
//设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
// 使能TIM3中断,允许更新
//NVIC 设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
//TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
//初始化NVIC寄存器
TIM_Cmd(TIM3, ENABLE);
//使能TIMx
五、案例
程序要求:通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED1实现LED1状态取反
Tout(溢出时间) = (ARR+1)(PSC+1)/Tclk
main文件
#include “stm32f10x.h”
#include “delay.h”
#include “key.h”
#include “timer.h”int main(void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_Int_Init(4999,7199);
KEY_Init();
while(1)
{
LED1 = !LED1;
delay_ms(200);
}
}
timer文件
#include “timer.h”
#include “key.h”
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE); }void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{
LED1 = !LED1;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
timer.h文件
#ifndef __TIMER_H
#define __TIMER_H
#include “sys.h”
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
key文件
#include “key.h”void KEY_Init() //IO³õʼ»¯{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
key.h文件
#ifndef __KEY_H
#define __KEY_H
#include “sys.h”
#define LED1 PAin(0)
#define KEY1 PEin(4)
void KEY_Init(void);
#endif
一、时钟选择
计数器时钟可由下列时钟源提供:
内部时钟(CM_INT)
外部时钟模式1:外部输入脚(TIx)
外部时钟模式2:外部触发输入(ETR)
内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如果可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频处理

二、计数模式
向下计数模式(时钟分频因子=1)

向上计数模式(时钟分频因子=1)

中央对其计数模式(时钟分频因子=1 ARR=6)

三、定时器常用寄存器和库函数
定时器参数初始化:
void TIM_TimeBaseInit(TIM_TypeDef*
TIMx, TIM_TimeBaseInitTypeDef*
TIM_TimeBaseInitStruct);
typedef struct
{
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
}
TIM_TimeBaseInitTypeDef;
定时器使能函数:
void TIM_Cmd(TIM_TypeDef*
TIMx, FunctionalState NewState);
定时器中断使能函数:
void TIM_ITConfig(TIM_TypeDef*
TIMx, uint16_t TIM_IT, FunctionalState NewState);
状态标志位获取和清除:
FlagStatus TIM_GetFlagStatus(TIM_TypeDef*
TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef*
TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef*
TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef*
TIMx, uint16_t TIM_IT);
四、定时器中断实现步骤:
使能定时器时钟。
RCC_APB1PeriphClockCmd();
初始化定时器,配置ARR,PSC.
TIM_TimeBaseInit();
开启定时器中断,配置NVIC
void TIM_ITConfig();
NVIC_Init();
使能定时器
TIM_Cmd();
编写中断服务函数
TIMx_IRQHandler();
例:
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
NVIC_InitTypeDef
NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
//时钟使能
//定时器3初始化
TIM_TimeBaseStructure.TIM_Period = arr;
//设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc;
//设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
//TIM向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
//初始化TIM3
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
// 使能TIM3中断,允许更新
//NVIC 设置
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
//TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);
//初始化NVIC寄存器
TIM_Cmd(TIM3, ENABLE);
//使能TIMx
五、案例
程序要求:通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED1实现LED1状态取反
Tout(溢出时间) = (ARR+1)(PSC+1)/Tclk
main文件
#include “stm32f10x.h”
#include “delay.h”
#include “key.h”
#include “timer.h”int main(void)
{
delay_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
TIM3_Int_Init(4999,7199);
KEY_Init();
while(1)
{
LED1 = !LED1;
delay_ms(200);
}
}
timer文件
#include “timer.h”
#include “key.h”
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef
TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE); }void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{
LED1 = !LED1;
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
timer.h文件
#ifndef __TIMER_H
#define __TIMER_H
#include “sys.h”
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
key文件
#include “key.h”void KEY_Init() //IO³õʼ»¯{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
key.h文件
#ifndef __KEY_H
#define __KEY_H
#include “sys.h”
#define LED1 PAin(0)
#define KEY1 PEin(4)
void KEY_Init(void);
#endif
举报