STM32内部定时中断(TIM)

本文详细介绍了STM32单片机中定时器TIM的配置,包括基本定时器和通用定时器的结构、计时模式、定时中断设置,以及如何使用TIM2定时器实现秒数计时。涉及预分频、计数器操作和主从触发模式等内容。
摘要由CSDN通过智能技术生成

这个实验我们需要配置好定时器中断,每隔1s使变量自增达到计时的效果。首先简单介绍下定时器TIM:
3b2b23df791c423d81310522d85affb3.png

其中能实现的最大定时59.65的值是(72MHz/ 65536/65536)的倒数的近似结果,第一个65536是将预分频器(PSC)的值配置到最大,第二个65536则是将计数器(CNT)配置到最大。这样的计算对于我来说不是很好理解,也有人提供了另一个理解的想法,就是将72MHz先预分频,再取倒数,得到CNT计加一的周期,然后再乘CNT的重装载值,就得到了中断一次的时间。这样就好理解了。

可以看到定时器的功能还是蛮多的,但是想要用好STM32单片机,以后还得掌握主从触发模式等功能。

a7c5629f0bc74f0d967b783efad21c43.png

0c5596b8ccb84acab706a84d2115f241.png

对于不同的定时器和各种外设资源是挂载在哪个总线或其他位置的可以参考上图。可见对于STM32F103C8T6型号的单片机来说, 只有一个挂载在APB2总线的高级定时器TIM1,和3个挂载在APB1总线的通用定时器TIM2,TIM3,TIM4。

我们先来看下基本定时器,方便之后的理解:

67972c4314af4137881200d82d7ee633.png

最前面的定时器介绍可以看到,PSC,CNT和自动重装载寄存器(ARR)构成了定时器的时基单元,在通用和高级定时器也会看到。 

其中ARR和PSC的 值都是可以配置的,PSC最大可以对主频进行65536分频,但是配置时我们要写入的是预分频系数,他等于我们要分频的数-1。

ARR最大可配置65536,PSC最大可配置65535。当CNT会根据从PSC来的信号周期性自增,当达到ARR的重装载值时触发更新中断或更新事件,当然此时CNT会置一个标志位,需要我们用对应的库函数清零,这个展示代码时再说。基本定时器介绍到这里,接着我们介绍一下通用定时器:

37109788232b4dfc99565db82b4e7381.png

对于通用定时器,可以看到在正中央的时基单元,功能还是一样的,不过相较于基本定时器可以配置CNT的计时模式,向上计时模式:由0向上自增。向下计时模式:由重装载值向下自减只0。中央计时模式:先由0向上自加,再由重装载值向下自减。。。。。。

基本定时器只能选择内部时钟作为时钟源,而通用定时器和高级定时器还可以选择外部时钟作为时钟源。 ITRx涉及到定时器的级联,CNT一下的电路可以先不看,可以只看来自TIMx_ETR的时钟和内部时钟,若来自TIMx_ETR且不经过选择器的时钟要配置为时钟模式2,若想要配置内部时钟则要用对应的库函数配置为内部时钟模式。

TRGO与主从触发有关。

5325dcc0fecc4434a6e7a08f20ad970f.png

 我们根据上图逐一配置外设:

#include "stm32f10x.h" // Device header
extern uint16_t Sec;
void Timer_Init()//TIM2
{
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
		
		TIM_InternalClockConfig(TIM2);//内部时钟模式
	
		TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
		TIM_TimeBaseInitStructure.TIM_Prescaler=7199;
		TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
		TIM_TimeBaseInitStructure.TIM_Period=9999;
		TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV4;//采样点数分频,越高信号质量越好
		TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级计数器配置
		TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
		TIM_Cmd(TIM2,ENABLE);
		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_IRQChannelPreemptionPriority=2;//抢占优先级
		NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级
		NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
		NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler()//中断函数,可在start文件夹的md.s文件里找到
{
		if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
		{
				TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
				Sec++;
		}
}

然后是简单的写下主函数(忽略OLED):

#include "stm32f10x.h"// Device header
#include "OLED.H"
#include "Timer.h"
uint16_t Sec=0,Min,Hour;
int main()
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,6,"Hr");
	OLED_ShowString(1,9,"Mi");
	OLED_ShowString(1,12,"Sc");
	OLED_ShowString(2,1,"Time:");
	OLED_ShowChar(2,8,':');
	OLED_ShowChar(2,11,':');
	while(1)
	{
			OLED_ShowNum(2,6,Hour,2);
			OLED_ShowNum(2,9,Min,2);
			OLED_ShowNum(2,12,Sec,2);
			if(Sec>=60)
			{
					Sec=0;
					Min++;
				if(Min>=60)
				{
						Min=0;
						Hour++;	
						Hour%=60;
				}
			}
			
	}
}

以上内容仅供参考,谢谢!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值