stm32 之定时器回眸一笑

大学马上就要结束了,蓝牙项目也算是告一段落,这一路走来,辛酸与欢笑同在,当程序和PCB不再是主要的矛盾的时候,顿时感觉前方一片坦荡,哈哈~

最后一个寒假,无聊之际好好给自己的stm32补漏一下,写写程序顺便再画个stm32开发板什么的,为年后实习,fighting!!!

stm32 的定时器功能强大,stm32f103vet6芯片上的定时器很早的一篇博客上已经写得很明白了,但是回头一看,还没好好写过定时器配置,惭愧!!!~

后面的定时器配置仅仅是一个普通的定时器TIM3配置,每一秒进一次中断,实现定时和计数。倒不难,只是影子寄存器还是让我卡了一会儿,它的解释直接网上COPY了~

工程下载地址:http://download.csdn.net/detail/xiaoleiacm/8410521


影子寄存器是高级定时器框图的一部分,细心的人可以发现预分频器寄存器、自动重载寄存器和捕捉/比较寄存器下面有一个阴影,其他的寄存器有些也有阴影。
这表示在物理上这个寄存器对应2个寄存器:一个是我们可以可以写入或读出的寄存器,称为预装载寄存器,另一个是我们看不见的、无法真正对其读写操作的,但在使用中真正起作用的寄存器,称为影子寄存器.
数据手册介绍预装载寄存器的内容可以随时传送到影子寄存器,即两者是连通的(permanently),或者在每一次更新事件(UEV)时才把预装载寄存器的内容传送到影子寄存器。
原文如下:
The auto-reload register is preloaded. Writing to or reading from the auto-reload register accesses the preload register. The content of the preload register are transferred into the shadow register permanently or at each update event (UEV), depending on the auto-reload preload enable bit (ARPE) in TIMx_CR1 register. The update event is sent when the counter reaches the overflow (or underflow when downcounting) and if the UDIS bit equals 0 in the TIMx_CR1 register. It can also be generated by software. The generation of the update event is described in detailed for each configuration.
在图中的,表示对应寄存器的影子寄存器可以在发生更新事件时,被更新为它的预装载寄存器的内容;而图中的部分,表示对应的自动重载寄存器可以产生一个更新事件(U)或更新事件中断(UI)。
作用:设计预装载寄存器和影子寄存器的好处是,所有真正需要起作用的寄存器(影子寄存器)可以在同一个时间(发生更新事件时)被更新为所对应的预装载寄存器的内容,这样可以保证多个通道的操作能够准确地同步。如果没有影子寄存器,软件更新预装载寄存器时,则同时更新了真正操作的寄存器,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上例如中断等其它因素,多个通道的时序关系有可能会混乱,造成是不可预知的结果。

 

stm32 之定时器回眸一笑_第1张图片

        下面是例子:

#ifndef _BSP_TIMER_H_
#define _BSP_TIMER_H_
/***************************************************************************************************
当前文档 bsp_timer.h
***************************************************************************************************/  

void NVIC_Configuration(void) ; 
void TIM3_Configuration(void);

#endif 

 

#include "bsp_timer.h"
#include "misc.h"
#include "stm32f10x_tim.h" 	
/***************************************************************************************************
当前文档 bsp_timer.c
***************************************************************************************************/  
/***************************************************************************************************
*\Function      TIM3_Configuration
*\Description   配置定时器TM3
*\Parameter     
*\Return        void
*\Note          
*\Log           2015年1月30日   
*               配置函数。
***************************************************************************************************/  
void TIM3_Configuration(void)
{
     
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;    	 
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   // 使能时钟源

	TIM_DeInit(TIM3);									     
	TIM_InternalClockConfig(TIM3);						   // 使用内部时钟

	//溢出时间 T=(TIM_Period+1)*(TIM_Prescaler+1)/Ftosc		
	TIM_TimeBaseStructure.TIM_Period = 2000 - 1;	         //设置自动重载计数周期值
	TIM_TimeBaseStructure.TIM_Prescaler = 36000 - 1;         //设置分频系数	

	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //设置时钟分频因子	 当前为72Mhz  
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数方式

	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);   // 初始化
	TIM_ClearFlag(TIM3, TIM_FLAG_Update);		     // 清除TIM3 溢出中断
	TIM_ARRPreloadConfig(TIM3, ENABLE);			     //实际影响计数的是影子寄存器,可以通过TIM_ARRPreloadConfig设置为DISABLE 还是ENABLE确定内容是立即更新还是每次UEV事件发生的时候更新这个计数值。	                 

	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);       //   开启TIM3中断
	TIM_Cmd(TIM3, ENABLE);		
}
/***************************************************************************************************
*\Function      NVIC_Configuration
*\Description   配置中断优先级
*\Parameter     
*\Return        void
*\Note          
*\Log           2015年1月30日   
*               配置函数。
***************************************************************************************************/  
void NVIC_Configuration(void)  				         //配置中断优先级
{  
  NVIC_InitTypeDef NVIC_InitStructure;  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  				   
  NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQn ;              //配置定时器中断  TIM3    
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  NVIC_Init(&NVIC_InitStructure);     
}  


最后在中断文档stm32f10x_it.h中写入中断处理函数:

#include  "stm32f10x_tim.h"
 static int flag=1;
 void TIM3_IRQHandler(void)
 {
 	 if(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
	 {
	 	    TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);

			 
	       	 //do someting...
		     if(flag==1)
			  {
			  	  GPIO_ResetBits(GPIOB, GPIO_Pin_5);
				  flag=0;
			  
			  } 
			  else{						   
			  GPIO_SetBits(GPIOB, GPIO_Pin_5); 
			  flag=1;
			  }



	 }
 
 }


 


 

 

 

 

 

 


你可能感兴趣的:(定时器,stm32,定时1秒)