江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟

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

目录

一、TIM(Timer)定时器简介

 1.1 定时器类型

摘要

1.1.1 基本定时器

1.1.2 通用定时器

1.1.3 高级定时器 

1.2 定时中断基本结构

1.2.1 结构框图

1.2.2 时序图

二、定时器定时中断&定时器外部时钟

2.1 内部时钟闹钟代码

2.1.1 Timer.c

2.1.2 Buzzer.c加入间隔发声函数

2.1.3 main.c

2.1.4 实验视频

2.1.5 bug调试

2.2 定时器外部时钟

2.2.1 Timer.c

2.2.2 main.c

2.2.3 bug调试


一、TIM(Timer)定时器简介

  • 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。
  • 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。此处计算:2^16=65536 , 65536×65536÷72M=59.65s
    原理参见基本定时器框图部分
  • STM32的定时器支持级联,可以用一个计时器的输出,当做另一个计时器的输入
  • 还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能

 1.1 定时器类型

摘要

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

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

1.1.1 基本定时器

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  • 这里的预分频器是16位的,最大值可以写65535,也就是65536分频;
  • 这里的计数器也是16位的,可以从0一直加到65535
  • 自动重装寄存器也是16位的,存的是我们写入的计数目标,当计数值等于计数目标时,会产生一个更新信号,并清零计数器,计数器自动开始下一轮的计数计时 
  • 基本定时器只能选择内部时钟

1.1.2 通用定时器

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  • 基本定时器只能向上自增计数
  • 通用定时器支持向上计数、向下计数和中央对齐计数三种模式
  • 通用定时器可以通过TIMx_ETR选择外部时钟
  • 通用定时器可以通过ITR0,1,2,3,与其他定时器实现级联,足以丈量宇宙
  • TIMx_CH1,2,3,4 用于输入捕获或输出比较,引脚共用

1.1.3 高级定时器 

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  • 高级定时器的重复次数定时器相当于对输出更新信号又做了一次分频,提升了定时时间
  • DTG是死区生成电路,防止互补输出的PWM在开关切换瞬间短暂的直通现象
  • 输出引脚变为互补输出,可以输出一对互补的PWM波,用于驱动三相无刷电机
  • 刹车输入功能

1.2 定时中断基本结构

1.2.1 结构框图

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  • 左边框图是可选择的时钟源
  • 时基单元:由预分频器、计数器、自动重装器构成,高级定时器还多一个重复计数器
  • 运行控制:控制寄存器,用来设置运行启动、停止、向上或向下计数等。
  • 中断输出控制:有很多地方会申请中断,如果需要就允许,不需要的就禁止。

1.2.2 时序图

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  • 预分频器时序
  • 计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

江科大stm32视频学习笔记——TIM定时中断&定时器外部时钟,STM学习,单片机,stm32,笔记

  •  计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
                                                         =CK_PSC / (PSC
    + 1) / (ARR + 1)

二、定时器定时中断&定时器外部时钟

2.1 内部时钟闹钟代码

2.1.1 Timer.c

  • 第一步:RCC开启给TIM2的时钟
  • 第二步:TIM2的时基单元选择时钟来源为内部时钟
  • 前两步相当于双重开关,一个选择给谁;另一个选择接受谁。
  • 第三步:配置时基单元
  • 第四步:中断输出控制:选择中断源为TIM2的update中断,使能输出
  • 第五步:配置NVIC
  • 最后不要忘了给TIM2使能
#include "stm32f10x.h"                  // Device header

//时间hh:mm:ss
uint32_t hh = 12 ;
uint32_t mm = 43 ;
uint32_t ss = 07 ;

//设置闹钟时间
uint32_t h = 0 ;
uint32_t m = 0 ;
uint8_t flag = 0 ;   //闹钟复位标记

void Timer_Init(void)
{
	//RCC开启时钟给TIM2
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//TIM2时基单元选择时钟来源为内部时钟
	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;                   //ARR自动重装器的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;                 //预分频器的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;              //重复计数器的值
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);                              //清除更新中断标志位
	
    //选择中断源为TIM2的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()
{
	//用取整取余的方式计算时间
	ss= 3600*hh + 60*mm + ss;
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
	{
		ss++;
		if(ss == 86400)
		{
			ss = 0;
		}	
		uint32_t i = ss % 3600 ;
		uint32_t j = i % 60 ;
		hh = ss / 3600;
		mm = i / 60;
		ss = j;
		
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}

	//if嵌套的方式进位
//	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
//	{
//		ss++;
//		while(ss == 60)
//		{
//      mm++;
//			ss = 0;
//			while(mm == 60)
//			{
//				hh++;
//				mm = 0;
//				while(hh == 24)
//				{
//					hh = 0;
//				}
//			}
//		}
//		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
//	}
}

2.1.2 Buzzer.c加入间隔发声函数

//滴滴~~
void  Buzzer_Spaced(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_12);
	Delay_ms(150);
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
	Delay_ms(150);
	GPIO_ResetBits(GPIOB, GPIO_Pin_12);
	Delay_ms(150);
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
	Delay_ms(600);
}

2.1.3 main.c

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

extern uint32_t h ;
extern uint32_t m ;
extern uint8_t flag ;

extern uint32_t hh ;
extern uint32_t mm ;
extern uint32_t ss ;

int main(void)
{
	OLED_Init();
	Timer_Init();
	Buzzer_Init();
	
	OLED_ShowString(1,5,"T I M E");
	OLED_ShowString(2,4,":");
	OLED_ShowString(2,7,":");
	OLED_ShowString(2,10,":");
	while(1)
	{
		//时间显示
		OLED_ShowNum(2,8,ss,2);
		OLED_ShowNum(2,5,mm,2);
		OLED_ShowNum(2,2,hh,2);
		OLED_ShowNum(2,11,TIM_GetCounter(TIM2),4);
		
		//闹钟开启
		if(hh == h && mm == m && flag == 0)
		{
			Buzzer_Spaced();
		}

		//闹钟关闭,可定义变量方便更改时间长度
		if(hh == h && mm == m && ss == 3 )
		{
			Buzzer_OFF();
			flag = 1;
		}

		//flag标志复位
		if(hh == h && mm != m && flag == 1)
		{
			flag = 0;
		}
	}
}

2.1.4 实验视频

Alarm Clock文章来源地址https://www.toymoban.com/news/detail-817374.html

2.1.5 bug调试

  • 现象:初始状态未从0开始
  • 归因:影子寄存器需要更新事件才能起作用,为了让其立刻生效,TIM_TimeBaseInit()在最后立即生成一个更新事件。由于更新中断和更新事件是同时发生的,所以同时将更新中断置标志位,初始化结束后立即触发了更新中断。
  • 解决方案:在更新中断使能前清除更新中断标志位
  • 现象:hh:mm:ss三个数据同时触发跳变,跳变不同步有延迟,但影响不大
  • 归因:怀疑时间进位时多重if嵌套拖慢进程,改为取整取余计算时间,无任何变化。
               更改三个数据OLED显示顺序,延迟数据有变化,但仍无法同步。
  • 解决方案:暂时未解决,可能需要修改OLED部分代码

2.2 定时器外部时钟

  • 简介:通过对射式红外传感器手动计数

2.2.1 Timer.c

#include "stm32f10x.h"                  // Device header

extern uint16_t Num ;

void Timer_Init(void)
{
	//开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	//TIM2选择外部时钟模式2,可设置预分频,极性,滤波
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);
	
	//时基单元配置
	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
	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);
}

2.2.2 main.c

#include "stm32f10x.h"                  // Device header
#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(2,5,TIM_GetCounter(TIM2),5);
	}
}

void TIM2_IRQHandler()
{
	Num++;
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
} 
  • 记得在中断函数最后清除中断标志位 

2.2.3 bug调试

  • 现象:遮挡一次,计数值跳变多次
  • 归因:传感器电平抖动导致,尝试判断中断是否来自TIM2的update、变更外部时钟预分频都不稳定。
  • 解决方案:变更外部时钟滤波方案为0x0f,实测稳定。

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

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

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

相关文章

  • stm32学习笔记-6TIM定时器

    注:笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注:工程及代码文件放在了本人的Github仓库。 定时器是STM32中功能最强大、结构最复杂的一个外设。定时器将包括四部分8小节: 第一部分主要讲定时器基本定时的功能,也就是指定一个时间,让

    2024年02月15日
    浏览(21)
  • STM32单片机(六)TIM定时器 -> 第二节:TIM定时中断练习(定时器定时中断和定时器外部时钟)

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

    2024年02月09日
    浏览(20)
  • 【江科大】STM32:定时器中断

    功能:定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 HZ 和ms的单位转换:1ms = 1KHZ 1MZ = 1000KHZ 1ms = 1000us 16位计数器、预分频器、自动重装寄存器(记录多少个时钟申请中断)的时基单元,在72MHz计数时钟下可以实现最大59.65s(72/65536/65536 ,再取倒数)的

    2024年01月23日
    浏览(22)
  • 【STM32】STM32学习笔记-TIM定时中断(13)

    TIM(Timer)定时器 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码

    2024年01月17日
    浏览(20)
  • STM32标准库开发——TIM定时器中断

    定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型 不仅具备基本的定时中断功能

    2024年01月18日
    浏览(19)
  • STM32学习笔记 & 通用定时器TIM3~TIM5 13

    通用定时器是一个通过可编程预分频器驱动的 16 位自动装载计数器构成。 它适用于多种场合,包括测量输入信号的脉冲长度 ( 输入捕获 ) 或者产生输出波形 ( 输出比较和PWM)。 使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间

    2024年02月05日
    浏览(41)
  • STM32 HAL库 STM32CubeMX -- TIM(定时器中断)

    STM32F1 系列中,除了一些特殊的型号,大部分F1有8 个定时器,分为 基本定时器,通用定时器和高级定时器 。 基本定时器TIM6 和TIM7 是一个16 位的只能向上计数的定时器,只能定时,没有外部IO。 通用定时器TIM2/3/4/5 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出

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

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

    2024年02月08日
    浏览(24)
  • 【STM32】STM32学习笔记-定时器定时中断 定时器外部时钟(14)

    1.1 TIM_InternalClockConfig 1.2 TIM_TimeBaseInit 1.3 TIM_TimeBaseInitTypeDef 1.4 TIM_ClearFlag 1.5 TIM_ITConfig 1.6 TIM_Cmd 1.7 中断服务函数 参考程序 1.8 TIM_ETRClockMode2Config timer.h timer.c main.c timer.h timer.c main.c 09-定时器定时中断.rar 10-定时器外部时钟.rar 参考: 【STM32】江科大STM32学习笔记汇总

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

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

    2024年02月03日
    浏览(20)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包