通用定时器及定时器中断实验

发布时间 2023-12-20 22:27:44作者: 潘守登

定时器:顾名思义是用来定时的一个外设。stm32有八个定时器,分三类

计数器计数模式又分为三种:向上,向下,向上/下计数。

向上:计数器从零计数到自动加载值,然后重新从零开始并产生一个计数器溢出事件。

向下:计数器从自动加载值计数到零,然后重新从自动加载值开始并产生一个计数器溢出事件。

向上/下计数:计数器从零计数到自动加载值并产生一个计数器溢出事件,从自动加载值计数到零并产生一个计数器溢出事件。

 

通用定时器功能:

第四个应用少。

DMA:直接存储器访问。

作用:将数据从一个地址栏空间复制到另一个地址空间。实现外设与存储器之间的高速数据传输,或者是存储器间的高速数据传输。

定时器工作过程:

 

分为四个模块:时钟产生模块,输入捕捉模块,寄存器模块,输出比较模块。

1,定时器时钟源来源很多TIMx_ETR(外部引脚),CK_INT(内部时钟),ITR(来自其他定时器),因为定时器间可以级联,其他定时器输出可以为此底定时器输入,TI1FP1,TI1FP2.

2,寄存器模块:从产生的时钟经过预分频器,进入计数器,开始计数。

3,输入捕捉模块:通过边沿检测器捕捉输入。

4,输出比较模块:例如:计数器值在变化,与比较寄存器中的值比较,大于输出高电平,小于输出低电平。

 

 

定时器中断实验:

原理:计数时,会产生计数器溢出事件,而后更新事件,这触发中断(更新中断标志位)

工作过程:1,选择时钟:除非APB1的分频系数是1,否则通用定时器时钟为APB1时钟的2倍。(84M)

                   使能定时器时钟

                 函数:RCC_APB1PeriphClockCmd();

             2,初始化定时器:TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//第一个参数为哪个定时器,第二个为初始化结构体。

TIM_TimeBaseInitStruct.TIM_ClockDivision//
TIM_TimeBaseInitStruct.TIM_CounterMode//定时器模式
TIM_TimeBaseInitStruct.TIM_Period//自动重装值
TIM_TimeBaseInitStruct.TIM_Prescaler//分频系数

 

中断时间计算公式:

Tout= ((arr+1)*(psc+1))/Tclk;

3,使能定时器

TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)//第一个参数为哪个定时器,第二个为是否使能

4,开启定时器中断,配置NVIC

TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)//开启定时器中断函数

配置NVIC不赘述

5,编写中断服务函数

TIMx_IRQHandler()

注意写完要实现的功能记得清除中断状态标志位(回到程序)。

 

 

 

 

完整代码:

void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟

TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
LED1=!LED1;//DS1翻转
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}