最近学习完了STM32系列单片机,所以准备对所学习的知识进行总结,以便以后查阅。
文章的单片机以
MCU:STM32F103C8T6
标准准库:V3.5.0
开发环境:Keil5
STM32F103C8T6 - Timer定时器中断
定时器分类
在STM32中定时器分为高级定时器、通用定时器、基本定时器三种。
高级定时器:
由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。
它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。
通用定时器:
由一个通过可编程预分频器驱动的16位自动装载计数器构成。
它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
基本定时器:
包含一个16位自动装载计数器,由各自的可编程预分频器驱动。
它们可以作为通用定时器提供时间基准,特别地可以为数模转换器(DAC)提供时钟。实际上,它们在芯片内部直接连接到DAC并通过触发输出直接驱动DAC。
一、初始化定时器
STM32最高主频72MHZ,APB1操作速度限于36MHz,APB2操作速度限于(最高72MHz)。在计算定时器时间时,需要在数据手册查看定时器外设在那一条总线上。
这里以初始化定时器2为例:
ARR :自动重载值最大值为65535
PSC : 预分频系数
TCLK :TIM 输入时钟频率(MHZ)为定时器挂载的总线时钟速度
例现在我们定时5ms中断一次
定时器2挂载在APB1总线上,所以TCLK = 36MHZ
PSC:我们取36
那计算的频率就为36MHZ/36 = 1MHZ,以后1MHZ计算一次就为1us,所以ARR就为5000
5ms=((ARR-1)*(PSC-1))/Tclk
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 启动时钟
TIM_InternalClockConfig(TIM2); // 选择内部时钟
// 定时器结构体参数
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; // 计数器模式 向上计数
TIM_TimeBaseInitStructure.TIM_Period = 5000 - 1;
TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); // 初始化定时器
// 优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 中断通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearFlag(TIM2, TIM_FLAG_Update); // 清除定时器标志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); // 定时器配置
// 启动定时器
TIM_Cmd(TIM2, ENABLE);
}
定时器中断函数
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}