江协科STM32 6-1定时器中断详解与代码剖析
江协科STM32 6-1定时器中断 代码详讲
引言:STM32主要是通过库函数来配置寄存器,所以了解库函数是很重要的事情,此博客主要讲以下两点:1.如何查看并且运用库函数,2.定时器中断代码中Timer.c、代码详讲。
一. 查看运用库函数
-
查看库函数变量以及用法:
假设我们要查看
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
此句函数是如何使用的,它有什么变量,我们只需要1.选中此句函数。2.点击黄色方框“Go To Defination …”
当我们点击此选项之后,就会跳转到此函数对应库中的声明此函数的部分(分为俩部分1.注释部分、2.函数声明部分)如果之后我们想查找定义的变量,只需要选中那个变量并且再按ctrl+f快捷键,就可以找到此变量的定义或者是它出现在哪个函数当中。
- 注释部分:
建议下载一个能在线翻译的词典,使用起来稍微方便一点。up使用的有道词典只需要选中文字之后就可以翻译出来了。
由翻译结果可以知道,此函数是开启APB1的外设时钟的,并且可以在args中选择我们要使用的组合,然后使之使能即可。
- 函数声明部分
二. Timer.c代码详讲
- 代码部分:
#include "stm32f10x.h" // Device header
extern uint16_t Num;
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=10000-1;
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
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_Cmd(TIM2,ENABLE);
}
void TIM2_IRQHandler(void){
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){
Num++;
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
因为此部分的代码和之前5-2中螺旋计数器的代码类似,所以只挑我认为的重点讲,其他部分代码配置的部分如果有不懂的部分请跳转:江协科STM32 5-2旋转编码器计次 代码详讲-CSDN博客
- 详讲部分
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启TIM2的外设时钟
TIM_InternalClockConfig(TIM2);//配置TIM2中的外设时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义一个结构体来配置寄存器
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟划分,一共有3个选项,在此代码中选择第一个,不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//调整计数器模式为向上计数模式
TIM_TimeBaseInitStructure.TIM_Period=10000-1;//指定要加载到活动的周期值,在下一次更新事件时自动重新加载寄存器
TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1;//指定用于划分TIM时钟的预分频器值。
TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//指定重复计数的值
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除TIM2的中断挂起位,更新中断,到指定位溢出时会触发中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//启用TIM2的中断
重点:
-
预分频值以及自动重载值的计算:
公式:
其中:
FCK_CNT:定时器的输入时钟频率(即 CK_INT
,通常为系统主频或APB总线时钟为72MHz)。
PSC:预分频值(TIM_Prescaler
),范围 0x0000
~ 0xFFFF
(即 0~65535)。
ARR:自动重载值(TIM_Period
),范围 0x0000
~ 0xFFFF
(即 0~65535)。
所以将已知的值带入得:
预分频后时钟:720072MHz=10kHz
每次计数时间:10kHz1=0.1ms
总定时时间:10000×0.1ms=1000ms=1秒
按照我理解的就是分频就是确定每次计数的时间,自动重载就是确定次数。
扩展:
-
STM32定时器(TIM)的时钟分频因子:
作用:配置定时器的 时钟分频(CKD),用于调整数字滤波器和死区时间的采样时钟频率。不改变定时器实际计数频率(
CK_CNT
),仅影响抗噪声能力。宏定义 值(二进制) 分频系数 适用场景 TIM_CKD_DIV1
0x0000
1 高精度场景(如高速PWM) TIM_CKD_DIV2
0x0100
2 平衡精度与抗噪性(如电机控制) TIM_CKD_DIV4
0x0200
4 高噪声环境(如开关电源) -
计数器模式定义:
-
TIM_CounterMode_Up
:计数器向上计数模式(从0递增到自动重装载值) -
TIM_CounterMode_Down
:计数器向下计数模式(从自动重装载值递减到0) -
TIM_CounterMode_CenterAligned1/2/3
:中央对齐模式(三种不同的中央对齐计数方式)
递增到自动重装载值) -
TIM_CounterMode_Down
:计数器向下计数模式(从自动重装载值递减到0) -
TIM_CounterMode_CenterAligned1/2/3
:中央对齐模式(三种不同的中央对齐计数方式)
作者:xuan_lili