- 0.说点啥
- 1.定时器分类
- 2.TIM6定时器的使用
- 2.1 TIM6代码编写
- 2.2 相关函数解析:
- 3.结语
1.定时器分类🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌🍌
🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒🍒
作者简介:大家好啊,我叫DW,小白一个,每天分享一些我新学到的知识,期待和大家一起进步🌹
🍊🍊🍊🍊🍊🍊🍊🍊🍊🍊🍊
🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋🍋系列专栏:STM32🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎
🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎🍎小实验目标:利用基本定时器定时点亮一颗LED灯🌞
🍊如有写得不好的地方欢迎大家指正🍊
创作时间:🍊🍊🍊2022年4月18日🍊🍊🍊
高级定时器:TIM1、TIM8
通用定时器:TIM2、TIM3、TIM4、TIM5
基本定时器:TIM6、TIM7
通过这个表可以清楚看出他们的相同和差异之处。
(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
2.2 相关函数解析:利用两个if语句实现定时4s,如果大家有其他定时需求,只需要修改if(temp2==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);
3.结语获取LED输出值,如果为0则置1,为1则置0,实现LED亮灭亮灭
今天的分享就到这里,从头到尾一个一个字码下来,重新回顾了今天的学习内容,收货满满,希望这个习惯能一直坚持下去,用博客记录自己学习的过程,谢谢大家的耐心阅读,如果觉得有用的话给个👍👍👍
🌜🌜🌜本章结束,我们下一章见🌜🌜🌜
源码已上传,需要自取
这是我今天学习链接:学习链接
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)