IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32学习记录 -- 通用定时器的配置(TIM2-TIM5) -> 正文阅读

[嵌入式]STM32学习记录 -- 通用定时器的配置(TIM2-TIM5)

前言

? ? ? ? 在我们编代码的时候,往往需要固定一程序心跳包去进行一个保活,或者给一个程序运行一个固定的时候,再或者是PWM的使用,都离不开定时器的使用,不仅方便我们处理数据,还给我们节约了MCU的内存,让我们的程序可以更加高效的执行起来


🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎

一.定时器的配置

1.timer.c

把TIM配置进行了封装处理,更加方便我们的配置和修改

#include "timer.h"	
#include "led.h"
/*********************************************************************************
* @Function	: 通用定时器的选择(TIM2-TIM5)
*	@Author   : HR
* @Date			: 2022-08-30
**********************************************************************************/
#if GENERAL_TIM2
		U16 Usart3_Time = 0; // ms 计时变量
		U16 Usart4_Time = 0; // ms 计时变量 
		U16 Usart5_Time = 0; // ms 计时变量 
#endif
#if GENERAL_TIM3
		U32 time = 0; // ms 计时变量 
#endif
#if GENERAL_TIM4
		U16 time_4 = 0; // ms 计时变量 
#endif
#if GENERAL_TIM5
		U16 time_5 = 0; // ms 计时变量 
#endif
/*********************************************************************************
* @Function	: TIM定时器选择
* @Input		: time,TIM定时器(TIM_2-TIM_5)
* @Output		:	TIM模块
* @Return		: None
* @Others		:	None
* @Date			: 2022-08-30
**********************************************************************************/
static TIM_TypeDef * TimeModule_get( TimeModule time )
{
	TIM_TypeDef * timeTemp;
	switch( ( U8 )time )//UART模块选择
	{
#if GENERAL_TIM2
		case TIM_2:
			timeTemp = TIM2;
		break;
#endif
#if GENERAL_TIM3
		case TIM_3:
			timeTemp = TIM3;
		break;
#endif
#if GENERAL_TIM4
		case TIM_4:
			timeTemp = TIM4;
		break;
#endif
#if GENERAL_TIM5
			case TIM_5:
				timeTemp = TIM5;
			break;
#endif
	}
  return timeTemp;
}
/*********************************************************************************
* @Function	: TIM定时器中断初始化
* @Input		: time,TIM定时器(TIM_2-TIM_5)
*						PreemptionPriority,抢占优先级
*						SubPriority,子优先级
* @Output		:	None
* @Return		: None
* @Others		:	None
* @Date			: 2022-08-30
**********************************************************************************/
static void GENERAL_TIM_NVIC_Config( TimeModule time, U8 PreemptionPriority, U8 SubPriority)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
  // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);	// 设置中断组为0
	//Usart NVIC 配置
	switch( ( U8 )time )//中断通道配置
	{
		case TIM_2: NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;break; //TIM2中断
		case TIM_3: NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;break;
		case TIM_4: NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;break;
		case TIM_5: NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;break;
	}
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= PreemptionPriority ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
}
/*********************************************************************************
* @Function	: TIM时钟使能
* @Input		: time,time时钟(TIM_1-TIM_5)
* @Output		:	None
* @Return		: None
* @Others		:	None
* @Date			: 2022-08-30
**********************************************************************************/
static void GENERAL_TIMClock_Enable( TimeModule time)
{
	switch( (U8)time )
	{
		case TIM_2: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); break;//通用定时器2时钟使能
		case TIM_3: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); break;//通用定时器2时钟使能
		case TIM_4: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); break;//通用定时器2时钟使能
		case TIM_5: RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); break;//通用定时器2时钟使能
	}
}

/*
 * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
 * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
 * 另外三个成员是通用定时器和高级定时器才有.
 *-----------------------------------------------------------------------------
 *typedef struct
 *{ TIM_Prescaler            都有
 *	TIM_CounterMode			     TIMx,x[6,7]没有,其他都有
 *  TIM_Period               都有
 *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有
 *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有
 *}TIM_TimeBaseInitTypeDef; 
 *-----------------------------------------------------------------------------
 */
static void GENERAL_TIM_Mode_Config(TimeModule time)
{
		TIM_TypeDef * timeTemp;
		TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;	
		timeTemp = TimeModule_get( time );//TIME时钟选择
	
		// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period=GENERAL_TIM_Period;
	  // 时钟预分频数
    TIM_TimeBaseStructure.TIM_Prescaler= GENERAL_TIM_Prescaler;	
		// 时钟分频因子 ,没用到不用管
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;		
		// 计数器计数模式,设置为向上计数
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 		
		// 重复计数器的值,没用到不用管
		TIM_TimeBaseStructure.TIM_RepetitionCounter=0;	
	  // 初始化定时器
    TIM_TimeBaseInit(timeTemp, &TIM_TimeBaseStructure);
		// 清除计数器中断标志位
    TIM_ClearFlag(timeTemp, TIM_FLAG_Update);
		// 开启计数器中断
    TIM_ITConfig(timeTemp,TIM_IT_Update,ENABLE);
		// 使能计数器
    TIM_Cmd(timeTemp, DISABLE); //关闭定时器
}
/*********************************************************************************
* @Function	: TIM2-5 初始化
* @Input		: time,TIM定时器(TIM_2-TIM_5)
*						PreemptionPriority,抢占优先级
*						SubPriority,子优先级
* @Output		:	None
* @Return		: None
* @Others		:	None
* @Date			: 2022-08-30
**********************************************************************************/
void GENERAL_TIM_Init(TimeModule time,U8 PreemptionPriority, U8 SubPriority)
{
	GENERAL_TIMClock_Enable(time); //TIM使能化
	GENERAL_TIM_NVIC_Config(time,PreemptionPriority,SubPriority); //TIM中断优先级配置
	GENERAL_TIM_Mode_Config(time); //TIM初始化	
}
/*********************************************************************************
* @Function	:  TIMER2定时器中断服务
* @Input		:  None
* @Output		:	 None
* @Return		:  None
* @Others		:	 None
* @Date			:  2022-08-30
**********************************************************************************/
#if GENERAL_TIM2 
void TIM2_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		if(Usart5_Time>0){
			Usart5_Time++;//串口五接收间隔判断
		}else if(Usart4_Time>0){
			Usart4_Time++;//串口四接收间隔判断
		}else if(Usart3_Time>0){
			Usart3_Time++;//串口三接收间隔判断
		}
		//满足条件关定时器
		if(Usart5_Time==10||Usart3_Time==10||Usart4_Time==10){
			TIM_Cmd(TIM2, DISABLE); //关闭定时器
		}
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志
	}
}
#endif
/*********************************************************************************
* @Function	:  TIMER3定时器中断服务
* @Input		:  None
* @Output		:	 None
* @Return		:  None
* @Others		:	 None
* @Date			:  2022-08-30
**********************************************************************************/
#if GENERAL_TIM3 
void TIM3_IRQHandler(void)   //TIM3中断
{
	U8 i;
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		if(time>0){
			time++;//串口五接收间隔判断
		}
		//满足条件关定时器
		if(time==10000){
			LED2_OFF;
			time=0;
			TIM_Cmd(TIM3, DISABLE); //关闭定时器
		}
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
	}
}
#endif



2.timer.h

在主函数只需要选择我们需要配置的通用定时器即可

例如?

GENERAL_TIM_Init(TIM_2,0,3);?? ??? ?//初始化定时器2,抢占优先级,子优先级(防止掉帧)

#ifndef __TIMER_H
#define __TIMER_H

#include "tool.h"
#include "stm32f10x_tim.h"
/**************通用定时器TIM参数定义,只限TIM2、3、4、5************/
// 当需要哪个定时器的时候,只需要把下面的宏定义改成1即可
#define GENERAL_TIM2    1
#define GENERAL_TIM3    1
#define GENERAL_TIM4    0
#define GENERAL_TIM5    0
/*********************************************************************************
* @Function	: TIME实例
**********************************************************************************/
typedef enum 
{
	TIM_2,
	TIM_3,
	TIM_4,
	TIM_5,
	TIME_NUM
}TimeModule;
/*********************************************************************************
* @Function	: 固定分频率
**********************************************************************************/
#define            GENERAL_TIM_Period            (1000-1)
#define            GENERAL_TIM_Prescaler         71 //时钟预分频数

/*********************************************************************************
* @Function	: TIM2-5 初始化
* @Input		: time,TIM定时器(TIM_2-TIM_5)
*						PreemptionPriority,抢占优先级
*						SubPriority,子优先级
* @Output		:	None
* @Return		: None
* @Others		:	None
* @Date			: 2022-08-30
**********************************************************************************/
void GENERAL_TIM_Init(TimeModule time,U8 PreemptionPriority, U8 SubPriority);

#endif

🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎

二.定时器的使用

1.PWM输出使用

使用TIM的分频率去控制PWM的输出,做到控制端口电压的输出,可实现呼吸灯,电机转速等控制效果

2.软件定时器的使用

例如我们执行一个开关的的程序,当我们固定一个动作打开灯后,在这个打开灯的时候就开启我们的定时器,在定时器里面做一个固定时间再关闭我们的灯

例如下列代码

在主函数首先进行TIM3的配置

GENERAL_TIM_Init(TIM_3,0,2);		//初始化定时器3,抢占优先级,子优先级(LED定时器)

?对TIM3的中断进行一个配置即可

/*********************************************************************************
* @Function	:  TIMER3定时器中断服务
* @Input		:  None
* @Output		:	 None
* @Return		:  None
* @Others		:	 None
* @Date			:  2022-08-30
**********************************************************************************/
#if GENERAL_TIM3 
void TIM3_IRQHandler(void)   //TIM3中断
{
	U8 i;
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		if(time>0){
			time++;//串口五接收间隔判断
		}
		//满足条件关定时器
		if(time==10000){
			LED2_OFF;
			time=0;
			TIM_Cmd(TIM3, DISABLE); //关闭定时器
		}
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
	}
}
#endif

3.串口防止掉帧使用等

道理相同,我们主要是防止串口出现丢包情况。所以配置一个定时器检测他的接收情况 ,如果串口在我们规定的时间内没有再有数据的输出,则说明我们的串口数据接收完成

/*********************************************************************************
* @Function	:  TIMER2定时器中断服务
* @Input		:  None
* @Output		:	 None
* @Return		:  None
* @Others		:	 None
* @Date			:  2022-08-30
**********************************************************************************/
#if GENERAL_TIM2 
void TIM2_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		if(Usart5_Time>0){
			Usart5_Time++;//串口五接收间隔判断
		}else if(Usart4_Time>0){
			Usart4_Time++;//串口四接收间隔判断
		}else if(Usart3_Time>0){
			Usart3_Time++;//串口三接收间隔判断
		}
		//满足条件关定时器
		if(Usart5_Time==10||Usart3_Time==10||Usart4_Time==10){
			TIM_Cmd(TIM2, DISABLE); //关闭定时器
		}
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志
	}
}
#endif

🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎🚎

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:27:45  更:2022-09-04 01:29:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:58:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码