7、STM32-定时器(定时中断内外时钟源选择功能)

一、STM32定时器简介

(1) 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
(2) 16位计数器、预分频器、自动重装寄存器 的时基单元,在 72MHz 计数时钟下可以实现  最大 59.65s 的定时。
(3) 不仅具备基本的 定时中断功能 ,而且还包含 内外时钟源选择 输入捕获 输出比较 编码器接口 主从触发模式 等多种功能。
(4) 根据复杂度和应用场景分为了 高级定时器 通用定时器 基本定时器 三种类型。

二、STM32定时器类型

(1)基本定时器框图

   (2)通用定时器框图

        (3)高级定时器(与通用比较)

  三、定时中断基本结构

四、预分频器时序

                              计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

五、定时器定时中断代码

        (1)恢复缺省配置

           void TIM_DeInit(TIM_TypeDef* TIMx);

        (2)时基单元初始化*

           void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef*                                                  TIM_TimeBaseInitStruct);

         (3)把结构体变量付一个默认值

            void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

          (4)使能计数器

            void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

           (5)使能中断输出信号

             void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

            (6)选择内部时钟

              void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

            (7)选择ITRX其他定时器的时钟

              void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t                                                                         TIM_InputTriggerSource);

            (8)选择TIx捕获通道时钟

                void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t                 TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);

             (9)选择ETR通过外部时钟模式1的时钟

               void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,                                                                       uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);

            (10)选择ETR通过外部时钟模式2的时钟

                void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx,uint16_t TIM_ExtTRGPrescaler,                                                                      uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

               (11)改写预分频值

               void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t                                                           TIM_PSCReloadMode);

            (12)改变计数器计数模式

               void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

            (13)自动重装器预装功能配置

              void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

            (14)给计数器写入一个值

              void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

            (15)给自动重装器写一个值

              void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

            (16)获取当前计数器的值

               uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

            (17)获取当前预分频器的值

              uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

            (18)获取标志位与清楚标志位

               void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
              ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
              void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

            (19)代码编写

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

 uint16_t Num=0;
void TimerInit(void);

int main(void)
{
	TimerInit();
  OLED_Init();

	while(1)
	{

		OLED_ShowNum(1,7,Num,5);
		
	}

}


/***************************************************************
  *  @brief void TimerInit(void)   
  *  @param void       
  *  @note  初始化中断引脚  
  *  @Sample TimerInit();  
 **************************************************************/
void TimerInit(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	NVIC_InitTypeDef NVIC_InitStruct;
	
  TIM_InternalClockConfig(TIM2);//选用内部时钟
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式
	TIM_TimeBaseInitStruct.TIM_Period=10000-1;//周期ARR自动重装载值
	TIM_TimeBaseInitStruct.TIM_Prescaler=7200-1;//PSC预分频器的值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器的值
	//定时频率=72M/(PSC+1)*(ARR+1)
	//定时时间=1/[72/(PSC+1)]*(ARR+1)
  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断
  
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;//中断通道
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择分组2
	NVIC_Init(&NVIC_InitStruct);
	
  TIM_Cmd(TIM2,ENABLE);//启动定时器
	
}

/***************************************************************
  *  @brief   void TIM2_IRQHandler()  
  *  @param   void     
  *  @note    定时器中断函数
  *  @Sample  无 
 **************************************************************/
void TIM2_IRQHandler()
{
	if( TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//判断中断标志位是否被置一
	{
	Num++;
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
	
}

六、定时器外部时钟代码

#include "stm32f10x.h"                  // Device header
#include "OLED.h"

 uint16_t Num=0;
void TimerInit(void);
uint16_t TimerGetCounter(void);


int main(void)
{
	TimerInit();
  OLED_Init();

	while(1)
	{

		OLED_ShowNum(1,7,Num,5);
		
	}

}


/***************************************************************
  *  @brief void TimerInit(void)   
  *  @param void       
  *  @note  初始化中断引脚  
  *  @Sample TimerInit();  
 **************************************************************/
void TimerInit(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	NVIC_InitTypeDef NVIC_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0X00);//选用外部ETR模式2时钟
	
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//指定时钟分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;//计数器模式
	TIM_TimeBaseInitStruct.TIM_Period=10-1;//周期ARR自动重装载值
	TIM_TimeBaseInitStruct.TIM_Prescaler=1-1;//PSC预分频器的值
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;//重复计数器的值
	//定时频率=72M/(PSC+1)*(ARR+1)
	//定时时间=1/[72/(PSC+1)]*(ARR+1)
  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断
  
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;//中断通道
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//选择分组2
	NVIC_Init(&NVIC_InitStruct);
	
  TIM_Cmd(TIM2,ENABLE);//启动定时器
	
}

uint16_t TimerGetCounter(void)
{
	
	return TIM_GetCounter(TIM2);
	
}


/***************************************************************
  *  @brief   void TIM2_IRQHandler()  
  *  @param   void     
  *  @note    定时器中断函数
  *  @Sample  无 
 **************************************************************/
void TIM2_IRQHandler()
{
	if( TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//判断中断标志位是否被置一
	{
	Num++;
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
	
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是stm32高级定时器TIM1的定时中断配置代码示例: ``` // 定时器配置 TIM_HandleTypeDef htim1; TIM_OC_InitTypeDef sConfigOC; htim1.Instance = TIM1; htim1.Init.Prescaler = 0; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 999; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } // 定时中断配置 HAL_NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn); HAL_TIM_Base_Start_IT(&htim1); // 中断处理函数 void TIM1_UP_TIM10_IRQHandler(void) { HAL_TIM_IRQHandler(&htim1); } void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM1) { // 定时器中断处理代码 } } ``` 这个示例代码中,我们使用了STM32 HAL库进行定时器配置和定时中断配置。其中,`htim1`是一个`TIM_HandleTypeDef`结构体,用于存储定时器的相关配置信息。`sConfigOC`是一个`TIM_OC_InitTypeDef`结构体,用于存储定时器输出比较(PWM)的相关配置信息。 在定时中断配置部分,我们使用了HAL库提供的函数`HAL_NVIC_SetPriority()`和`HAL_NVIC_EnableIRQ()`来配置定时器中断优先级和使能定时中断。同时,我们也使用了HAL库提供的函数`HAL_TIM_Base_Start_IT()`来启动定时器,并且使能定时中断。 在中断处理函数`TIM1_UP_TIM10_IRQHandler()`中,我们调用了HAL库提供的函数`HAL_TIM_IRQHandler()`来处理定时器中断。在`HAL_TIM_PeriodElapsedCallback()`回调函数中,我们可以编写定时器中断处理代码。 需要注意的是,这个示例代码中的定时器时钟为APB2总线,如果需要使用其他时钟或者其他定时器,请根据具体情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值