STM32F103共有8个16位定时器,分别为TIM0~TIM7。其中TIM6、TIM7是基本定时器,TIM2、TIM3、TIM4和TIM5是通用定时器,而TIM1和TIM8是高级定时器。还有一个SysTick定时器.
1:先介绍下SysTick定时器:
SysTick定时器是存在于系统内核的一个滴答定时器,只要是ARM Cortex-M0/M3/M4/M7内核的MCU都包含这个定时器,它是一个24位的递减定时器,当计数到 0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。使用内核的SysTick定时器来实现延时,可以不占用系统定时器,由于和MCU外设无关
在core_cm3.h文件中,SysTick_Config函数包含了SysTick定时器初始化,配置初始计数值,使能中断,使能定时器等。
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
对应的中断函数为:
u32 GlobelTime;
void SysTick_Handler(void)
{
GlobelTime++;// 通常在这里定义一个全局变量++
}
如果想要SysTick定时器每1ms中断一次,则需要
SysTick_Config(SystemCoreClock / 1000); //定时1ms
2 通用定时器(定时器5举例):
/*定时时间计算:
Tout= ((arr+1)*(psc+1))/Tclk;
arr:计数重装值,psc分频数,Tclk系统时钟频率,Tout一个周期的时间。
Tout=1000*72/72000000 = 0.001s*/
如下是定时器5初始化与中断函数得配置:
void TIM5_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //1分频
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //设置定时器5
TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清除溢出中断标志位
TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE); //使能TIM5溢出中断
TIM_Cmd(TIM5,DISABLE); //先关闭TIM5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_Cmd(TIM5, ENABLE); //使能TIMx外设
}
//定时器5中断服务程序
void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM5, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
}
}