1. 关于STM32F1定时器
(1)STM32F1定时器
2 个基本定时器 (TIM6、TIM7):类似 51单片机内的定时器;
4 个通用定时器 (TIM2—TIM5):在基本定时器的基础上增加了输入捕获与输出比较等功能;
2 个高级定时器 (TIM1、TIM8):在通用定时器基础上增加了可编程死区互补输出、重复计数器和带刹车 (断路)功能。
(2)通用定时器功能
通用定时器是一个通过可编程预分频器PSC驱动的16位自动装载计数器。它适用于多种场合,能够进行输入捕获(测量输入信号的脉冲长度)、输出比较(生成输出波形)、生成PWM波形和单脉冲模式输出。
(3)定时器时钟选择
计数器时钟可由下列时钟源提供:
● 内部时钟(CK_INT),(通常选用此时钟源)
● 外部时钟模式1:外部输入脚(TIx)
● 外部时钟模式2:外部触发输入(ETR)
● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器
(4)计数器时钟频率
预分频器:预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。它是基于一个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器。这个控制寄存器带有缓冲器,它能够在工作时被改变。新的预分频器参数在下一次更新事件到来时被采用。
计数频率:定时器挂接在APB1总线上,而APB1总线时钟频率为36MHz。由于通用定时器的时钟是APB1时钟的2倍 (即72MHz),计数器时钟频率计算公式:fCK_CNT = fCK_PSC / (PSC[15:0]+1)
(5)产生中断/DMA请求的事件
①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发);②触发事件(计数器启动、停止、初始化或由内部/外部触发计数);③输入捕获;④输出比较
2. 通用定时器配置步骤
(1)使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
(2)初始化定时器参数
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
(3)设置定时器中断类型, 并清楚标志位
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
(4)设置定时器中断优先级, 使能定时器中断通道
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //TIM4中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; //抢占式优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //响应式优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure);
(5)开启定时器
TIM_Cmd(TIM4,ENABLE); //TIM4使能
(6)编写定时器中断服务函数
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==1) //定时器中断有很多个类型
{ //通过状态寄存器判断此中断类型
led1=!led1; //具体的中断操作
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清楚标志位
}
3. 定时器使用例程
//定时器4初始化函数
void TIMx_Init(u16 per, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //TIM4中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; //抢占式优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //响应式优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4,ENABLE);
}
//中断服务函数
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==1)
{
led2=!led2;
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
//main函数
int main(void)
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级2组
LED_Init();
TIMx_Init(1000,36000-1); //计时500ms
while(1);
}
1. 关于STM32F1定时器
(1)STM32F1定时器
2 个基本定时器 (TIM6、TIM7):类似 51单片机内的定时器;
4 个通用定时器 (TIM2—TIM5):在基本定时器的基础上增加了输入捕获与输出比较等功能;
2 个高级定时器 (TIM1、TIM8):在通用定时器基础上增加了可编程死区互补输出、重复计数器和带刹车 (断路)功能。
(2)通用定时器功能
通用定时器是一个通过可编程预分频器PSC驱动的16位自动装载计数器。它适用于多种场合,能够进行输入捕获(测量输入信号的脉冲长度)、输出比较(生成输出波形)、生成PWM波形和单脉冲模式输出。
(3)定时器时钟选择
计数器时钟可由下列时钟源提供:
● 内部时钟(CK_INT),(通常选用此时钟源)
● 外部时钟模式1:外部输入脚(TIx)
● 外部时钟模式2:外部触发输入(ETR)
● 内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器
(4)计数器时钟频率
预分频器:预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。它是基于一个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器。这个控制寄存器带有缓冲器,它能够在工作时被改变。新的预分频器参数在下一次更新事件到来时被采用。
计数频率:定时器挂接在APB1总线上,而APB1总线时钟频率为36MHz。由于通用定时器的时钟是APB1时钟的2倍 (即72MHz),计数器时钟频率计算公式:fCK_CNT = fCK_PSC / (PSC[15:0]+1)
(5)产生中断/DMA请求的事件
①更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发);②触发事件(计数器启动、停止、初始化或由内部/外部触发计数);③输入捕获;④输出比较
2. 通用定时器配置步骤
(1)使能定时器时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
(2)初始化定时器参数
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
(3)设置定时器中断类型, 并清楚标志位
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
(4)设置定时器中断优先级, 使能定时器中断通道
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //TIM4中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; //抢占式优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //响应式优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure);
(5)开启定时器
TIM_Cmd(TIM4,ENABLE); //TIM4使能
(6)编写定时器中断服务函数
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==1) //定时器中断有很多个类型
{ //通过状态寄存器判断此中断类型
led1=!led1; //具体的中断操作
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清楚标志位
}
3. 定时器使用例程
//定时器4初始化函数
void TIMx_Init(u16 per, u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
TIM_TimeBaseInitStructure.TIM_Period=per; //自动装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //预分频系数
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //时钟不分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //TIM4中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; //抢占式优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0; //响应式优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断通道
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4,ENABLE);
}
//中断服务函数
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==1)
{
led2=!led2;
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
//main函数
int main(void)
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级2组
LED_Init();
TIMx_Init(1000,36000-1); //计时500ms
while(1);
}
举报