8、STM32定时器原理与使用(内附代码)

                                            STM32定时器原理与使用

1.定义

设置等待时间,到达等待时间之后执行指定的硬件操作。

定时器最基本的功能就是定时,比如说定时发送串口数据,定时采集AD数据,也可以产生PWM方波等,定时器产生PWM控制电机状态是工业控制的普通。


2、STM32F4xx系列的芯片:2个高级控制定时器(TIM1和TIM8)、10个通用定时器(10TIM2-TIM5,TIM9-TIM14)、2个基本定时器(TIM6和TIM7)、2个看门狗定时器

具体可参考中文参考手册了解其特性及原理

8、STM32定时器原理与使用(内附代码)_第1张图片


3、定时器计数模式:

通用定时器可以向上计数、向下计数、向上向下双向计数模式。

①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

如图:

8、STM32定时器原理与使用(内附代码)_第2张图片


4、通用定时器工作原理:

● 计数器寄存器 (TIMx_CNT)

● 预分频器寄存器 (TIMx_PSC)

● 自动重载寄存器 (TIMx_ARR)

假如是向上增长模式,计数器(CNT)从0加到自动重载值(ARR),预分频器(PSC)减一次。

时间计算方式:

假设频率为:42M*2 == 84M == 84000000 == 1s //42根据定时器时钟数可知 并且一般都是*2

定时器定时1s产生中断:

ARR = 84000; // 1ms

PSC = 1000; // 1000*1ms == 1s

 

如图:可知基本定时器的时钟是42M,那么对应*2就是84M=84000000=1S(ARR*PSC)

       高级的既是84*2=96M=96000000=1S

8、STM32定时器原理与使用(内附代码)_第3张图片


5、定时器中断实现步骤 

//5.1、能定时器时钟。
    RCC_APB1PeriphClockCmd();

//5.2、初始化定时器,配置ARR,PSC。(申明结构体)
    TIM_TimeBaseInit();

  typedef struct
  {
    uint16_t TIM_Prescaler;
    uint16_t TIM_CounterMode;
    uint16_t TIM_Period;
    uint16_t TIM_ClockDivision;
    uint8_t TIM_RepetitionCounter;
  } TIM_TimeBaseInitTypeDef;



//5.3、启定时器中断,配置NVIC(申明结构体)
    NVIC_Init();

    进行NVIC中断配置

    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);// ④初始化 NVIC
    TIM_Cmd(TIM3,ENABLE); //⑤使能定时器 3

//5.4、设置 TIM3_DIER 允许更新中断
    TIM_ITConfig();

//5.5、使能定时器。
    TIM_Cmd();

//5.6、编写中断服务函数。
    TIMx_IRQHandler();

//定时器 3 中断服务函数
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
    {
        /*处理的程序段*/
    }

    TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}

TIM3_Int_Init(5000-1,8400-1);	//定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms

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);  //清除中断标志位
}

--------------------------------------------------------------------------END--------------------------------------------------------------------------------

 

你可能感兴趣的:(STM32,STM32)