zoukankan      html  css  js  c++  java
  • 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.


    看图就明白了。



    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翻转一次。

    仿真结果:




  • 相关阅读:
    51Nod 1267 4个数和为0 二分
    51Nod 1090 3个数和为0 set 二分优化
    51Nod 1001 数组中和等于K的数对 Set
    Codeforces 890C
    Codeforces 890B
    Codeforces 890A
    51nod 1058 N的阶乘的长度 位数公式
    C#调用本机摄像头
    读取、写入excel数据
    数据库笔记--基本应用
  • 原文地址:https://www.cnblogs.com/longintchar/p/5224423.html
Copyright © 2011-2022 走看看