目录

 概述

一、STM32 通用定时器简介

1.1 STM32定时器定时原理 

1.2 STM32 通用定时器相关寄存器简介

1.3 定时器功能描述

1.4计数器模式

二、定时器中断库函数

2.1 步骤总结

2.2 库函数讲解

总结:


 概述

        这一章,我们将向大家介绍如何使用 STM32F1系列 的通用定时器。TIME1和TIME8为高级定时器;TIME2~5为通用定时器;TIME6和TIME7为基本定时器。本章将选择难度适中的通用定时器讲解,在本章中,我们将学会如何配置使用 TIM3 的定时器中断。

一、STM32 通用定时器简介

        STM32F1 的通用定时器是一个16位自动装载计数器构成的(可计数0~65535)。每个通用定时器有4个独立通道(ch1~4),每个独立通道可实现:1)输入捕获  2)输出比较  3)PWM模式  4)单脉冲模式输出。(输出比较与PWM模式都能输出PWM波形,但有差别,常使用PWM模式输出PWM波形)。

        自动重装载计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟频率由 72M经过预分频器分频得到。

1.1 STM32定时器定时原理 

        定时器本质上是一个16位计数器(就是自动重装载计数器),计数器是一种寄存器,学过数电应该清楚,寄存器必须输入时钟才能工作,该计数器输入时钟频率为72M/(psc+1),psc就是预分频值。计数器每增加一个数,时间增加一个计数器时钟周期,因此,计数器计多少个数,就决定了定时时长是多少。这样就能理解为什么要配置自动重装载计数器和预分频寄存器了。

1.2 STM32 通用定时器相关寄存器简介

该部分可大体浏览一下,可只看文字部分,初步了解,等以后深入。

1)控制寄存器1(TIMx_CR1)。

图 1.1.1 TIMx_CR1 寄存器各位描述

        我们主要关注这几位:最低位CEN,也就是计数器使能位,该位必须置 1,才能让定时器开始计数。第 4 位 DIR(direction,方向),设置计数方式是向上计数还是向下计数。

2)DMA/中断使能寄存器 (TIMx_DIER),(DMA/Interrupt Enable Register)该寄存器是一个 16 位的寄存器。

图1.1.2 TIMx_DIER寄存器描述

        第0位:更新中断允许位,本章使用定时器中断需要使该位置1。

3)预分频寄存器(TIMx_PSC)。

图1.1.3 TIMx_PSC寄存器描述

       该寄存器对时钟进行分频,然后提供给计数器,作为计数器的时钟。 定时器时钟来源有多个。常见的时钟来源是从APB1倍频而来,72MHZ。f_计数器 = 72 M/(psc+1)

这个控制寄存器带有缓冲器,它能够随时被该变预分频值,但是新的预分频器值将在下一次中断发生时被设置成新的分频系数。

4)自动重装载寄存器。(TIMx_ARR)实际上有两个自动重装载寄存器,一个是我们看得见的,可以直接操作的;另一个是我们看不见的,叫影子寄存器。影子寄存器里的自动重装载值才是真正使用的自动重装载值。我们可以随时向看的见的寄存器里写入新的值,但是只有在在产生中断时,影子寄存器才会重新置入自动重装载值。

图1.1.4 TIMx_ARR 寄存器描述

1.3 定时器功能描述

时基单元包含:

● 计数器寄存器(TIMx_CNT)

● 预分频器寄存器 (TIMx_PSC)

● 自动装载寄存器 (TIMx_ARR)

1.4计数器模式

向上计数模式:

在向上计数模式中,计数器从0计数到自动重装载值(TIMx_ARR计数器的内容),然后重新从0开始

计数并且产生一个计数器中断事件。

向下计数和中央对齐模式暂不介绍。

二、定时器中断库函数

2.1 步骤总结

  1. Timer3定时器时钟使能。
  2. 配置时基单元
  3. 设置Timer3允许中断更新
  4. Timer3中断优先级配置
  5. 使能Timer3
  6. 编写中断服务函数

2.2 库函数讲解

timer3.c文件

#include "stm32f10x.h"
void timer3_init(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStr;   //定义时基单元结构体
	NVIC_InitTypeDef NVIC_Initstr;           //定义NVIC结构体
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟3使能,挂载于APB1
	TIM_TimeBaseInitStr.TIM_ClockDivision = TIM_CKD_DIV1; //默认值,目前不需要修改
	TIM_TimeBaseInitStr.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitStr.TIM_Period = 4999; //2hz  72000000/(4999+1)(7199+1)  
	TIM_TimeBaseInitStr.TIM_Prescaler = 7199; //设置预分频器值
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStr);   //初始化时基单元
	
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //Timer3中断使能
	
	NVIC_Initstr.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_Initstr.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Initstr.NVIC_IRQChannelPreemptionPriority = 0;//最高优先级
	NVIC_Initstr.NVIC_IRQChannelSubPriority= 0;
	
	NVIC_Init(&NVIC_Initstr);
	TIM_Cmd(TIM3, ENABLE);//开启定时器	
}

函数及参数讲解:

voidTIM_TimeBaseInit(TIM_TypeDef*TIMx, TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct);

举例:TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

时基初始化函数:该函数用来设置 定时器 定时时长。第一个参数指定哪个定时器。第二个参数传入时基单元结构体指针,该结构体参数如下:

  • uint16_t TIM_Prescaler;  预分频值。

  • uint16_t TIM_ClockDivision;  设置分频因子,输入捕获模式才用得到。这里我们默认使用TIM_CKD_DIV1;

  • uint16_t TIM_Period;  设置自动重装载寄存器值。

  • uint16_t TIM_CounterMode;  计数模式 :向上,向下

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

    举例:TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );

    定时器中断配置函数 :该函数用来使能定时器中断。

    第一个参数指定哪个定时器;第二个参数 指定中断类型;第三个指定使能还是失能。

    void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

    举例 :void TIM_Cmd(TIM3, ENABLE);

    定时器控制函数,用来设置开启/关闭定时器。

     中断服务函数

    void TIM3_IRQHandler(void) //定时器中断服务函数,固定函数名,去starup启动函数文件找函数名
    {
    	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查 TIM3 更新中断发生与否
    	{
    		TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除 TIM3 更新中断标志
    		LED0=!LED0;
    	}
    }

     函数及参数讲解:

    void TIM3_IRQHandler(void) 服务函数名的名字是固定的,可以去启动文件查找。

    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)  

    举例:TIM_GetITStatus(TIM3, TIM_IT_Update)

    判断定时器中断是否产生。第一个参数选择哪个定时器,;第二个参数为中断类型

    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)

    举例:TIM_ClearITPendingBit(TIM3, TIM_IT_Update );

    清楚中断标志位。

    主函数

    int main(void)
    {
    	delay_init();
    	Led_Init();
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    	timer3_init();
    
    	while(1)
    	{
    	}
    }

    总结:

    学先大体了解工作原理,学会调用库函数实现功能;然后再逐步深入。初有问题请留言。

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32学习–定时器中断

    发表评论