stm32——定时器

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

一、定时器介绍

1.简介

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

2.定时器类型

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

  • STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

3.基本定时器

stm32定时器,stm32,单片机,嵌入式硬件
基本定时器可分为3部分

a.时钟源

时钟源来自RCC的TIMXCLK,就是内部时钟(CK_INT)直接经过控制器传给时基单元充当CK_PSC

b.控制器

控制定时器的复位、使能、计数、DAC触发

c.基本时基单元

1>预分频器(PSC)perscaler
分频、得到计时器的时钟,即CNT计数1次所需要的时间,预分频器时16位的寄存器、所以可分频为1-65536。
基本定时器只能选择内部时钟,故预分频器直接输入端,即内部时钟CK_INT(一般为72MHz)
预分频器(PSC)写0(1分频或者不分频):则SK_CNT输出72MHz,
写1(2分频):输出36MHz,写2(3分频):输出24MHz。
故实际分频系数=预分配系数+1(分频器是16位,故最大位65525)。

2>计数器(CNT)counter
用来计数,到达设定值后,会产生中断。

3>自动重装寄存器(ARR)Auto Reload Register
CNT加到ARR的值之后,会产生一个事件或中断或DMA请求,中断用得比较多

UI(向上的箭头)中断响应,更新中断后会通向NVIC,再通向CPU
U(向下的箭头)事件响应:触发其他外设工作

d.主模式触发DAC功能

1)能让内部的硬件再不受程序的控制下实现自动运行,若利用好,可以极大地减轻CPU的负担。
2)用途:使我们使用DAC的时候,用DAC输出一段波形,则需要每隔一段事件触发一次DAC,让它输出下一个电压点。
用正常思维实现:先设置一个定时器产生中断,每隔一段时间再中断程序中调用代码手动触发一次DAC转换,然后DAC输出。这样会使主程序处于频繁被中断的状态,会影响主程序的运行和其他中断的响应
故定时器设置了一个主模式,使用主模式可以把定时器的更新事件映射到触发输出TRGO(Trigger Out)的位置,然后TRGO直接接到DAC的触发转换引脚上,这样定时器的更新就不需要用中断来触发DAC(数模转换)转换了
仅仅需要将更新事件通过主模式映射到TRGO,然后TRGO就会直接去触发DAC,整个过程不需要软件的参与,实现了硬件的自动化,这就是主模式的作用

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

时序

stm32定时器,stm32,单片机,嵌入式硬件
有框框的有影子寄存器,即预分频缓冲器,可以进行缓存,更改的值下个周期才生效(比如你改手机套餐,这个月内你还是原套餐,你改的套餐下个月才生效)
stm32定时器,stm32,单片机,嵌入式硬件

4.通用定时器

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

区别:
1.计数器支持向上、向下、中央对齐计数模式
2.可用外部时钟作为主频率
3.时钟来自其他定时器

未完待续…

二、实例

1. 基本思路

stm32定时器,stm32,单片机,嵌入式硬件第一步:RCC开启时钟
第二步:选择时基单元的时钟源,对于定时中断,选择内部时钟源
第三步:配置时基单元,包括预分频器、自动重装器、计数模式(用结构体配置)
第四步:配置输出中断控制,允许更新中断输出到NVIC
第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级
第六步:运行控制,整个模块配置完成后,使能计数器,否则计数器不运行, 计数器使能后,计数器就会开始计数,当计数器更新时,触发 中断,最后写个定时器中断函数,这样中断中断函数就能每隔一段时间自动执行一次

2.定时器中断

Timer.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //RCC开启时钟
	
	TIM_InternalClockConfig(TIM2);  //配置内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;  //配置时基单元
	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;  //预分频值(对72Mhz进行7200分频率,即10K计数频率,再计数10000次,得到1s)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;  //多少次触发才触发一次中断(高级定时器才有此功能)
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);  //清除向上溢出的中断标志
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);  //使能更新中断
	
	//配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
	NVIC_InitTypeDef NVIC_InitStructure;
	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)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}
*/

main. c

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

uint16_t num;

int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"NUM:");
	
	while(1)
	{
		OLED_ShowNum(1,5,num,5);
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

3.定时器外部时钟

Timer.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //配置GPIO口
	
	GPIO_InitTypeDef GPIO_InitSturcture;
	GPIO_InitSturcture.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitSturcture.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitSturcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSturcture);
	
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);  //更改为外部中断2模式(相较于1模式(4条通道),该模式只有1条通道,且可分频,比较简单,推荐使用)
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period=10-1;
	TIM_TimeBaseInitStructure.TIM_Prescaler=1-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_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);
	
}

uint16_t Timer_getcounter(void)  //看CNT的值
{

	return TIM_GetCounter(TIM2);
}

/*
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}
*/

Timer.h

#ifndef  __TIMER_H__
#define  __TIMER_H__

void Timer_Init(void);
uint16_t Timer_getcounter(void);

#endif

main.c

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

uint16_t num;

int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"NUM:");
	OLED_ShowString(2,1,"CNT:");
	while(1)
	{
		OLED_ShowNum(1,5,num,5);
		OLED_ShowNum(1,5,Timer_getcounter(), 5);
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		num++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

4.其他知识

extern:告诉编译器,已经在别的文件中定义了该变量,(可以实现在文件之间传递值)文章来源地址https://www.toymoban.com/news/detail-738090.html

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

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

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

相关文章

  • 【单片机】STM32单片机读取旋转编码器,TIM定时器编码器模式捕获,程序

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

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

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

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

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

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

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

    2024年02月09日
    浏览(56)
  • 【单片机】STM32单片机,定时器,多路PWM,TIM1、TIM2、TIM3、TIM4,STM32F103

    下图是定时器相关引脚: 在《STM32中文参考手册V10.pdf》有写: TIM1 的PWM是带互补输出的,较为高级和复杂,有兴趣可以参考其他介绍文章,这里的代码让7个引脚输出PWM。 调用: 这里没有重映射,注意不能把PA9 PA10 初始化成串口去了。 timer.c timer.h 调用: 这里没有重映射。

    2024年02月11日
    浏览(57)
  • STM32F103RCT6开发板M3单片机教程06--定时器中断

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

    2024年02月04日
    浏览(47)
  • 基于STM32F103C8T6单片机的1秒定时器设计与应用

    标题:基于STM32F103C8T6单片机的1秒定时器设计与应用 摘要: 本文主要探讨了如何在STM32F103C8T6微控制器上利用内部定时器实现精确的1秒钟定时功能,并通过实际项目实施,验证其稳定性和可靠性。首先介绍了STM32F103C8T6单片机的特性及其定时器资源,然后详细阐述了基于TIMx(

    2024年01月18日
    浏览(52)
  • (第48-59讲)STM32F4单片机,FreeRTOS【事件标志、任务通知、软件定时器、Tickless低功耗】【纯文字讲解】【】

    【吐血总结】FreeRTOS难点、Systick中断-滴答定时器、PendSV中断-任务切换、SVC中断-系统底层、时间片调度-时钟节拍【已完结】 (第1-8讲)STM32F4单片机,FreeRTOS基础知识总结【视频笔记、代码讲解】【正点原子】【原创】 (第9-10讲)STM32F4单片机,FreeRTOS任务创建和删除(动态方

    2024年02月01日
    浏览(54)
  • STM32单片机(六)TIM定时器 -> 第六节:TIM输入捕获练习(输入捕获模式测频率和PWMI模式测频率占空比)

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

    2024年02月09日
    浏览(33)
  • 学习笔记|定时器|STC中断|定时器时间计算|STC32G单片机视频开发教程(冲哥)|第十一集:定时器的作用和意义

    什么是定时器:定时器-与非网 上节课的一段代码: TimeCount++然后一个延时1毫秒,每运行1ms,变量就会加一。 系统已经运行了多少个毫秒。 实际使用时的代码如下, 判断按键有沿有按下的时候,我们等待按键松开,还有一个while循环。 如果没有松开,会一直死在这一行。所以,

    2024年02月09日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包