STM32定时器中断

一、STM32定时器资源介绍

TIMXCLK来源:

简化理解:

  • 2个基本定时器(类似于51单片机中的定时器)
  • 4个通用定时器TIM2~4(每个定时器可输出4路PWM控制舵机等)
  • 两个高级定时器

二、工程实现

新建文件夹及文件:

C文件添加到工程组中:

包含头文件路径:

添加定时器相关库文件到工程组中:

移除不必要的工程组文件:
exti.c key.c
定时器中断使用步骤:

1.初始化配置:

  • 使能TIM时钟,定时器外设是挂在APB1总线上的

  • TIM_TimeBaseInit初始化(配置计时时间、计数模式)

  • 使用定时器的某个中断类型作为NVIC的中断(如TIM_IT_Update更新中断)

  • TIM_ClearITPendingBit清除 TIM 的中断待处理位

  • 初始化NVIC(设置两组优先级)

  • TIM_Cmd开启定时器
    2.中断服务函数实现:

  • TIM_GetITStatus检查指定的 TIM 某一类型中断发生与否

  • 中断发生则实现具体操作

  • 清除 TIM 的指定中断待处理位,函数退出
    time.h

    #ifndef __TIME_H
    #define __TIME_H

    #include "system.h"

    void TIM4_Init(u16 per, u16 psc);

    #endif

time.c

复制代码
#include "time.h"


void TIM4_Init(u16 per, u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
	NVIC_InitTypeDef NVIC_InitStructure; 
	
	//1.使能时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //使能TIM4时钟,定时器外设是挂在APB1总线上的

	//2.初始化TIM
	//中断触发时间T =  自动重装载寄存器值per * 计数一次对应的时间 = 自动重装载寄存器值per * ((psc+1)/(CLK))s,其中CLK为72M。
	//以500ms为例:T = 1000 * ((35999+1)/(72000000))s = 1000 * (1/2000)s = 0.5s = 500ms
	//TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。它的取值必须在 0x0000 和0xFFFF 之间。这里由参数传入
	TIM_TimeBaseStructure.TIM_Period = per; 
	//TIM_Prescaler 设置了用来作为 TIMx 时钟频率除数的预分频值。它的取值必须在 0x0000 和 0xFFFF 之间,即设置分频系数
	TIM_TimeBaseStructure.TIM_Prescaler = psc; 
  //这里一般配置为TIM_CKD_DIV1
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 
	//计数模式设置为向上计数
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);	
	
	//3.开启定时器中断,即使用定时器4的更新中断作为NVIC的中断源,如计数器到达设定自动重装载寄存器值时,触发更新中断
	TIM_ITConfig(TIM4,TIM_IT_Update, ENABLE);
	//4.清除 TIM4 的中断待处理位
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	
	//5.初始化NVIC
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //在"stm32f10x.h"查看
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	//抢占优先级设为2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级设置为2	
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
	NVIC_Init(&NVIC_InitStructure);	
	
	//6.开启定时器
	TIM_Cmd(TIM4, ENABLE);
}

//实现中断服务函数
void TIM4_IRQHandler(void)
{
	//检查指定的 TIM4 TIM_IT_Update更新中断发生与否
	if(TIM_GetITStatus(TIM4, TIM_IT_Update) == SET)
	{
		PCout(1) = !PCout(1); //LED2状态取反
	}
	//清除 TIM4 的更新中断待处理位
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);	
}

main.c

复制代码
#include "system.h"  //已经包含了"stm32f10x.h" 以及定义了位带操作的宏,后续只包含该头文件就可以了
#include "SysTick.h" //使用delay_ms和delay_us

#include "key.h"
#include "led.h" //需要调用Led_Init()对8个LED GPIO初始化
#include "time.h" //TIM4_Init()调用

//这里不用定义SystemInit函数,是因为在system_stm32f10x.c中已有实现

int main()
{
	u8 i = 0;
	
	SysTick_Init(72); //72为SYSCLK delay_ms延时函数需要使用
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组2:2 在使用中断回调函数时都需要调用
	Led_Init();
	////以500ms为例:T = 1000 * ((35999+1)/(72000000))s = 1000 * (1/2000)s = 0.5s = 500ms
	TIM4_Init(1000, 35999); //定时器4初始化以及实现中断回调
	
	while(1)
	{
		i++;
		if(i%20 == 0)
		{
			PCout(4) = !PCout(4); //LED5状态取反 20*10ms = 100ms
		}
		delay_ms(10);	
	}	
}

编译烧录验证:LED2每隔500ms交替闪烁。

相关推荐
清风6666661 天前
基于单片机与DAC0832的双路波形信号发生系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
azwsm1 天前
电路元器件和GPIO控制器
单片机·嵌入式硬件
kebidaixu1 天前
FreeRTOS 移植到 STM32F407VETX 记录(一)
stm32·单片机·嵌入式硬件
CSDN官方博客1 天前
「谁说嵌入式只是调包和焊板子?」—— 2026嵌入式全栈技术征锋令
嵌入式硬件·物联网·embedding
半条-咸鱼1 天前
【INACCESSIBLE_BOOT_DEVICE】安装 Config Tool 后 Windows 蓝屏,最终通过 VMware 虚拟机解决
windows·stm32·vmware·芯片
点灯小铭1 天前
基于单片机的数码管定时插座设计与定时开关功能实现
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
云栖梦泽1 天前
玩转RK3506SDK
linux·嵌入式硬件
数智工坊1 天前
机器人四大主控板系统分层选型指南:树莓派、ESP32、STM32与Arduino的能力边界与实战定位
stm32·嵌入式硬件·机器人
某林2121 天前
跨越底层与AI的鸿沟:ROS2+多模态大模型(Qwen-VL)机器人全链路排障实录
人工智能·stm32·机器人·人机交互·ros2·技术复盘
进击的小头1 天前
第8篇:IGBT 从零到精通:核心原理、关键参数、选型指南与工业级应用要点
经验分享·嵌入式硬件·学习