stm32内部时钟定时器

这篇具有很好参考价值的文章主要介绍了stm32内部时钟定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、总体介绍

TIM(Timer)定时器是STM32中功能最强大,结构最复杂的一个外设,以下对其做一下简介(以stm32为例):

TIM可以对输入的时钟进行计数,并在数值达到设定值时触发中断。
在STM32中定时器的基准时钟一般都是主频72MHz,并且以16位计数器,预分频器,自动重装寄存器为时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。同时STM32定时器支持级联模式,可实现更长时间的定时。(当两个定时器级联时就可产生8千年多的定时)
TIM不仅具备基本的定时中断功能,而且还包括内外时钟源选择,输入捕获,输出比较,编码器接口,主从触发模式等多种功能。
STM32的定时器,根据复杂程度好应用场景分为了高级定时器,通用定时器,基本定时器三种类型。

2、定时器类型

stm32单片机计时器,# stm32,stm32,单片机,嵌入式硬件

当然也存在TIM9,TIM10等只是一般情况下用不到,同时也不是所有的STM32单片机都有所有的TIM外设,如STM32F103C8T6只有TIM1~TIM4这4个定时器。

3、定时中断

定时中断的基本结构

stm32单片机计时器,# stm32,stm32,单片机,嵌入式硬件

4、配置中断函数

定时一秒的时间,频率就是1HZ

这里以配置TIM2(通用定时器为例),首先我们需要在keil软件中编写Timer的.c和.h文件。将基本结构中的每一步打通即可完成Timer的函数配置。

开启RCC时钟
选择时基单元的时钟源(对于定时中断选择内部时钟源即可)
配置时基单元(ARR,PSC,CNT模式等,用结构体即可配置)
配置输入中断控制,允许更新中断输出到NVIC
配置NVIC,在NVIC中打开定时器的中断通道,并配置一个优先级
运行控制
上面配置完成之后,还需要使能计数器,否则计数器无法运行,最后写一个中断函数,这样每个一段时间中断函数就可自动运行了(计数器有使能和失能两个状态,使能是开启的意思,失能则是关闭)
.c文件:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启时钟
	
	TIM_InternalClockConfig(TIM2); //开启内部定时器
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;     //TIM结构体
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //这个是分屏系数,不需要纠结
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;     
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;   //这个值和上一行的值可以自己改变玩玩,体会一下不同
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复定时器,这个是高级定时器才有
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);// 清除更新时的中断标志位,防止更新时程序直接进入中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  //使能内部定时器
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;                //NVIC结构体
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;     //选取中断路径
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//相应优先级
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);    //开启定时器
}


void TIM2_IRQHandler(void)    //TIM2的中断函数名称,不能更改,不需要声明,同时这个函数也可放到main.c中
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)  //检查中断标志位
	{ //括号里添加自己所需要的中断代码
		

		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除标志位
	}
}


注意:TIM_TimeBaseStructure.TIM_ClockDivision = 0;这句话是什么作用?其实仔细看过技术手册后发现这句话与PWM输出实验其实是没关系的,这句话是设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例的(与输入捕获相关),0表示滤波器的频率和定时器的频率是一样的。 

 .h文件

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

5.计数器模式

通用定时器可以向上计数、向下计数、向上向下双向计数模式。
                1)向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。
                2)向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。
                3)中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。
        简单地理解三种计数模式,可以通过下面的图形:

stm32单片机计时器,# stm32,stm32,单片机,嵌入式硬件

 6、通用定时器工作流程

stm32单片机计时器,# stm32,stm32,单片机,嵌入式硬件

对于这个定时器框图,分成四部分来讲:最顶上的一部分(计数时钟的选择)、中间部分(时基单元)、左下部分(输入捕获)、右下部分(PWM输出)。这里主要介绍一下前两个,后两者的内容会在后面的文章中讲解到。

7.通用定时器时间计算

        初始化定时器的时候指定我们分频系数psc,这里是将我们的系统时钟(72MHz)进行分频。然后指定重装载值arr,这个重装载值的意思就是当我们的定时器的计数值达到这个arr时,定时器就会重新装载其他值。例如当我们设置定时器为向上计数时,定时器计数的值等于arr之后就会被清0重新计数。定时器计数的值被重装载一次被就是一个更新(Update)
        超出(溢出)时间计算:Tout=(ARR+1)(PSC+1)/TIMxCLK
                其中:Tout的单位为us,TIMxCLK是定时器时钟源,在这里就是72Mhz。我们将分配的时钟进行分频,指定分频值为psc,就将我们的TIMxCLK分了psc+1,我们定时器的最终频率就是TIMxCLK/(psc+1) MHz。这里的频率的意思就是1s中记 TIMxCLK/(psc+1) M个数 (1M=10的6次方) ,每记一个数的时间为(psc+1)/Tclk ,很好理解频率的倒数是周期,这里每一个数的周期就是(psc+1)/TIMxCLK 秒。然后我们从0记到arr 就是 (arr+1)*(psc+1)/TIMxCLK。
        这里需要注意的是:PSC预分频系数需要加1,同时自动重加载值也需要加1。
                1)为什么自动重加载值需要加1,因为从ARR到0之间的数字是ARR+1个;
                2)为什么预分频系数需要加1,因为为了避免预分频系数不设置的时候取0的情况,使之从1开始。
        这里需要和之前的预分频进行区分:由于通用定时器的预分频系数为1~65535之间的任意数值,为了从1开始,所以当预分频系数寄存器为0的时候,代表的预分频系数为1。而之前的那些预分频系数都是固定的几个值,比如1、4、8、16、32、64等等,而且可能0x000代表1,0x001代表4,0x010代表8等等。也就是说,一边是随意的定义(要从1开始),另一边是宏定义了某些值(只有特定的一些值)。
        比如,想要设置超出时间为1s,并配置中断,我们设置arr=7199,psc=9999。我们将72MHz (1M等于10的6次方) 分成了(9999+1)等于 7200Hz,就是一秒钟记录9000数,每记录一个数就是1/7200秒。我们这里记录9000个数进入定时器更新(7199+1)*(1/7200)=1s,也就是1s进入一次更新Update。
 

8、通用定时器相关配置库函数

1个初始化函数

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//定时器参数初始化
typedef struct
{
  uint16_t TIM_Prescaler;//预分频系数的设置      
  uint16_t TIM_CounterMode;//计数模式   
  uint16_t TIM_Period;//自动装载值
  uint16_t TIM_ClockDivision;//输入捕获会用到 
  uint8_t TIM_RepetitionCounter;//高级定时器会用到
} TIM_TimeBaseInitTypeDef; 

 作用:用于对预分频系数、计数方式、自动重装载计数值、时钟分频因子等参数的设置。

2个使能函数

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//定时器使能函数
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//定时器中断使能函数

作用:前者使能定时器,后者使能定时器中断。

 

4个状态标志位获取函数

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
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);

 作用:前两者获取(或清除)状态标志位,后两者为获取(或清除)中断状态标志位。

9.定时器中断的一般步骤
        实例要求:通过TIM3的中断来控制DS1的亮灭,DS1是直接连接在PE5上的。

                1)使能定时器时钟。调用函数:RCC_APB1PeriphClockCmd();
                2)初始化定时器,配置ARR、PSC。调用函数:TIM_TimeBaseInit();
                3)开启定时器中断,配置NVIC。调用函数:void TIM_ITConfig();NVIC_Init();
                4)使能定时器。调用函数:TIM_Cmd();
                5)编写中断服务函数。调用函数:TIMx_IRQHandler()。
文章来源地址https://www.toymoban.com/news/detail-585198.html

到了这里,关于stm32内部时钟定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 单片机-定时器时钟

    89C52RC 1.定时器0,lcd1602显示时间。    main.c

    2024年02月11日
    浏览(45)
  • 【单片机】STM32单片机,定时器的输入捕获,基于捕获的频率计,STM32F103

    下面的定时器都具有输入捕获能力: 查看另一篇文章:https://qq742971636.blog.csdn.net/article/details/131471539 外部计数频率计的缺点:需要两个定时器配合,最高能测量的频率是否有限制我没具体尝试。 基于捕获的频率计的缺点:最高能测量的频率有限制。 TIM3_CH1 PWM PA6 10KHZ。 输入

    2024年02月14日
    浏览(58)
  • STM32单片机入门学习笔记——定时器TIM第二部分

    笔记整理自B站UP主 江科大自化协 教程 《STM32入门教程-2023持续更新中》 ,所用单片机也为教程推荐单片机。 第一部分:定时器基本定时的功能,定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算

    2024年02月08日
    浏览(55)
  • STM32单片机(六)TIM定时器 -> 第三节:TIM输出比较

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月09日
    浏览(65)
  • STM32单片机入门学习笔记——定时器TIM第一部分

    笔记整理自B站UP主 江科大自化协 教程 《STM32入门教程-2023持续更新中》 ,所用单片机也为教程推荐单片机。 第一部分:定时器基本定时的功能,定时器每隔这个时间产生一个中断,来实现每隔一个固定时间执行一段程序的目的,比如要做一个时钟、秒表或者使用一些程序算

    2024年02月03日
    浏览(57)
  • STM32单片机(六)TIM定时器 -> 第五节:TIM输入捕获

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月09日
    浏览(42)
  • 【单片机】STM32单片机读取旋转编码器,TIM定时器编码器模式捕获,程序

    旋转编码器简单来说,就是会输出2个PWM,依据相位可以知道旋转方向,依据脉冲个数可以知道旋转的角度。一般旋转一圈有一个固定数值的脉冲个数。 旋转编码器广泛用于电机、或者角度传感器,STM32的定时器可以直接接入这两个波形获取到信息。 前两个引脚(接地和Vcc)

    2024年02月13日
    浏览(50)
  • 51单片机-定时器(简易时钟的实现)

    最近在学习51单片机,学到了 定时器 这块,由于自己的基础不太扎实,在这方面花了很多时间,这里通过对定时器和中断的介绍,用 简易时钟 这个例子来对学习的内容进行加深巩固,把自己的经验分享给大家,希望对大家能够有帮助。 其实就是单片机的内部,通过系统时钟

    2024年02月03日
    浏览(68)
  • C51单片机按键控制流水灯模式(定时器版本)以及定时器时钟

      上篇文章我们学了关于定时器的三大组成部分及许多寄存器的概念问题,这篇文章我们就要开始讲解实操部分。 首先,我们先来看看本文最后写成的代码:      以上三张是代码的主函数,此外,代码中还需用到的独立按键检测代码在下面:  注意:头文件中#ifndef和#def

    2023年04月17日
    浏览(49)
  • STM32F103RCT6开发板M3单片机教程06--定时器中断

    除非特别说明,本章节描述的模块应用于整个 STM32F103xx 微控制器系列,因为我们使用是 STM32F103RCT6开发板是mini最小系统板。 本教程使用是( 光明谷SUN_STM32mini开发板 )   首先了解一下是STM32F10X定时器(Timer)   注: 小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101

    2024年02月04日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包