定时器中断

一、定时器工作原理

  • TIM(Timer)定时器
  • 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
  • 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
  • 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
  • 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型

esp8266定时器中断使用 esp32 定时器中断_引脚

基本定时器

PSC(Prescaler)

CNT(Counter)

ARR(AutoReloaderRegister)

esp8266定时器中断使用 esp32 定时器中断_嵌入式硬件_02

预分频器时序

esp8266定时器中断使用 esp32 定时器中断_单片机_03

计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

一般72M/(PSC+1)

预装载功能:PSC,ARR以及捕获/比较寄存器有

计数器时序

esp8266定时器中断使用 esp32 定时器中断_引脚_04

计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)

一般72M/(PSC+1)/(ARR+1)

预装载功能

esp8266定时器中断使用 esp32 定时器中断_esp8266定时器中断使用_05

通用定时器

TRGI 外部时钟模式1 的输入可以是

  • ETR引脚(外部输入方波)
  • 其他定时器(实现级联)
  • CH1引脚的边沿
  • CH1,CH2引脚

esp8266定时器中断使用 esp32 定时器中断_单片机_06

定时器级联功能表

esp8266定时器中断使用 esp32 定时器中断_引脚_07

高级定时器

esp8266定时器中断使用 esp32 定时器中断_引脚_08

定时中断基本结构

esp8266定时器中断使用 esp32 定时器中断_嵌入式硬件_09

二、定时器中断库函数

esp8266定时器中断使用 esp32 定时器中断_stm32_10

esp8266定时器中断使用 esp32 定时器中断_esp8266定时器中断使用_11

定时器中断

void TIM1_Int_Init(u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;             //时基单元
    NVIC_InitTypeDef NVIC_InitStructure;                       //NVIC
    //TIM_InternalClockConfig(TIM1)                            //时钟选择,上电默认内部时钟,可以不写
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);       //时钟使能(peripheral外围设备)
这里经常不注意,APB12前后要对应
    
    TIM_TimeBaseStructure.TIM_Period = arr;                    //重装载值
    TIM_TimeBaseStructure.TIM_Prescaler = psc;                 //预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;    //时钟分割,用不到(输入的采样频率,可一定程度滤波,或                                                                //者输入时钟的分频)
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;           //高级定时器1和8需要填这个(重复次数计数器)
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);            //初始化定时器时基单元
    TIM_ClearFlag(TIM1,TIM_FLAG_Update);          //为避免一上电就进中断
    TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE );                //定时器中断配置,更新中断

    
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;               
    NVIC_Init(&NVIC_InitStructure);                               //NVIC配置
    TIM_Cmd(TIM1, ENABLE);                                        //使能定时器
}

void TIM1_UP_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
    {

    }
    TIM_ClearFlag(TIM1, TIM_IT_Update );
}
  • 一上电就进中断的问题
    TIM_TimeBaseInit函数中最后一句
    因为预分频器有缓冲寄存器,写的值只有在更新事件时才会真正起作用,为了让值立刻起作用,在最后手动生成了一个更新事件
    这样,预分频器的值就有效了
    但是就会进一次中断

esp8266定时器中断使用 esp32 定时器中断_esp8266定时器中断使用_12

解决:手动把更新中断标志位清除一下TIM_TimeBaseInit后,TIM_ITConfig开中断前

TIM_ClearFlag(TIM1,TIM_FLAG_Update);          //为避免一上电就进中断

定时器外部时钟

接TIMx_ETR引脚

/**
  * @brief  Configures the External clock Mode2  
  * @param  TIMx: where x can be  1, 2, 3, 4, 5 or 8 to select the TIM peripheral. //定时器
  * @param  TIM_ExtTRGPrescaler: The external Trigger Prescaler. //预分频
  *   This parameter can be one of the following values:
  *     @arg TIM_ExtTRGPSC_OFF: ETRP Prescaler OFF.
  *     @arg TIM_ExtTRGPSC_DIV2: ETRP frequency divided by 2.
  *     @arg TIM_ExtTRGPSC_DIV4: ETRP frequency divided by 4.
  *     @arg TIM_ExtTRGPSC_DIV8: ETRP frequency divided by 8.
  * @param  TIM_ExtTRGPolarity: The external Trigger Polarity. //触发极性,上升沿下降沿
  *   This parameter can be one of the following values:
  *     @arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
  *     @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
  * @param  ExtTRGFilter: External Trigger Filter. //滤波
  *   This parameter must be a value between 0x00 and 0x0F
  * @retval None
  */
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
将前面
//TIM_InternalClockConfig(TIM1)                            //时钟选择,上电默认内部时钟,可以不写
改
TIM_ETRClockMode2Config(TIM1,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);

另外配置对应GPIO
并调整ARR PSC

三、定时器中断CubeMX

STM32的定时器开发基础_哔哩哔哩_bilibili

esp8266定时器中断使用 esp32 定时器中断_嵌入式硬件_13


esp8266定时器中断使用 esp32 定时器中断_stm32_14

四、定时器中断寄存器

看数据手册吧