首页 > 代码库 > cortex_m3_stm32嵌入式学习笔记(八):定时器中断实验

cortex_m3_stm32嵌入式学习笔记(八):定时器中断实验

STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器。

本节学习通用定时器 TIM3

STM32 的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。

STM3 的通用 TIMx (TIM2、 TIM3、 TIM4 和 TIM5)定时器功能包括:
1)16 位向上、向下、向上/向下自动装载计数器( TIMx_CNT)。
2)16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~
65535 之间的任意数值。
3) 4 个独立通道( TIMx_CH1~4),这些通道可以用来作为:
A.输入捕获
B.输出比较
C. PWM 生成(边缘或中间对齐模式)
D.单脉冲模式输出
4)可使用外部信号( TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外
一个定时器)的同步电路。
5)如下事件发生时产生中断/DMA:
A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
C.输入捕获
D.输出比较
E.支持针对定位的增量(正交)编码器和霍尔传感器电路
F.触发输入作为外部时钟或者按周期的电流管理



本实验是实现TIM3的更新中断。

TIM3相关配置文件 timer.c

#include "led.h"
#include "timer.h"
//arr:自动重装值。
//psc:时钟预分频数
void TIM3_Int_Init(u16 arr,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_ist;
	NVIC_InitTypeDef NVIC_ist;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //①时钟 TIM3 使能
	//定时器 TIM3 初始化
  TIM_ist.TIM_Period = arr; //设置自动重装载寄存器周期的值
  TIM_ist.TIM_Prescaler =psc; //设置时钟频率除数的预分频值
  TIM_ist.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
  TIM_ist.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数
  TIM_TimeBaseInit(TIM3, &TIM_ist);  //②初始化 TIM3
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );  //③允许更新中断
	NVIC_ist.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_ist.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_ist.NVIC_IRQChannelSubPriority=3;
	NVIC_ist.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_ist);
	
	TIM_Cmd(TIM3, ENABLE);  //⑤使能 TIM3
}
//中断服务程序
void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除 TIM3 更新中断标志,(<span style="color:#ff6600;">很重要的</span>)
		LED1=!LED1;
	}
}

定时器的溢出时间计算公式如下:

Tout(溢出时间)= ((arr+1)*(psc+1))/Tclk;

Tclk为TIM3 的输入时钟频率(单位为 Mhz)(72Mhz)。
假如我们传入的参数为arr=4999 psc=7199 得到的溢出时间为500ms 意味着每500ms变会触发一次更新中断(LED1闪烁)当TIM3溢出后就会重新加载0,然后在向上计数(在初始化函数中选了向上计数模式)直到溢出后又会发生更新中断。。

timer.h
#ifndef _TIMER_
#define _TIMER_
#include "sys.h"
void TIM3_Int_Init(u16 arr,u16 psc);
void TIM3_IRQHandler(void);
#endif

主函数
#include "led.h"
#include "sys.h"
#include "timer.h"
#include "delay.h"
#include "usart.h"
void init(void)
{
	delay_init();
	LED_Init();
	NVIC_Configuration();
	uart_init(9600);
	TIM3_Int_Init(4999,7199);//溢出时间为500ms
}

int main(void)
{
	init();
	while(1)
	{
		LED0=!LED0;	
		delay_ms(250);
	}
}



最终会看到LED0和LED1 一直闪烁,但LED0的闪烁频率比LED1高(一倍)




cortex_m3_stm32嵌入式学习笔记(八):定时器中断实验