STM32定时器定时及其应用

STM32定时器定时及其应用

  • 定时器概述
  • ☆定时器相关配置
  • CubeMX工程配置及程序实现
  • 固件库程序设计及实现

定时器概述

  • 1. 工作原理
    使用精准的时基,通过硬件的方式,实现定时功能。定时器核心就是计数器
    STM32定时器定时及其应用_第1张图片

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

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

  • 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 = ARR CNT = 0
    向下计数 CNT = 0 CNT = ARR
    中心对齐计数 CNT = ARR - 1 CNT = ARR
    CNT = 1 CNT = 0

STM32定时器定时及其应用_第3张图片

  • 6. 定时器时钟源

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

☆定时器相关配置

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

CubeMX工程配置及程序实现

  • 时钟配置

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

    1. 开启定时器
      STM32定时器定时及其应用_第6张图片

    2. 参数设置
      STM32定时器定时及其应用_第7张图片

    3. 使能中断NVIC
      STM32定时器定时及其应用_第8张图片

  • 程序设计

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

你可能感兴趣的:(stm32单片机,stm32,嵌入式硬件,单片机)