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交替闪烁。

相关推荐
weixin_456808383 小时前
【沁恒蓝牙开发】ADC DMA定时采样、转化
单片机·嵌入式硬件
华普微HOPERF4 小时前
MCU+BLE射频+丰富外设,BLE SoC如何高效传输数据?
单片机·嵌入式硬件
振南的单片机世界4 小时前
时钟开关:不用的外设,把它的时钟关掉,省电!
stm32·单片机·嵌入式硬件
金色光环4 小时前
SCPI添加错误码
stm32·scpi
iCxhust5 小时前
将8088 BootLoader分拆烧写到8086 ROM中
stm32·单片机·嵌入式硬件·51单片机·微机原理
国科安芯6 小时前
商业航天电机控制领域抗辐射 MCU 芯片应用研究
网络·单片机·嵌入式硬件·安全性测试
charlie1145141916 小时前
嵌入式C++工程实践第20篇:GPIO 输入模式内部电路 —— 芯片是如何“听“到外部信号的
开发语言·c++·stm32·单片机
电子科技圈6 小时前
芯科科技在蓝牙亚洲大会展示汽车与边缘AI前沿蓝牙创新技术, 解锁车用、家居、健康及工商业等应用场景
人工智能·科技·嵌入式硬件·mcu·物联网·网络安全·汽车
不吃鱼的羊7 小时前
DISC 性格测评理论
嵌入式硬件