STM32学习笔记7 正点原子miniSTM32通用定时器中断实验

初学者学习总结,如有错误,请大神指正


一、STM32 通用定时器

1.1 通用定时器简介

1)通用定时器(在stm32中包括(TIM2、TIM3、TIM4 、 TIM5)是一个通过可编程预分频器驱动的16位自动装载计数器构成。

2)它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)。

3)使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个 毫秒间调整。

4)每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操。

1.2 主要功能

1)16位向上、向下、向上/向下自动装载计数器(TIMx_CNT)

2)16位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为1~65536之          间的任意数值

3)4个独立通道:

     A.输入捕获

     B.输出比较

     C.PWM 生成(边缘或中间对齐模式)

     D.单脉冲模式输出       

4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定       时器)的同步电路。

5)如下事件发生时产生中断/DMA:

     A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

     B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

     C.输入捕获

     D.输出比较

5)支持针对定位的增量(正交)编码器和霍尔传感器电路

6)触发输入作为外部时钟或者按周期的电流管理

1.3 相关寄存器

1.3.1 控制寄存器 1(TIMx_CR1)

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第1张图片

在 TIMx_CR1 寄存器中,将最低位,也就是计数器使能位 置1, 才能让定时器开始计数。 

1.3.2 DMA/中断使能寄存器(TIMx_DIER)

TIMx_DIER的第 0 位,是更新中断允许位,要用到定时器的更新中断,需要将该位要置 1,来允许由于更新事件所产生的中断。 

1.3.3  预分频寄存器(TIMx_PSC)

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第2张图片

TIMx_PSC用来设置对时钟进行分频,然后提供给计数器,作为计数器的时钟。 

这里,定时器的时钟来源有 4 个:

1)内部时钟(CK_INT)

2)外部时钟模式 1:外部输入脚(TIx)

3)外部时钟模式 2:外部触发输入(ETR)

4)内部触发输入(ITRx):使用 A 定时器作为 B 定时器的预分频器(A 为 B 提供时钟)。 这些        时钟,具体选择哪个可以通过 TIMx_SMCR 寄存器的相关位来设置。这里的 CK_INT 时钟是          从 APB1倍频的来的,STM32 中除非APB1 的时钟分频数设置为 1,否则通用定时器TIMx 的          时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等于          APB1 的时钟。这里还要注意的就是高级定时器的时钟不是来自 APB1,而是来自 APB2 的。

1.3.4 TIMx_CNT 寄存器

该寄存器是定时器的计数器,该寄存器存储了当前 定时器的计数值。

1.3.5 自动重装载寄存器(TIMx_ARR)

TIMx_ARR在物理上实际对应着 2 个寄存器。 一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器被叫做影子寄存器。事实上真正起作用的是影子寄存器。根据 TIMx_CR1 寄存器中 APRE 位的设置:APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2 者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到 影子寄存器。

1.3.6 状态寄存器(TIMx_SR)

TIMx_SR用来标记当前与定时 器相关的各种事件/中断是否发生。

1.4 通用定时器库函数

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第3张图片

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第4张图片

 1.4.1  TIM_TimeBaseInit    通用定时器初始化配置

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第5张图片

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第6张图片

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第7张图片

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第8张图片

1.4.2 TIM_ITConfig   中断使能

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第9张图片

 1.4.3 TIM_Cmd  定时器使能

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第10张图片

1.4.4 TIM_GetITStatus   中断发生标志 

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第11张图片

例:

 if(TIM_GetITStatus(TIM2, TIM_IT_CC1) == SET)

{

1.4.5 TIM_ClearITPendingBit   中断标志清除

STM32学习笔记7 正点原子miniSTM32通用定时器中断实验_第12张图片

例:

TIM_ClearITPendingBit(TIM2, TIM_IT_CC1); 

二、硬件连接

1) 指示灯 DS0 和 DS1

2) 定时器 TIM3

本章将通过 TIM3 的中断来控制 DS1 的亮灭,DS0 和 DS1 的电路在前面已经有介绍了。TIM3 属于 STM32 的内部资源

三、程序设计

3.1 定时器使用步骤

1)TIM3 时钟使能。

2)初始化定时器参数,设置自动重装值,分频系数,计数方式等。

3)设置 TIM3_DIER 允许更新中断。

4)TIM3 中断优先级设置。

5)允许 TIM3 工作,也就是使能 TIM3。

6)编写中断服务函数。

3.2 程序代码

3.2.1  timer.c

#include "timer.h"
#include "led.h"

 

//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到5000为500ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(  //使能或者失能指定的TIM中断
		TIM3, //TIM2
		TIM_IT_Update ,
		ENABLE  //使能
		);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设
							 
}

void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
		{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源 
		LED1=!LED1;
		}
}

3.2.2 main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"

 int main(void)
 {	
	delay_init();	    	 //延时函数初始化
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	LED_Init();		  	//初始化与LED连接的硬件接口
	TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms  
   	while(1)
	{
		LED0=!LED0;
		delay_ms(200);		   
	}
}

你可能感兴趣的:(stm32,单片机,学习)