正点原子STM32F103(精英版)------通用定时器实验

三种STM32定时器区别

定时器种类

位数

计数器模式

产生DMA请求

捕获/比较通道

互补输出

特殊应用场景

高级定时器

TIM1,TIM8)

16

向上,向下,向上/

可以

4

带死区控制盒紧急刹车,可应用于PWM电机控制

通用定时器(TIM2~TIM5

16

向上,向下,向上/

可以

4

通用。定时计数,PWM输出,输入捕获,输出比较

基本定时器

(TIM6,TIM7)

16

向上,向下,向上/

可以

0

主要应用于驱动DAC

通用定时器功能特点描述 

STM3 的通用 TIMx (TIM2TIM3TIM4 和 TIM5)定时器功能特点包括:

位于低速的 APB1 总线上 (APB1)
16  位向上、向下、向上 / 向下 ( 中心对齐 ) 计数模式,自动装载计数器( TIMx_CNT )。
16  位可编程 ( 可以实时修改 ) 预分频器 ( TIMx_PSC ) ,计数器时钟频率的分频系数 为  1 65535  之间的任意数值。
个独立通道( TIMx_CH1~4 ),这些通道可以用来作为: 
输入捕获 
输出比较
③  PWM  生成 ( 边缘或中间对齐模式
单脉冲模式输出 
可使用外部信号( TIMx_ETR )控制定时器和定时器互连(可以用  个定时器控制另外一个定时器)的同步电路。

如下事件发生时产生中断/DMA6个独立的IRQ/DMA请求生成器): 

触发事件更新:计数器向上溢出/ 向下溢出,计数器初始化 ( 通过软件或者内部 / 外部触发
( 计数器启动、停止、初始化或者由内部 / 外部触发计数
输入捕获 
输出比较 
支持针对定位的增量 ( 正交 ) 编码器和霍尔传感器电路 
触发输入作为外部时钟或者按周期的电流管理
STM32  的通用定时器可以被用于:
测量输入信号的脉冲长度 ( 输入捕获 ) 或者产生输出波形 ( 输出比较和  PWM) 等。  
使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。 STM32  的每个通用定时器都是完全独立的,没有互相共享的任何资源。

计数器模式

通用定时器可以向上计数、向下计数、向上向下双向计数模式。

①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

 通用定时器工作过程:

 

 

 

 

 

时钟选择

计数器时钟可以由下列时钟源提供:

内部时钟 (CK_INT)
外部时钟模式 1 :外部输入脚 ( TIx )
外部时钟模式 2 :外部触发输入 (ETR)
内部触发输入 ( ITRx ) :使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器 Timer1 而作为另一个定时器 Timer2 的预分频器。

内部时钟选择

 时钟计算方法:

 除非APB1的分频系数是1,否则通用定时器的时钟等于APB1时钟的2倍。

默认调用SystemInit函数情况下:

SYSCLK=72M

AHB时钟=72M

APB1时钟=36M

所以APB1的分频系数=AHB/APB1时钟=2

所以,通用定时器时钟CK_INT=2*36M=72M

定时器中断实验相关寄存器

计数器当前值寄存器CNT

预分频寄存器TIMx_PSC 

 自动重装载寄存器(TIMx_ARR)

控制寄存器1TIMx_CR1 

 DMA中断使能寄存器(TIMx_DIER

常用库函数 

定时器参数初始化:

         void TIM_TimeBaseInit(TIM_TypeDef* TIMx,

                                            TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

typedef struct
{
  uint16_t TIM_Prescaler;        
  uint16_t TIM_CounterMode;     
  uint16_t TIM_Period;        
  uint16_t TIM_ClockDivision;  
  uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef; 


TIM_TimeBaseStructure.TIM_Period = 4999; TIM_TimeBaseStructure.TIM_Prescaler =7199; TIM_TimeBaseStructure.TIM_ClockDivision =   TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode =   TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 

定时器使能函数:

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)

定时器中断使能函数:

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

状态标志位获取和清除

FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

定时器中断实现步骤

能定时器时钟。

       RCC_APB1PeriphClockCmd();

 初始化定时器,配置ARR,PSC

      TIM_TimeBaseInit();

开启定时器中断,配置 NVIC

      void TIM_ITConfig();

      NVIC_Init();

 使能定时器。

      TIM_Cmd();

 编写中断服务函数。

      TIMx_IRQHandler();

程序要求

通过定时器中断配置,每500ms中断一次,然后中断服务函数中控制LED实现LED1状态取反(闪烁)。

选择通用定时器就可以TIM2-5

设置500ms,只要ARR,PSC不超过16位的最大值就可以,最后结果为500ms

LED0每200ms翻转一次,LED1每500ms翻转一次

timer.c

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

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

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
	
	//定时器TIM2初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


	TIM_Cmd(TIM2, ENABLE);  //使能TIMx					 
}
//定时器3中断服务程序
void TIM2_IRQHandler(void)   //TIM2中断
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM2更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志 
		LED1=!LED1;
		}
}












main.c

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

 

	
 int main(void)
 {		
 
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
 	LED_Init();			     //LED端口初始化
	TIM2_Int_Init(4999,7199);//10Khz的计数频率,计数到5000为500ms  
   	while(1)
	{
		LED0=!LED0;
		delay_ms(200);		   
	}	 

 
}	 
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值