stm32-TIM之基本定时器
Posted lzd626
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32-TIM之基本定时器相关的知识,希望对你有一定的参考价值。
TIM:
STM32F1 系列中,除了互联型的产品,共有8 个定时器,分为基本定时器,通用定时器和高级定时器。基本定时器TIM6 和TIM7 是一个16 位的只能向上计数的定时器,只能定时,没有外部IO。通用定时器TIM2/3/4/5 是一个16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部IO。高级定时器TIM1/8是一个16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有8个外部IO。
TIM分类:
基本定时器框图:
1. 时钟源
定时器时钟TIMxCLK,即内部时钟CK_INT,经APB1 预分频器后分频提供,如果APB1预分频系数等于1,则频率不变,否则频率乘以2,库函数中APB1 预分频的系数是2,即PCLK1=36M,所以定时器时钟TIMxCLK=36*2=72M。
2. 计数器时钟
定时器时钟经过PSC 预分频器之后,即CK_CNT,用来驱动计数器计数。PSC 是一个16 位的预分频器,可以对定时器时钟TIMxCLK 进行1~65536 之间的任何一个数进行分频。 具体计算方式为:CK_CNT=TIMxCLK/(PSC+1)。
3. 计数器
计数器CNT 是一个16 位的计数器,只能往上计数,最大计数值为65535。当计数达到自动重装载寄存器的时候产生更新事件,并清零从头开始计数。
4. 自动重装载寄存器
自动重装载寄存器ARR 是一个16 位的寄存器,这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断。
5. 定时时间的计算
定时器的定时时间等于计数器的中断周期乘以中断的次数。计数器在CK_CNT 的驱动下,计一个数的时间则是CK_CLK 的倒数,等于:1/(TIMxCLK/(PSC+1) ),产生一次中断的时间则等于:1/ (CK_CLK * ARR)。如果在中断服务程序里面设置一个变量time,用来记录中断的次数,那么就可以计算出我们需要的定时时间等于:1/CK_CLK * (ARR+1)*time。
bsp_timbase.h文件:
#ifndef __BSP_TIMEBASE_H #define __BSP_TIMEBASE_H #include "stm32f10x.h" #define BASIC_TIM6 // 使用TIM7时,注释掉该行即可 #ifdef BASIC_TIM6 #define BASIC_TIM TIM6 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM6 //定时周期(从0开始计数) ,得出一次中断的事件为1000/1M=1ms, #define BASIC_TIM_Period 1000-1 //预分频,72MHz/(71+1)= 1MHz,(0时,为1分频) #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM6_IRQn #define BASIC_TIM_IRQHandler TIM6_IRQHandler #else #define BASIC_TIM TIM7 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM7 #define BASIC_TIM_Period 1000-1 #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM7_IRQn #define BASIC_TIM_IRQHandler TIM7_IRQHandler #endif /**************************oˉêyéù?÷********************************/ void BASIC_TIM_Init(void); #endif
bsp_timbase.c文件:
#include "bsp_timbase.h" static void BASIC_TIM_NVIC_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } static void BASIC_TIM_Mode_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE); TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period; TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler; //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM_TimeBaseStructure.TIM_RepetitionCounter=0; TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure); //?????????ж???λ TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update); TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE); TIM_Cmd(BASIC_TIM, ENABLE); } void BASIC_TIM_Init(void) { BASIC_TIM_NVIC_Config(); BASIC_TIM_Mode_Config(); }
中断处理函数:
void SysTick_Handler(void) { } void BASIC_TIM_IRQHandler (void) { if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) { time++; TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update); } }
main.c文件:
#include"stm32f10x.h" #include"bsp_led.h" #include"bsp_timbase.h" volatile uint32_t time = 0; int main(void) { LED_GPIO_Config(); BASIC_TIM_Init(); while(1) { if ( time == 1000 ) //1000 * 1 ms = 1s { time = 0; red_TOGGLE; } } }
以上是关于stm32-TIM之基本定时器的主要内容,如果未能解决你的问题,请参考以下文章