您现在的位置是:首页 >学无止境 >TIM-定时器——STM32网站首页学无止境
TIM-定时器——STM32
简介TIM-定时器——STM32
TIM-定时器——STM32
TIM(Timer)定时器
定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。
即使我在计数中途改变了预分频值,计数频率仍然会保持为原来的频率,直到本轮计数完成,在下一轮计数时,改变后的分频值才会起作用。
带一个黑色阴影的寄存器,都是有影子寄存器这样的的缓冲机制的。
引入这个影子寄存器的目的实际上是为了同步,就是让值的变化和更新事件同步发生,防止在运行途中更改造成错误,
中断定时器配置步骤
第一步,RCC开启时钟
第二步,选择时基单元的时钟源
第三步,配置时基单元
第四步,配置输出中断控制,允许更新中断输出到NMIC
第五步,配置NVIC,在NMIC中打开定时器中断的通道,并分配一个优先级
第六步,就是运行控制了
#include "stm32f10x.h" // Device header
//exten声明变量,就是告诉编译器,现在有Num这个变量,e
//它在别的文件里定义了,用户跨文件使用变量
extern uint16_t Num;
void Timer_Intial(void)
{
//第一步开启时钟,初始化RCC,选择TIM2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//第二步选择时基单元的时钟,选择内部时钟,选择TIM2
TIM_InternalClockConfig(TIM2);
//第三步配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数 1分频
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数的模式 向上计数
//计数器溢出频率:CK CNT_OV = CKCNT /(ARR + 1)= CK PSC /(PSC + 1)/(ARR +1)
//配置定时为1s,则CK CNT_OV=1;CKCNT=72MHz=72000000;
TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;//周期,ARR自动重装器的值 范围0~65536
TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1;//PSC预分频器的值 范围0~65536
TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //重复计数器的值 高级计数器才有
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
//第四步配置输出中断
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//更新中断
//清除中断标志位,能够避免刚初始化完就进中断的问题
TIM_ClearFlag(TIM2,TIM_IT_Update);
//第五步,配置NVIC
//注意:分组方式整个芯片只能用一种,因此,分组的代码只需要执行一次
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择中断分组
//初始化NVIC
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
//第六步,运行控制
TIM_Cmd(TIM2,ENABLE);
}
//定时器的中断函数
void TIM2_IRQHandler(void)
{
//首先检查一下中断标志位
if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
{
Num++;
//清除标志位
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
#ifndef _TIMER_H
#define _TIMER_H
void Timer_Intial(void);
#endif
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "KEY.h"
#include "Timer.h"
uint16_t Num;
int main(void)
{
while(1)
{
}
}
如何使用跨文件的变量,在中断函数中使用
第一种解决方案,就是使用跨文件的变量,用extern声明即可
第二种解决方案,就是将中断函数剪切到主函数,和变量在同一个文件夹下。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。