基本定时器(TIM6/TIM7)

1.基本定时器介绍

基本定时器 TIM6TIM7 包含一个 16 位自动重载计数器,该计数器由可编程预分频器驱动。
此类定时器不仅可用作通用定时器以生成时基,还可以专门用于驱动数模转换器 (DAC)。实际上,此类定时器内部连接到 DAC 并能够通过其触发输出驱动 DAC。
这些定时器彼此完全独立不共享任何资源

2.基本定时器的主要特性

(1)16 位自动重载递增计数器
(2)16 位可编程预分频器,用于对计数器时钟频率进行分频(即运行时修改),分频系数介于 1 和 65536 之间
(3)用于触发 DAC 的同步电路
(4)发生如下更新事件时会生成中断/DMA 请求:计数器上溢

3.基本定时器的配置

在这里插入图片描述
根据上图我们总结一下大致的配置流程:
(1)开启相对应的时钟线
(2)确保相对应的定时器已经完成初始化
(3)配置定时器的更新中断使能
(4)配置优先级分组
(5)NVIC初始化

其实整体配置过程与之前讲的外设中断和SysTick定时器中断大同小异。做完以上定时器中断初始化配置后,接下来完成对中断函数的内容编写就可以使用了。下面是分别用TIM6实现和SysTick一样的定时功能,TIM7实现定时中断功能。

//实现xms的延时
void TIM6_DelayMs(u16 x)
{
	//开启TIM6时钟线
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	//基本定时器没有这个部分,可以选择配置默认值(不分频)或不配
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	//配置为向上计数
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	//配置重装载值
	TIM_TimeBaseInitStruct.TIM_Period = 2*x-1;
	//定时器内分频倍数
	TIM_TimeBaseInitStruct.TIM_Prescaler = 42000-1;
	//仅限于TIM1/TIM8配置PWM需要
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct);
	
	//软件产生更新事件
	TIM_GenerateEvent(TIM6, TIM_EventSource_Update);
	
	//清除标志位
	TIM_ClearFlag(TIM6, TIM_FLAG_Update);
	
	//清空计数器
	TIM_SetCounter(TIM6, 0);
	
	//使能定时器
	TIM_Cmd(TIM6, ENABLE);
	
	//等待计数完成
	while(TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
}

//实现xμs的延时
void TIM6_DelayUs(u16 x)
{
	//开启TIM6时钟线
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	//基本定时器没有这个部分,可以选择配置默认值(不分频)或不配
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	//配置为向上计数
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	//配置重装载值
	TIM_TimeBaseInitStruct.TIM_Period = 2*x-1;
	//定时器内分频倍数
	TIM_TimeBaseInitStruct.TIM_Prescaler = 42-1;
	//仅限于TIM1/TIM8配置PWM需要
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseInitStruct);
	
	//软件产生更新事件
	TIM_GenerateEvent(TIM6, TIM_EventSource_Update);
	
	//清除标志位
	TIM_ClearFlag(TIM6, TIM_FLAG_Update);
	
	//清空计数器
	TIM_SetCounter(TIM6, 0);
	
	//使能定时器
	TIM_Cmd(TIM6, ENABLE);
	
	//等待计数完成
	while(TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
}

//初始化TIM7
void TIM7_Init(u16 x)
{
	//开启TIM7时钟线
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	//基本定时器没有这个部分,可以选择配置默认值(不分频)或不配
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	//配置为向上计数
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	//配置重装载值
	TIM_TimeBaseInitStruct.TIM_Period = 2*x-1;
	//定时器内分频倍数
	TIM_TimeBaseInitStruct.TIM_Prescaler = 42000-1;
	//仅限于TIM1/TIM8配置PWM需要
	//TIM_TimeBaseInitStruct.TIM_RepetitionCounter = ;
	
	TIM_TimeBaseInit(TIM7, &TIM_TimeBaseInitStruct);
	
	//软件产生更新事件
	TIM_GenerateEvent(TIM7, TIM_EventSource_Update);
	
	//清除标志位
	TIM_ClearFlag(TIM7, TIM_FLAG_Update);
	
	//清空计数器
	TIM_SetCounter(TIM7, 0);
	
	//使能定时器
	TIM_Cmd(TIM7, ENABLE);
}

//TIM7中断初始化函数
void TIM7_ITInit(u16 x, u8 PreemptionPriority, u8 SubPriority)
{
	//x毫秒触发一次中断
	TIM7_Init(x);
	//开启TIM7更新中断
	TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
	
	//配置优先级组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//NVIC初始化
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM7_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = SubPriority;
	NVIC_Init(&NVIC_InitStruct);
}

//TIM7中断处理函数
void TIM7_IRQHandler(void)
{	
	//判断产生的中断是否为更新中断
	if(TIM_GetITStatus(TIM7, TIM_IT_Update) == SET)
	{
		//中间写你需要在更新中断时执行的操作
		LED2_T;

		//清除更新中断标志位
		TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
	}
}

补充:由于影子寄存器的存在,我们在对定时器内部的PSC(预分频器)和自动重载寄存器操作后,需要写一个更新中断才能让值写入相对应的影子寄存器,我们的写入操作才能生效。
具体的标准库函数参照stm32f4xx_tim.c或stm32f4xx_tim.h。

  • 17
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值