欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > STM32第六课:定时器

STM32第六课:定时器

2024/10/24 11:18:47 来源:https://blog.csdn.net/Jokerblank/article/details/139897146  浏览:    关键词:STM32第六课:定时器

文章目录

  • 需求
  • 一、系统定时器
    • 1.配置流程
    • 2.时间轴的实现
    • 3.主函数需求实现
  • 二、基本定时器
    • 1.TIM6定时器的配置
      • 1.时钟源使能
      • 2.分频器
      • 3.装载值
      • 4.计数器使能
      • 5.打开定时器中断并配NVIC
      • 6.中断函数的编写
    • 2.需求编写
  • 三、通用定时器
    • TIM2
  • 总结


需求

1.使用系统滴答定时器实现LED灯的翻转(0.5s翻转一次)。
2.实现定时器6的定时功能,让LED2以500ms一次的频率闪烁。
3.配置定时器2,实现一个1s的定时功能(到时间LED4翻转)。


一、系统定时器

STM32里面有几个定时器:
高级定时器:TIM1,8
通用定时器: TIM2,3,4,5
基本定时器:TIM6,7
系统定时器(滴答定时器):Systick

1.配置流程

由于系统定时器在内核中,所以想要配置系统定时器的相关寄存器,需要打开内核手册。
在这里插入图片描述
首先要打开时钟源和分频器
在这里插入图片描述
由内核手册可知该寄存器的0,1,2位均要置1。
代码如下:

	//系统滴答定时器定时 1ms//时钟源和分频器 72m  7	2000 000SysTick->CTRL |= 0x1<<2;//计数器 打开SysTick->CTRL |= 0x1<<0;//打开系统定时器中断SysTick->CTRL |= 0x1<<1;

配置完成后,还需要配置重载值
在这里插入图片描述
在这里插入图片描述
代码如下:

	SysTick->LOAD = 72000-1;//计数器计数从72000-1计数到0产生中断

或者直接使用内核写好的函数

SysTick_Config(72000);  //1ms中断进入一次

SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定时为1ms。

最后的NVIC可配可不配。

2.时间轴的实现

配置完系统定时器后,我们就可以实现一个类似事件轴的东西,比单纯使用delay函数更准确。
代码如下:
delay.c 里加入void SysTick_Handler(void)函数

void SysTick_Handler(void)		//1ms调用一次
{systicktime++;led1_count++;led2_count++;
}

在main函数中外部声明一下 led1_count和led2_count。
这样我们就得到了一个1ms计数一次的时间轴,当我们需要时只需要在主函数中判断计数即可。

3.主函数需求实现

		if(led1_count>=500){//过去500msled1_count=0;/***LED1闪烁任务***/Led_Toggle(1);}if(led2_count>=700){//过去500msled2_count=0;/***LED2闪烁任务***/Led_Toggle(2);}

二、基本定时器

STM32中定时器分类以及相关作用
高级控制定时器:TIM1、TIM8 定时+输入捕获+输出比较+死区+互补PWM
通用定时器:TIM2、3、4、5 定时+输入捕获+输出比较
基本定时器:TIM6、7 定时

定时器配置的大致流程:
1、时钟源 RCC内部的时钟 APB1 36M APB1*2 = 72M
2、配置时需要打开APB1上TIM2、3、4、5、6、7或APB2上 TIM1、8的时钟(根据需求)
3、配置分频器:根据实际情况计算,不能超过65536 (TIMx_PSC)
4、配置重装载值:根据实际情况计算,不能超过65536(TIM_ARR)
5、打开计数器:
TIM_CR1(位0,位2) TIMx_DIER位0;
6、使能中断通道、配置中断优先级。
7、写一个中断服务函数。

1.TIM6定时器的配置

首先创建一个tim.c和tim.h文件
在.c中创建void TIM6_Config(uint16_t psc,uint16_t reload)函数
然后打开手册找到TIM6定时器

在这里插入图片描述
由图中可以看到,只要配置好分频器,计数器自动重装载寄存器即可。

1.时钟源使能

首先还是老规矩,先打开时钟源,顺着手册看TIM6的时钟源是在APB1还是APB2上。

在这里插入图片描述
在这里插入图片描述

从手册中得知该时钟源是在APB1总线上,所以将其RCC_APB1第四位置1即可。

RCC->APB1ENR |= 0x01<<4;

2.分频器

在这里插入图片描述
由于该分频器是自动+1,所以传参时应-1。

	//分频器TIM6->PSC = psc-1;

3.装载值

在这里插入图片描述
在这里插入图片描述
由于该寄存器是从0开始重载,所以需要初始值-1

	//装载值TIM6->ARR = reload-1;

4.计数器使能

直接找到手册里的TIM6控制寄存器
在这里插入图片描述在这里插入图片描述
可知将TIM6 和TIM7 控制寄存器1的第0位置1即可使该计数器使能。

	//计数器使能TIM6->CR1 |= 0x01<<0;

5.打开定时器中断并配NVIC

在这里插入图片描述
在这里插入图片描述
由手册可知,将TIM6 和TIM7 DMA/中断使能寄存器(TIMx_DIER)的第0位置1即可打开。
最后配置一下NVIC即可

	//打开定时器中断TIM6->DIER |= 0x01<<0;NVIC_SetPriority(TIM6_IRQn,5);//设置优先级0~15NVIC_EnableIRQ(TIM6_IRQn);//使能中断通道

6.中断函数的编写

在这里插入图片描述

先在.s文件中找到TIM6对应的中断函数复制,然后看TIM6的SR是如何判断的。
由图可知,当TIM6->SR的第0位为1时产生中断。

void TIM6_IRQHandler()
{//判断中断标志位if((TIM6->SR&(0x01<<0))!=0){//清理中断标志位TIM6->SR &= ~(0x01<<0);printf("定时器中断\r\n");}
}

2.需求编写

首先在主函数中调用 TIM6_Config();
由于需求是让LED2以500ms一次的频率闪烁,所以此时函数中应填写

	  TIM6_Config(7200,5000);

系统时钟是72Mhz,等于72000000hz。除于7200,等于0.1ms计数一次。
5000代表计数5000次定时器报警,也就是说500ms产生中断一次
最后,在产生中断时翻转LED2即可。

中断函数代码为:

void TIM6_IRQHandler()
{//判断中断标志位if((TIM6->SR&(0x01<<0))!=0){//翻转LED2Led_Toggle(2);//清理中断标志位TIM6->SR &= ~(0x01<<0);printf("定时器中断\r\n");}
}

三、通用定时器

TIM2

跟TIM6配置一样
照着流程走即可
需求实现代码如下:
main.c

#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
#include "led.h"
#include "delay.h"
#include "tim.h"int main()
{NVIC_SetPriorityGrouping(5);//两位抢占两位次级TIM2_Config(7200,10000);	Usart1_Config(); Led_Init();while(1){	}
}void TIM2_IRQHandler()
{//判断中断标志位if((TIM2->SR&(0x01<<0))!=0){//翻转LED2Led_Toggle(2);//清理中断标志位TIM2->SR &= ~(0x01<<0);printf("定时器中断\r\n");}
}

tim.c

#include "stm32f10x.h"/*
配置定时器的基本功能
参数1psc:分频系数
参数2reload:装载值
*/void TIM6_Config(uint16_t psc,uint16_t reload)
{//时钟源APB1*2=72MHz,时钟源使能RCC->APB1ENR |= 0x01<<4;//分频器TIM6->PSC = psc-1;	//装载值TIM6->ARR = reload-1;//计数器使能TIM6->CR1 |= 0x01<<0;//打开定时器中断TIM6->DIER |= 0x01<<0;NVIC_SetPriority(TIM6_IRQn,5);//设置优先级0~15NVIC_EnableIRQ(TIM6_IRQn);//使能中断通道
}void TIM2_Config(uint16_t psc,uint16_t reload)
{//时钟源APB1*2=72MHz,时钟源使能RCC->APB1ENR |= 0x01<<0;//分频器TIM2->PSC = psc-1;	//装载值TIM2->ARR = reload-1;//计数器使能TIM2->CR1 |= 0x01<<0;//打开定时器中断TIM2->DIER = 0x01<<0;NVIC_SetPriority(TIM2_IRQn,3);//设置优先级0~15NVIC_EnableIRQ(TIM2_IRQn);//使能中断通道
}

tim.h

#ifndef _TIM_H_
#define _TIM_H_
#include "stm32f10x.h"void TIM6_Config(uint16_t psc,uint16_t reload);
void TIM2_Config(uint16_t psc,uint16_t reload);
#endif

总结

1.了解了STM32中定时器的种类及作用。
2.学会了配置及使用系统定时器,基本定时器和通用计时器。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com