STM32学习笔记-通用定时器-定时中断和外部时钟

时基单元

1、预分频器PSC器(TIMx_PSC寄存器):对前置时钟频率进行分频,若分频系数为N,则对时钟的分频为CLK/(N+1);即对PSC送N+1个时钟信号,PSC才会送出一个时钟信号给CNT;

2、自动重装器ARR(自动重装载寄存器(TIMx_ARR)):CNT基数会累加,若自动重装器设为M,若CNT的技术累加到M+1,就会触发更新中断/更新事件,并将CNT重置为0(向上计数方式);向下计数及中心对齐类似;

3、计数器CNT:可读取TIMx_CNT寄存器的值知道当前计数到多少;

4、运行控制:调用void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)函数,实际操作的就是TIMx_CR1寄存器的bit0,CEN:使能计数器 0:禁止计数器; 1:使能计数器。

5、影子寄存器:如上的PSC和ARR都存在影子寄存器,作用就是缓冲PSC和ARR的修改是否立即生效;若启用了影子寄存器((TIMx_CR1)寄存器的bit7,ARPE:自动重装载预装载允许位,0:TIMx_ARR寄存器没有缓冲; 1:TIMx_ARR寄存器被装入缓冲器),则在修改PSC和ARR后,参数还要自动流转到影子寄存器,待影子寄存器在产生更新事件/中断时才生效;

6、时钟选择:

内部时钟:调用void TIM_InternalClockConfig(TIM_TypeDef* TIMx)函数即可;实际操作的是TIMx_SMCR寄存器的SMS[2:0],000:关闭从模式 – 如果CEN=1(TIMx_CR1寄存器的bit0,计数器的使能位),则预分频器直接由内部时钟驱动;

外部时钟模式2:由外部GPIO-ETR输入,不通过触发选择器,直接送给时基单元,调用void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);/*调用TIM_ETRConfig()函数,不作为时钟源输入选择,单纯只是对极性,分频和滤波做设定,再对寄存器进行SMCR |= TIM_SMCR_ECE(0x4000)操作,实现外部时钟模式二的设定*/

外部时钟模式1:也是由外部GPIO-ETR输入,但是通过触发选择器,调用void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);/*嵌套了一个TIM_ETRConfig()函数,对极性、滤波、分频设定好,操作的是SMCR寄存器*/
/*在对SMCR寄存器TS[2:0]:触发选择 (Trigger selection) ,外部触发输入(ETRF),以及SMS[2:0]:从模式选择 (Slave mode selection) ,111:外部时钟模式1 – 选中的触发输入(TRGI)的上升沿驱动计数器。 *//*实现外部时钟模式一的设定*/

ITRX:调用void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);/*也是时钟源选择,ITR其他定时器作为时钟选择,嵌套了TIM_ITRxExternalClockConfig()函数,最终也是操作TIMx->SMCR寄存器,只是访问的是BIT4~6*/

TIX:调用void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
/*也是时钟源选择,TIx外部时钟(GPIO口作为输入捕获的那些,第三个和第四个参数是对输入的时钟信号的极性选择和滤波),*/

7、中断输出控制:调用void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)函数即可;实际操作的是TIMx_DIER寄存器,可选择启用更新中断、捕获/比较中断、触发中断、DMA请求等中断类型;

8、NVIC,中断优先级设定,参考GPIO外部中断

内部时钟:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启定时器2时钟
	
	TIM_InternalClockConfig(TIM2);//选择时钟源为内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//创建时基单元结构体并初始化
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//不是预分频,是时钟滤波的作用,内部时钟下设定为不分频,外部时钟时,以系统时钟频率下设定多少分频作为滤波基数,不影响最终时钟频率的输入,即外部时钟滤波就是以时钟72M的N分频下去采样外部时钟,采样到M个信号都是一致就认为有效,N就是这个参数;
	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_ClearFlag(TIM2, TIM_FLAG_Update);//清除更新中断标志位,因为在TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);函数里,最后操作的是TIMx->EGR = TIM_PSCReloadMode_Immediate; 重新初始化计数器,并产生一个更新事件 ,同时也触发了更新中断;更新中断标志位置1,这样一初始化就会有更新中断,所以需要手动清除下更新中断标志位;
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能中断方式,这里选择更新中断;
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级设定
	
	NVIC_InitTypeDef NVIC_InitStructure;//初始化NVIC
	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);
	}
}

外部时钟模式2:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//定时器2时钟使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//外部时钟模式2是使用GPIO作为时钟源,故需要使能GPIO时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;//初始化GPIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//由于定时器2的TIM2_CH1_ETR是复用在PA0上
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);//选择时钟源是外部模式2,第一个参数TIM2,第二个参数输入的时钟频率是否分频,选择不分频;第三个参数,输入信号是否反向,选择不反向,上升沿/高电平有效,第四个参数滤波;
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化TIM2
	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)
{
	return TIM_GetCounter(TIM2);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值