6.[STM32]基本定时器-TIM6&TIM7

6.[STM32]基本定时器-TIM6&TIM7,第1张

文章目录
  • 0.说点啥
  • 1.定时器分类
  • 2.TIM6定时器的使用
    • 2.1 TIM6代码编写
    • 2.2 相关函数解析:
  • 3.结语

0.说点啥

🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌
🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒
作者简介:大家好啊,我叫DW,小白一个,每天分享一些我新学到的知识,期待和大家一起进步🌹
🍊🍊🍊🍊🍊🍊🍊🍊🍊🍊🍊
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋

系列专栏:STM32🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎

小实验目标:利用基本定时器定时点亮一颗LED灯🌞
🍊如有写得不好的地方欢迎大家指正🍊
创作时间:🍊🍊🍊2022年4月18日🍊🍊🍊

1.定时器分类

高级定时器:TIM1、TIM8
通用定时器:TIM2、TIM3、TIM4、TIM5
基本定时器:TIM6、TIM7


通过这个表可以清楚看出他们的相同和差异之处。

2.TIM6定时器的使用 2.1 TIM6代码编写

(1)创建time.c和time.h文件

(2)添加头文件和包含路径

(3)在time.h和time.h中编写如下代码

//time.h
#ifndef __TIME_H
#define __TIME_H

#include "sys.h"

#endif

这几行的代码的意思是,如果没有time.h文件就创建time.h文件
#include “sys.h”:里面含有我们用的的串口定义等代码,需要包含

//time.c
#include "time.h"

在time.c文件中需要包含time.h文件,才可以引用里面的内容

🎵🎵 小提示
如果在time.c文件中没有引用time.h文件,编译后项目窗口是没有time.h文件的,这个需要注意。

(4)创建TIM6函数
在time.c文件中创建TIM6函数

void TIM6_UserConfig(void){
}

🎵🎵 小提示
如果没有添加包含路径,在time.c中编写代码时是不会有代码提示的



由此我看可以看出其中的差别

(5)创建TIM6结构体和NVIC结构体,并开启时钟,TIM6挂载在APB1时钟总线上

	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	NVIC_InitTypeDef NVIC_InitStrcture;
		
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);

(6)定义TIM6的相关参数

	TIM_InitStructure.TIM_Period = Period;//自动重装载寄存器周期的值
	TIM_InitStructure.TIM_Prescaler = Prescaler;//预分频系数
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//系统时钟分割:不分割
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数 TIM6 TIM7只有向上计数
	TIM_InitStructure.TIM_RepetitionCounter = DISABLE;//基本定时器不支持重复计数
	TIM_TimeBaseInit(TIM6,&TIM_InitStructure);

	TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清空中断状态
	TIM_ITConfig(TIM6,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//使能中断更新和中断源
	TIM_Cmd(TIM6,ENABLE);//开启全局使能

(7)中断配置

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//使用0号分组
	
	NVIC_InitStrcture.NVIC_IRQChannel = TIM6_IRQn;//中断入口:使用TIM6
	NVIC_InitStrcture.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
	NVIC_InitStrcture.NVIC_IRQChannelSubPriority = 0;//子占优先级
	NVIC_InitStrcture.NVIC_IRQChannelCmd = ENABLE;//中断使能
	NVIC_Init(&NVIC_InitStrcture);//初始化

(8)中断函数编写

//全局变量
u8 temp1 = 0;
u8 temp2 = 0;

void TIM6_IRQHandler(void){
	
	if(TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET){//500ms
		
		temp1 = temp1+1;
		if(temp1==2){//1s
			
			temp1=0;
			temp2 = temp2+1;
			if(temp2==2)//2s 脉宽
			{
				temp2=0;
				//LED亮灭亮灭
				(GPIO_ReadOutputDataBit(LED_PROT,LED) == RESET) ? GPIO_SetBits(LED_PROT,LED) : GPIO_ResetBits(LED_PROT,LED);
			}
		}
		TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清空中断状态
	}
} 

🎵🎵 小提示

🎵 使用void TIM6_UserConfig(u16 Period,u16 Prescaler)函数进行脉宽计算
TIM6_UserConfig(5000-1,7200-1);//500ms 减1编译器会自动加1,故需要减1
🎵 🎵 我们单片机的频率为72MHz =72 000 000Hz
先对其进行7200分频 ,故分频系数Prescaler为7200 ,72 000 000/7200 = 1 000 0
我们需要500ms的脉宽 500ms=2hz 故用1 000 0/2=5000 既重装载值Period为5 000
🎵 🎵 🎵 脉宽为500ms(高电平持续时间),周期为1s
在中断函数中,利用temp1、temp2实现LED亮灭周期为4s

利用两个if语句实现定时4s,如果大家有其他定时需求,只需要修改if(temp2==2)这句代码即可.

2.2 相关函数解析:

(1)TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)

if(TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET)

获取中断标志位,如果它的值为1代表产生了中断

(2)c语言补充:三目运算符

🎵🎵 小提示

🎵 C语言中的三目运算符是:“?:”,该运算符连接3个对象,是C语言中唯一一个三目运算符,又称为条件运算符。
🎵 🎵 三目运算符判断条件表达式的真值,若为真则执行“?”号后的第一个表达式,否则执行第二个表达式。

(3)GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

(GPIO_ReadOutputDataBit(LED_PROT,LED) == RESET) ? GPIO_SetBits(LED_PROT,LED) : GPIO_ResetBits(LED_PROT,LED);

获取LED输出值,如果为0则置1,为1则置0,实现LED亮灭亮灭

3.结语

今天的分享就到这里,从头到尾一个一个字码下来,重新回顾了今天的学习内容,收货满满,希望这个习惯能一直坚持下去,用博客记录自己学习的过程,谢谢大家的耐心阅读,如果觉得有用的话给个👍👍👍

🌜🌜🌜本章结束,我们下一章见🌜🌜🌜

源码已上传,需要自取
这是我今天学习链接:学习链接

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/759980.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-01
下一篇 2022-05-01

发表评论

登录后才能评论

评论列表(0条)

保存