STM32 clock and timer

Clock Source

STM32 includes five clock sources, respectively, HSI, HSE, LSI, LSE, PLL.

  • HSI is the high-speed internal clock, the RC oscillator frequency is 8MHz;
  • HSE is a high-speed external clock, i.e. the crystal oscillator connected to crystal / ceramic resonator or receive an external clock source, the frequency range of 4MHz ~ 16MHz;
  • LSI low-speed internal clock, the RC oscillator frequency of 40kHz;
  • LSE is a low-speed external clock, then 32.768kHz crystal, as the RTC clock source;
  • PLL is a phase locked loop frequency output, the clock input source selected to HSI / 2, HSE or HSE / 2. Alternatively multiplier 2 to 16 times, but it must not exceed the maximum output frequency of 72MHz;

Timer TIM2 ~ TIM7 APB1 mount the divider, TIM1 and mount the APB2 TIM8 divider; mount APB1 above are low-speed peripherals, mounted on a high-speed peripheral APB2. APB2 can operate at 72MHz, while the maximum is APB1 36MHz .

Route generating timer: system clock -> prescaler the AHB -> APB2 and prescaler -> TIM1 multiplier -> system clock generated TIM1

In system_stm32f10x.c file with the default definition SYSCLK_FREQ_72MHz, while calling the SetSysClock in SystemInit () function (), based on macro definitions set the clock to 72MHz. SystemCoreClock read to obtain a variable system clock frequency .

By default, each clock frequency of the system is as follows:

  • SYSCLK:72M
  • AHB: 72M
  • APB1(PCLK1):36M
  • APB2(PCLK2):72M
  • PLL:72M

 The type of timer

  • TIM1 and TIM8 senior Timer
  • TIM2-TIM5 is a general-purpose timer
  • TIM6 and TIM7 basic timer

Are eight 16-bit timers, their addition to the basic types of counters and timers TIM6 TIM7 other support up, down, up / down counting modes three.

Three kinds of count mode of the counter

  • 向上计数模式:从0开始,计到arr预设值,产生溢出事件,返回重新计时
  • 向下计数模式:从arr预设值开始,计到0,产生溢出事件,返回重新计时
  • 中央对齐模式:从0开始向上计数,计到arr产生溢出事件,然后向下计数,计数到1以后,又产生溢出,然后再从0开始向上计数。(此种技术方法也可叫向上/向下计数)

各定时器的主要功能

基本定时器(TIM6、TIM7)的主要功能:

只有最基本的定时功能,基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。主要用于产生DAC触发信号。

通用定时器(TIM2~TIM5)的主要功能:

除了基本的定时器的功能外,还具有测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)

高级定时器(TIM1、TIM8)的主要功能:

高级定时器不但具有基本/通用定时器的所有的功能外,还具有控制交直流电动机所有的功能,比如它可以输出6路互补带死区的信号,刹车功能等等。

详细的定时器设定如下:

  1. 首先要搞清楚定时器的计数时钟频率,在预分频系数≠1的时候,TIM2~7的时钟频率为APB1的频率的2倍,即72MHz,预分频系数的默认值不是1。
  2. 定时器的设置主要包括定时器的初始化和中断的初始化。

定时器的时钟不是直接来自APB1或APB2,而是来自输入为APB1或APB2的一个倍频器,当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率的两倍

假定AHB=36MHz,因为APB1允许的最大频率为36MHz,所以APB1的预分频系数可以取任意数值;

当预分频系数=1时,APB1=36MHz,TIM2~7的时钟频率=36MHz(倍频器不起作用);

当预分频系数=2时,APB1=36MHz/2=18MHz,在倍频器的作用下,TIM2~7的时钟频率=36MHz;

当预分频系数=4时,APB1=36MHz/4=9MHz,在倍频器的作用下,TIM2~7的时钟频率=18MHz;

当预分频系数=8时,APB1=36MHz/8=4.5MHz,在倍频器的作用下,TIM2~7的时钟频率=9MHz;

当预分频系数=16时,APB1=36MHz/16=2.25MHz,在倍频器的作用下,TIM2~7的时钟频率=4.5MHz;

既然需要TIM2~7的时钟频率=36MHz,为什么不直接取APB1的预分频系数=1呢?这是因为APB1不但要为TIM2~7提供时钟,而且还要为其它外设提供时钟,设置这个倍频器可以在保证其它外设使用较低时钟频率时,TIM2~7仍能得到较高的时钟频率。例如当AHB=72MHz时,APB1的预分频系数必须大于2,因为APB1的最大频率只能为36MHz。如果APB1的预分频系数=2,则因为这个倍频器,TIM2~7仍然能够得到72MHz的时钟频率。能够使用更高的时钟频率,无疑提高了定时器的分辨率,这也正是设计这个倍频器的初衷。

定时器初始化:

首先定义TIM_TimeBaseInitTypeDef类型的结构体,它包含了如下的内容:

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_Prescaler 是定时器预分频值,时钟源经该预分频器才是定时器时钟,它设定TIMx_PSC 寄存器的值。可设置范围为 0 至 65535,实现 1至 65536 分频。

第二项 TIM_CounterMode 为定时器计数模式,它的内容如下:

#define TIM_CounterMode_Up                 ((uint16_t)0x0000)
#define TIM_CounterMode_Down               ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)

它可以是向上计数、向下计数以及三种中心对齐模式。基本定时器只能是向上计数,即 TIMx_CNT只能从0开始递增,并且无需初始化。

第三项 TIM_Period 为定时器周期,当计数寄存器的值递增到等于该值时,将相关事件标志位置位。范围为0 至 65535。

第四项 TIM_ClockDivision 为时钟分频,设置定时器时钟 CK_INT 频率与数字滤波器采样时钟频率分频比,基本定时器没有此功能,不用设置。

第五项 TIM_RepetitionCounter 为重复计数器,属于高级控制寄存器专用寄存器位,利用它可以非常容易控制输出 PWM 的个数。一般的定时器不需要设置。

循环定时时间的计算:基本定时器只有内部时钟72MHz,定时器的实际时钟=内部时钟 / ( 定时器预分频值 + 1 ),那么如果 TIM_Prescaler 设置为7200-1,则内部时钟源经过定时器预分频后即可得到 (72MHz / (7200-1)+1)=10kHz的频率。然后 TIM_Period 设置为5000-1(因为计数是从0开始,所以要减1),即可得到定时时间为(5000 * (1 / 10kHz))=0.5s的定时器。

除此之外还要设置中断的类型,一般的定时器为更新中断,即由溢出事件产生的中断,设置的方式为:TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE),其中第一项是定时器代号,第二项为类型,这里设定为更新方式,第三项为使能。

TIM3的初始化函数:

void TIM3_Init(u16 arr,u16 psc)
{
     // 定时时间=(arr+1)*(psc+1)/72 单位为us
    TIM_TimeBaseInitTypeDef TIM_STR;
    NVIC_InitTypeDef NVIC_STR;
    // TIM3挂载在APB1上,由于预分频系数默认不是1,所以TIM3的时钟为2*APB1=72M
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    //初始化定时器
    TIM_STR.TIM_Period=arr;
    TIM_STR.TIM_Prescaler=psc;
    // (arr+1)*(psc+1)/TIM时钟=定时器溢出中断触发周期
    TIM_STR.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_STR.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3,&TIM_STR);
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
    // 初始化中断
    // 设定为TIM3中断
    NVIC_STR.NVIC_IRQChannel=TIM3_IRQn;
    // 先占优先级0级
    NVIC_STR.NVIC_IRQChannelPreemptionPriority=0;
    // 从优先级3级
    NVIC_STR.NVIC_IRQChannelSubPriority=3;
    // IRQ通道时能
    NVIC_STR.NVIC_IRQChannelCmd=ENABLE;
    // 中断初始化
    NVIC_Init(&NVIC_STR);
    // 使能定时器
    TIM_Cmd(TIM3,ENABLE);
}

中断服务函数:

TIM3的中断函数为 TIM3_IRQHandler

中断服务函数内包含了:判断是否发生中断、中断发生后执行的内容、清除标志位三部分。

void TIM3_IRQHandler(void)
{
    // 判断是否发生中断
    if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
    {
        // 清除标志位
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
        // 执行中断内容
    }
}

  

Guess you like

Origin www.cnblogs.com/xi-jie/p/12378331.html