stm32 定时器初步

今天学习STM32 的通用定时器:TIMx (TIM2、TIM3、TIM4 和 TIM5)。

定时器比较复杂,功能繁多,这里我们就说最基本的计数功能。

1.定时器的时钟从哪里来?

定时器的时钟来源有 4 个: 
1)内部时钟(CK_INT)
2)外部时钟模式 1:外部输入脚(TIx) 
3)外部时钟模式 2:外部触发输入(ETR) 
4)内部触发输入(ITRx):使用 A 定时器作为 B 定时器的预分频器(A 为 B 提供时钟) 
这些时钟,具体选择哪个可以通过 TIMx_SMCR 寄存器的相关位来设置。我们的实验选择内部时钟。

注意:这里的 CK_INT时钟是从 APB1 倍频(*1或者*2)的来的:

如果 APB1 的时钟分频数设置为 1,那么就等于PCLK1;

如果 APB1 的时钟分频数设置不等于1,那么就等于PCLK1*2。

本实验中,APB1的预分频=2,所以TIMxCLK = PCLK1 * 2 = 36MHz * 2 = 72MHz.


看图就明白了。

stm32 定时器初步_第1张图片


2.两个关键的参数

1)  PSC[15:0]:预分频器的值 (Prescaler value) 

计数器的时钟频率CK_CNT等于F_CK_PSC /(PSC[15:0]+1)。 

假设我们的PSC[15:0]取值是7199,那么F_timx = 72MHz / 7200 = 10KHz,T = 1/10000 s 

2)     ARR[15:0]: 自动重装载的值 (Auto reload value) 

假设我们令其等于4999,如果设置了更新中断,那么中断的周期是 (4999+1)* 1/10000 s = 0.5s


3.代码怎么写?

//TIM3的初始化
//时钟是72M
//arr : 自动重装载值
//psc: 预分频值

void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //外设时钟使能
	
	//TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //自动重装载值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //预分频值
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); 
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //使能更新中断

	//中断优先级配置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  


	TIM_Cmd(TIM3, ENABLE);  //开启时钟		 
}
中断程序如下

//定时器3的中断服务程序
void TIM3_IRQHandler(void)   
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //发生了更新中断
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清除中断标志
		LED1=!LED1;  //LED翻转
	}
}
主函数如下

int main(void)
{	
	delay_init();	    	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断分组
	
 	LED_Init();			     //LED初始化
	TIM3_Int_Init(4999,7199);//定时器3初始化
	// T = 1/[72MHz/(7199+1)] * (4999+1) s = 0.5s
   	while(1)
	{
		LED0=!LED0;
		delay_ms(200);		   
	}	 
}

实验结果:LED0每隔200ms 翻转一次,LED1 每隔500ms翻转一次。

仿真结果:

stm32 定时器初步_第2张图片


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