STM32共有8个定时计数器,
高级定时器: TIME1 TIME8
是通用定时器:TIME2~TIME5
基本定时器: TIME6和TIME7
以TIME3通用定时器为例总结定时计数器的基本用法
一:TIM3时钟使能
APB1外设时钟使能寄存器(RCC_APB1ENR)
Eg:RCC->APB1ENR|=1<<1; //使能TIM3时钟
二:设置TIM3_ARR和TIM3_PSC的值
通过这两个寄存器来设置自动重装的值以及分频系数
自动重装载寄存器(TIMx_ARR)
预分频器(TIMx_PSC)
三:设置TIM3_DIER允许更新中断
中断使能寄存器(TIMx_DIER)
Eg: TIM3->DIER|=1<<0; //允许更新中断
四:允许TIM3工作
控制寄存器1(TIMx_CR1)
CEN:使能计数器 位0 0:禁止计数器; 1:使能计数器
Eg: TIM3->CR1|=0x01; //使能定时器3
或 TIM3->CR1|=1<<0;
五:TIM3中断分组设置
直接调用MY_NVIC_Init()函数
Eg:MY_NVIC_Init(1,3,TIM3_IRQChannel,2);//抢占1,子优先级3,组2
六:编写中断服务函数
状态寄存器(TIMx_SR)
Eg: if(TIM3->SR&0X0001)//溢出中断
Eg: //定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3_Int_Init(5000,7199); //10Khz的计数频率,计数到5000为500ms//500ms中断一次
{
if(TIM3->SR&0X0001) //溢出中断
{
//add your code
}
TIM3->SR&=~(1<<0); //清除中断标志位
}
六:关于溢出事件的计算
因为Stm32_Clock_Init函数里面已经初始化APB1的时钟为2分频,所以APB1的时钟是32MHz(系统时钟72MHz)。
从STM32内部时钟树图可知:
当APB1的时钟分频数为1时,TIM2~7的时钟为APB1的时钟;
而如果APB1的时钟分频数不为1,那么TIM2~7的时钟频率是APB1时钟的两倍。
因此TIM3的时钟为72MHz,再根据arr和psc即可计算中断时间
Tout = ( (arr+1) * (psc+1) ) / Tclk
其中,Tclk为TIM3的输入时钟频率(单位:MHz)。
Tout为TIM3的溢出时间(单位:us)。
Eg:void TIM3_Int_Init(u16 arr,u16 psc)----->TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms
Tout = (5000 * 7200)/72 = 500,000us = 500ms
示例程序
//定时器3中断服务程序
void TIM3_IRQHandler(void) //TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms
//500ms中断一次
{
if(TIM3->SR&0X0001)//溢出中断
{
LED1=!LED1; 9 }
TIM3->SR&=~(1<<0);//清除中断标志位
}
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器设置
TIM3->DIER|=1<<0; //允许更新中断
TIM3->CR1|=0x01; //使能定时器3
MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2
}
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,9600); //串口初始化
LED_Init(); //初始化与LED连接的硬件接口
TIM3_Int_Init(5000,7199);//10Khz的计数频率,计数到5000为500ms
while(1)
{
LED0=!LED0;
delay_ms(200);
}
}