目录
1、使能定时器时钟
2、设置定时器时钟频率
3、配置定时器结构体参数
4、配置中断结构体
5、使能定时器中断源中断
6、使能定时器
7、编写中断函数
本文章对基本定时器的定时做一个简单的介绍,并贴出相应的源码以及注释,方便新手进行学习参考。
//使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
//设置系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//设置AHB时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1); //72Mhz
//设置APB1时钟(如果TIM时钟不为APB的1分频 频率X2)
RCC_PCLK1Config(RCC_HCLK_Div4); //72Mhz
此处需要注意的是如果TIM的时钟频率部位APB1时钟的1分频的时候TIM的时钟频率会自动X2详情参考时钟树
提到时钟树这里插入一个题外话,此处提供一个获取STM32时钟频率的函数,供大家在配置时钟频率的时候进行检查配置是否正确
//建议放在配置完时钟函数后使用 并进行单步调试看时钟结构体中的频率
RCC_ClocksTypeDef RCC_CLKInitStructure;
RCC_GetClocksFreq(&RCC_CLKInitStructure);
// //设置定时器时钟与数字滤波器使用的采样频率之间的分频比(基本定时器可以忽略)
// TIM_InitStructure.TIM_ClockDivision=TIM_CKD_DIV2;
//设置定时器计数模式 (定时器向上计数模式根据定时器配置)
TIM_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
//设置自动重装载寄存器周期值
TIM_InitStructure.TIM_Period=arr; //设置计数到5000溢出
//设置时钟频率的预分频值
TIM_InitStructure.TIM_Prescaler=psc;//设置计数频率
// //配置重复结构体(普通定时器不需要配置只需要在高级定时器中使用)
// TIM_InitStructure.TIM_RepetitionCounter=0x00;
//初始化TIM结构体
TIM_TimeBaseInit(TIM6,&TIM_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//使能update中断
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
//使能定时器
TIM_Cmd(TIM6,ENABLE);
//编写定时器6中断函数
void TIM6_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM6,TIM_IT_Update); //清除TIM6中断源标志位
LED0=!LED0;
}
}
定时器溢出时长Tout=(arr+1)*(psc+1)/Tclk
void TIM_InitConfig(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_InitStructure;
//使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
//设置定时器时钟(根据时钟树进行配置)
//设置系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//设置AHB时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1); //72Mhz
//设置APB1时钟(如果TIM时钟不为APB的1分频 频率X2)
RCC_PCLK1Config(RCC_HCLK_Div4); //72Mhz
// //设置定时器时钟与数字滤波器使用的采样频率之间的分频比(基本定时器可以忽略)
// TIM_InitStructure.TIM_ClockDivision=TIM_CKD_DIV2;
//设置定时器计数模式 (定时器向上计数模式根据定时器配置)
TIM_InitStructure.TIM_CounterMode=TIM_CounterMode_Up;
//设置自动重装载寄存器周期值
TIM_InitStructure.TIM_Period=arr; //设置计数到5000溢出
//设置时钟频率的预分频值
TIM_InitStructure.TIM_Prescaler=psc;//设置计数频率
// //配置重复结构体(普通定时器不需要配置只需要在高级定时器中使用)
// TIM_InitStructure.TIM_RepetitionCounter=0x00;
//初始化TIM结构体
TIM_TimeBaseInit(TIM6,&TIM_InitStructure);
//使能update中断
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
//使能定时器
TIM_Cmd(TIM6,ENABLE);
//定时器溢出计算公式
//Tout=((arr+1)*(psc+1))/Tclk;
//Tout=(5000)*(7200)/72000000=0.5s
}
void NVIC_InitGonfig(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel=TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//编写定时器6中断函数
void TIM6_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6,TIM_IT_Update)!=RESET)
{
TIM_ClearITPendingBit(TIM6,TIM_IT_Update); //清除TIM6中断源标志位
LED0=!LED0;
}
}
main函数的调用函数如下
int main(void)
{
NVIC_InitGonfig();
TIM_InitConfig(49999,7199);
while(1)
{
}
}
后续研究之后为大家更新利用高级定时器产生PWM波以及正弦波,感谢各位观看谢谢。