新手必看!!超详细!STM32-基本定时器--定时功能


  

一、基本定时器的作用

  1. 定时
  2. 触发输出直接驱动DAC。

二、基本定时器的框图

可以看出基本定时器的时钟源来自内部时钟。
在这里插入图片描述

以STM32F103系列为例,具体开发板请查看开发手册。

类别定时器总线位数计数方向预分频系数是否可以产生DMA捕获/比较通道互补输出
基本定时器TIM6 / TIM7APB116位向上1~65536可以0
通用定时器TIM2 /TIM3 /TIM4/ TIM5APB116位向上/向下/中央对齐1~65536可以4
高级定时器TIM1 /TIM8APB216位向上/向下/中央对齐1~65536可以4

三、基本定时器的寄存器

1. 控制寄存器-TIMx->CR1

在这里插入图片描述

位 0:CEN 计数器使能 (Counter enable)

    0:禁止计数器
    1:使能计数器

位 1:UDIS 更新禁止 (Update disable)(没有使用中断可以不设置)

   0:使能 更新 (UEV),更新事件可通过以下事件之一生成:(1)计数器上溢(2)将 UG 位置 1

   1:禁止 更新UEV。定时到达后不会生成更新事件。

位 2: URS 选择更新请求源 (Update request source)

    0:如果使能了中断或DMA,以下任一事件可以产生一个更新中断或DMA请求。此类事件包括:(1)计数器上溢;(2)将 UG 位置 1
    1:只有计数器上溢才会生成更新中断或DMA请求。

位 3: OPM 单脉冲模式 (One-pulse mode)

    0:计数器在发生更新事件时不会停止计数
    1:计数器在发生下一更新事件时停止计数(将 CEN 位清零)。

位 7: ARPE 自动重载预装载使能 (Auto-reload preload enable)

    0: TIMx_ARR 寄存器不进行缓冲(影子寄存器无效)。
    1: TIMx_ARR 寄存器进行缓冲(影子寄存器有效)。

2. 控制寄存器-TIMx->CR2(用于高级定时器,这里我们先不看。)

在这里插入图片描述

3.事件产生寄存器-TIMx->EGR

在这里插入图片描述
位 0: 产生更新事件(该位由软件设置,由硬件自动清除)

 0:无作用
 1:重新初始化定时器的计数器并产生对寄存器的更新。

4. DMA/中断使能寄存器-TIMx->DIER

在这里插入图片描述

位 8: 更新DMA请求

    0:禁止更新DMA请求。
	1:使能更新DMA请求。

位 0: 更新中断请求

   0:禁止更新中断。
   1:使能更新中断。

5. 状态寄存器(中断标志)-TIMx->SR

在这里插入图片描述

如果清除中断标志位需要软件清0。读取该寄存器的位0来判断是否发生中断。

位 0: 更新中断标志位

   0:没有发生中断(定的时间还没到)。
   1:发生了中断。如果发生中断,则该位由硬件置1。

6. 计数器-TIMx->CNT

在这里插入图片描述

位 [ 15:0 ]:用于计数,范围0~65535。一般不用设置。基本定时器默认为0开始。

7. 预分频器-TIMx->PSC

在这里插入图片描述

位 [ 15:0 ]: 设置预分频系数。

8. 自动重装载寄存器-TIMx->ARR

在这里插入图片描述
位 [ 15:0 ]: 设置重装载值。

四、实验

实验1. 查询方式:用定时器TIM6实现延时1s闪烁LED1灯。
实验2. 中断方式:用TIM7实现1s反转一次LED灯。

补:定时时间计算如下:

注意单位Tout为us。
在这里插入图片描述
arr:重装载值。
psc:预分频系数。
Tclk:定时器时钟频率,单位Mhz。基本定时器为72Mhz。

实验1. 查询方式:利用TIM6实现定时1s的功能。

在这里插入图片描述

●伪代码:

定时器初始化
{
	1.打开APB1定时器6的时钟。
	2.设置单脉冲模式。
	3.设置预分频系数。
	4.设置自动重装载值。
	5.UG置1,产生更新事件。(将上面的配置更新到寄存器)
	6.使能计数器。
}

因为设置了单脉冲模式,所以当发生更新事件时,就会自动关闭定时器,所以不需要手动关闭。
●具体代码:

void TIM6_Init(u16 psc,u16 arr)
{
   RCC->APB1ENR |=(0X01 <<4); //1.打开APB1时钟
   TIM6->CR1 |=(0X01 <<3);  //2.设置单脉冲模式。
   TIM6->PSC =psc ; //3.设置分频系数
   TIM6->ARR =arr;  //4.设置装载值(上限值)  
   TIM6->EGR |=(0x01 <<0); //5.UG置1,产生更新事件。(将上面的配置更新到寄存器)
   TIM6->CR1 |=(0x01 <<0); //6.使能计数器
}

●主函数:

int main()
{
	 LED_Init();
	 while(1)
	 {
	   TIM6_Init(9999,7199); //(9999+1)*(7199+1)/72 =1000 000us =1000ms =1s。
	   LED1=1;
	   TIM6_Init(9999,7199);
	   LED1=0;  
	 }
}

实验二:中断方式:用TIM7实现1s反转一次LED灯。

●伪代码:

定时器初始化
{
	1.打开APB1定时器7的时钟。
	2.设置影子寄存器--缓冲。
	3.设置循环模式。
	
	4.选择更新请求源。
	
	5.设置预分频系数。
	6.设置自动重装载值。
	7.UG置1,产生更新事件。(将上面的配置更新到寄存器)

    8. 设置中断优先级。
     
    9.使能NVIC控制器。
	10.使能定时器。
	11.使能定时器中断。
	12.使能更新事件。
}

●具体代码:

void TIM7_Init(u16 psc, u16 arr)
{
	RCC->APB1ENR |= 1<<5;//1.使能定时器7的时钟
	TIM7->CR1 |= 1<<7;  //2.TIM7_ARR 寄存器进行缓冲
	TIM7->CR1&=~(1<<3);//3.计数器在发生更新事件时不会停止计数(循环计数,循环定时)

	TIM7->CR1&=~(1<<2);//4.选择更新请求源,允许①计数器上溢;②将 UG 位置 1 ,这两种情况产生更新事件
		
	TIM7->PSC = psc;//5.设置预分频系数。
	TIM7->ARR = arr;//6.设置自动重装载值。
	TIM7->EGR |= 1<<0;//7.UG置1,产生更新事件。(将上面的配置更新到寄存器)
	
	NVIC_SetPriority(SysTick_IRQn,NVIC_EncodePriority(7-2,1,2));  // 8. 设置中断优先级。
	
	NVIC_EnableIRQ(TIM7_IRQn);//9.使能NVIC控制器。
	TIM7->CR1|=1<<0;// 10.使能定时器。
	TIM7->DIER |= 1<<0;// 11.使能定时器中断。
	TIM7->CR1&=~(1<<1);//12.使能更新事件。
}

void  TIM7_IRQHandler(void)
{
   if(TIM7->SR&(1<<0))  //判断中断标志是否置1
   {
      TIM7->SR &=~(1<<0);//中断标志清零
      LED=!LED;
   }
}

●主函数:

int main(void)
{
	LED_Init();
	TIM7_Init(9999,7199); //(9999+1)*(7199+1)/72 =1000 000us =1000ms =1s。
	while(1)
	{
	
	}
}

附录:库函数版

void Time7_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
	TIM_InternalClockConfig(TIM7);
	
	
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = arr; //电机PWM频率要和定时器采样频率一致
	TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM7, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM7, TIM_FLAG_Update);
	TIM_ITConfig(TIM7, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM7, ENABLE);
}

void TIM7_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM7, TIM_IT_Update) == SET)
	{		
		TIM_ClearITPendingBit(TIM7, TIM_IT_Update);
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值