STM32定时器定时及其应用

定时器概述

  • 1. 工作原理
    使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器

  • 2. 定时器分类
      基本定时器(TIM6~TIM7)
      通用定时器(TIM2~TIM5)
      高级定时器(TIM1和TIM8)

    定时器类型主要功能
    基本定时器没有输入输出通道,常用作时基,即定时功能
    通用定时器具有多路独立通道,可用于输入捕获/输出比较,也可用作时基
    高级定时器除具备通用定时器所有功能外,还具备带死区控制的互补信号输出刹车输入等功能
  • 3. STM32F103C8T6资源

  • 4. 通用定时器介绍

    1. 16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT)。
    2. 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
    3. 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
       A.输入捕获
       B.输出比较
       C.PWM 生成(边缘或中间对齐模式)
       D.单脉冲模式输出
    4. 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
    5. 如下事件发生时产生中断/DMA:
       A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
       B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
       C.输入捕获
       D.输出比较
  • 5. 定时器计数模式

    计数模式计数器溢出值计数器重装值
    向上计数CNT = ARRCNT = 0
    向下计数CNT = 0CNT = ARR
    中心对齐计数CNT = ARR - 1CNT = ARR
    CNT = 1CNT = 0

在这里插入图片描述

  • 6. 定时器时钟源

    1. 时钟源:定时器时钟TIMxCLK,即内部时钟CK_INT,经APB预分频后分频提供
    2. 计数器时钟:定时器时钟经过PSC预分频器之后,即CK_CNT,用来驱动计数器计数。
    3. 计数器CNT:是一个16位/32的计数器
    4. 自动重装载寄存器:这里面装着的计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。
    5. 计数中断时间:1/(TIMxCLK/(PSC+1))*(ARR+1))
  • 7. 定时器溢出时间公式☆

    例如,要定时500ms,则:PSC=7199,ARR=4999,Tclk=72M

☆定时器相关配置

  • 使能时钟配置
  • 定时器参数配置
  • NVIC中断配置
  • 中断服务函数

CubeMX工程配置及程序实现

  • 时钟配置

    1. 采用外部高速晶振
    2. 时钟树配置
  • 定时器配置

    1. 开启定时器

    2. 参数设置

    3. 使能中断NVIC

  • 程序设计

    //初始化TIM2用于计时
    HAL_TIM_Base_Start_IT(&htim2);	
    
    //定时器中断服务程序
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
    		if( htim->Instance == TIM2)
    		{
    				HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
    		}
    }
    

固件库程序设计及实现

  • 使能时钟配置

    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//初始化定时器时钟
    
  • 定时器结构体配置

    	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;	//定时器结构体定义
    	
    	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;	//不分频
    	TIM_TimeBaseStructure.TIM_Prescaler =  psc;				//设置预分频系数
    	TIM_TimeBaseStructure.TIM_Period = arr;					//设置自动重装载值
    	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	//向上计数
    	TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure );		//初始化结构体
    	TIM_ITConfig( TIM2, TIM_IT_Update,  ENABLE);			//使能中断 允许更新中断源
    	TIM_Cmd( TIM2, ENABLE);									//使能定时器2
    
  • NVIC中断配置

    	NVIC_InitTypeDef NVIC_InitStructure;	//NVIC结构体定义
    	
    	//NVIC初始化
    	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;		//中断通道 TIM2
    	NVIC_InitStructure.NVIC_IRQChannelCmd =  ENABLE;	//使能通道
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;	//抢占优先级
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//子优先级
    	NVIC_Init(&NVIC_InitStructure);						//初始化NVIC结构体
    
  • 定时器2初始化函数设计

    	void TIM2_Init(u16 psc, u16 arr)		//500ms
    	{
    		 
    		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    		NVIC_InitTypeDef NVIC_InitStructure;
    		
    		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//初始化定时器时钟
    		//定时器初始化	
    		TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;	//不分频
    		TIM_TimeBaseStructure.TIM_Prescaler =  psc;
    		TIM_TimeBaseStructure.TIM_Period = arr;
    		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    		TIM_TimeBaseInit( TIM2, &TIM_TimeBaseStructure );				//初始化结构体
    		TIM_ITConfig( TIM2, TIM_IT_Update,  ENABLE);					//使能中断 允许更新中断源
    		
    		//NVIC初始化
    		NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    		NVIC_InitStructure.NVIC_IRQChannelCmd =  ENABLE;
    		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    		NVIC_Init(&NVIC_InitStructure);
    		
    		TIM_Cmd( TIM2, ENABLE);																//使能定时器2
    	}
    
  • 中断服务函数

    //TIM2 中断服务函数
    void TIM2_IRQHandler(void)
    {
    	if( TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET )	 //中断标志位判断,确认进入中断
    	{
    		LED1 = !LED1;
    		TIM_ClearFlag(TIM2, TIM_IT_Update);		//清除中断标志位
    	}
    }
    
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会编程的小江江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值