目录
时钟的选择及分频
定时器中断有关的寄存器
定时器中断有关的库函数
1.时钟使能函数:RCC_APB1PeriphClockCmd
2.定时器初始化函数:TIM_TimeBaseInit
3.定时器中断使能 / 选择函数:TIM_ITConfig
4.NVIC配置函数:NVIC_Init
5.定时器使能函数:TIM_Cmd
6.中断服务函数:TIM3_IRQHandler
一般情况定时器的始终会选择来自系统的内部时钟,由AHB时钟经APB1预分频再经历一系列操作得来的。而对于通用定时器来说,如果APB1预分频系数为1,即AHB经过APB1产生的时钟并未分频,此时需要乘于1输出;否则乘于2输出
而通常情况下我们APB1的时钟是36M的,经过系统时钟预变频而来,所以我们选择的是X2输出,即通用定时器时钟CK_INT是72M,CK_INT经时钟预分频因子转换后就可以得出CK_CNT
我们得到CN_CNT时钟后,需要使能才能让其工作。当它工作后,我们可以实现让相应的计数寄存器开始计数,直至到达我们的预装载值时就溢出,产生中断。
因此,一次溢出的时间Tout(us)可以由以下的公式计算得来:
Tout= ((arr+1)*(psc+1))/Tclk
其中Tclk为输入定时器的时钟频率,单位为(Mhz),psc+1就是预分频系数,所以Tclk/(psc+1)得到的就是定时器的时钟频率,倒数就是定时器的一个时钟周期,乘上预装载值就是一次达到预装载值需要几个周期,即从0达到预装载值的时间
1.TIMx_CNT:这个寄存器是作为计数器当前值的记录器,记录当前的计数器的数值;
2.TIMx_PSC:这个寄存器用来配置预分频因子的值(CK_CNT=fck_psc/[PSC[15:0]+1]);
3.TIMx_ARR:这个寄存器用来配置自动重装载值,即计数器的触发时间的地方;
4.TIMx_CR1:这个寄存器用来控制计数模式和使能计数器;
5.TIMx_DIER:这个寄存器用来使能中断;
在说定时器中断有关的库函数之前,先来梳理一下实现定时器中断操作的步骤;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
这个函数有两个参数,第一个参数是要使能的时钟,第二个参数是确定使能
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
它有两个参数,第一个是要初始化的定时器,第二个是配置定时器相关参数功能的结构体
这个结构体有五个成员,
uint16_t TIM_Prescaler;
uint16_t TIM_CounterMode;
uint16_t TIM_Period;
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
第一个成员是TIM_Prescaler,它是设置TIM定时器的预分频系数即PSC
第二个成员是TIM_CounterMode,它表示计数方式的选择
第三个成员是TIM_Period,它表示定时器预装载值的大小
第四个成员是TIM_ClockDivision,它设置时钟分割
第五个成员是TIM_RepetitionCounter,它我还没用到.....
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
它有三个参数,第一个是选择中断使能的定时器,第二个是中断发生方式,第三个是使能
NVIC_Init(&NVIC_InitStructure);
这个函数用于配置中断的优先级,它的参数是一个结构体,它的成员用于配置中断的模式
uint8_t NVIC_IRQChannel;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
FunctionalState NVIC_IRQChannelCmd;
第一个成员是 uint8_t NVIC_IRQChannel; ,它用于选择配置哪一个定时器的中断
第二个成员是 uint8_t NVIC_IRQChannelPreemptionPriority; ,它用于配置抢占优先级
第三个成员是 uint8_t NVIC_IRQChannelSubPriority; ,它用于配置响应优先级
第四个成员是FunctionalState NVIC_IRQChannelCmd; ,它用于使能通道
并且要记得设置中断优先级分组!!(如配置分组2)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)
TIM_Cmd(TIM3, ENABLE);
这个函数比较简单,就是使能定时器即可,第一个参数是定时器的名称,第二个参数是使能命令
这个函数用于写产生中断后需要做的操作,例如我们可以让LED闪一下或者蜂鸣器响之类的操作
void TIM3_IRQHandler(void)
其中,在中断服务函数内部我们也需要增加一些判断,例如判断是否真的产生中断。这里我们使用函数:TIM_GetITStatus
它有两个参数,第一个是定时器,第二个是中断形式
TIM_GetITStatus(TIM3, TIM_IT_Update)
它用于获取中断的标志位,如果产生了中断,它的标志位就会变成1(SET)。
当完成一次操作后,我们需要人为手动将其标志位清0(RESET),这时需要函数:
TIM_ClearITPendingBit
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
它也有两个参数,第一个也是定时器,第二个也是中断的形式。