stm32定时器级联(一个定时器作为另一个的预分频器

本文详细介绍了如何在STM32中实现TIM2和TIM3的级联,使用TIM2作为TIM3的预分频器,通过TIM2的更新事件触发TIM3,每秒TIM2中断一次,TIM3在接收到两次TIM2的信号后中断。代码示例展示了配置过程,包括时基设置、中断配置和NVIC设置。文章强调了主从模式的独立性以及外部触发输入的选择方法。
摘要由CSDN通过智能技术生成

stm32定时器级联(一个定时器作为另一个的预分频器

在网上找了许多代码看了许多资料,都没有找到理想的,有些不是用标准库的,有些只写出了想法并没有具体的操作,经过多次修改笔者终于成功运行。

该代码的实现功能是:TIM2和TIM3的级联,TIM2用内部时钟源,每秒产生一个中断(执行NUM1++)和更新事件(作为TRGO输出到TIM3),TIM3以触发输入为时钟,每传来两次信号后进入中断(执行NUM2++)

Timer.c

#include "stm32f10x.h"                  // Device header


void Timer_Init(void)
{
	/*
		TIM2
	*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	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;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//打开更新中断
	TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);//设置更新事件,触发输出
	
	/*
		TIM3
	*/ 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);//TIM3的触发输入
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_External1);//选择TIM3的从模式

	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 2-1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1-1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	/*
		NVIC
	*/
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStrucutre;

	NVIC_InitStrucutre.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStrucutre.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStrucutre.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStrucutre.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStrucutre);
	
	NVIC_InitStrucutre.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStrucutre.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStrucutre.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStrucutre.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStrucutre);
	
	TIM_Cmd(TIM2, ENABLE);
	TIM_Cmd(TIM3, ENABLE);
}

Timer.h

#ifndef __TIMER_H_
#define __TIMER_H_

void Timer_Init(void);

#endif

main.c

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

uint16_t Num1, Num2;

int main(void)
{
	OLED_Init();
	Timer_Init();
	
	while (1)
	{
		OLED_ShowString(1, 1, "NUM1:");
		OLED_ShowNum(1, 6, Num1 ,5);
		
		OLED_ShowString(2, 1, "NUM2:");
		OLED_ShowNum(2, 6, Num2 ,5);
	}
}

void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num1++;
		TIM_ClearFlag(TIM2, TIM_IT_Update);
	}
}

void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3, TIM_IT_Update) == SET)
	{
		Num2++;
		TIM_ClearFlag(TIM3, TIM_IT_Update);
	}
}

先看看手册中给出的方法:

在这里插入图片描述

可以归结为一下几点:
①配置TIM1为主模式,配置内部时钟,时基单元,产生的更新事件映射到TRGO口。
②配置TIM2为从模式,从ITRx引脚输入时钟,设置外部时钟模式,设置时基单元。
③开启TIM1和TIM2。

几点感悟:

①主从模式并不是需要配套使用的,可以只有TIM3的从模式,这也算是笔者学习的一个误区,自以为主从模式是配套的,有主就得有从。
②从其他时钟触发输入选择的时钟模式,应该由TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_External1)函数确定,不应该设置外部时钟模式1(TIM_ETRClockMode1Config)。笔者产生这个误会来自下图。实际上应该看下图。
在这里插入图片描述在这里插入图片描述
③定时器的更新中断和更新事件可以同时允许。

附上定时器框图和定时器的内部连接:
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值