关于stm:32和51单片机的定时计数器

63次阅读

共计 4672 个字符,预计需要花费 12 分钟才能阅读完成。

51 单片机的定时计数器

定时 / 计数器的核心部件是一个加法(或减法)计数器;若计数脉冲来自零碎时钟,则为定时形式;若计数脉冲来自单片机内部引脚,则为计数形式。

根本介绍

定时器:

  • 定时器是 SOC 的外部外设。
  • 定时器就是 CPU 的闹钟。

计数器:

  • 单片机实现定时器其实质是用计数器来实现的。
  • 计数器能够计算内部脉冲的个数。
  • 当单片机计算外部脉冲个数时就相当于定时器,当计算内部脉冲个数就相当于计数器。

加法计数器和减法计数器:(51 单片机是加法计数器)

  • 加法计数器:从咱们给定的值开始加,加到溢出,而后触发中断。

    • 例如:16 位定时器最大计数 65535 次,如果咱们想计数 50000 次,那么设置的 TH 和 TL 应设为 65535-50000 = 15535。
  • 减法计数器;从咱们给定的值开始减,减到 0 就溢出,而后触发中断。

    • 例如:16 位定时器最大计数 65535 次,如果咱们想计数 50000 次,那么设置的 TH 和 TL 应设为 50000。
  • 计算 TL 和 TH:

    • 首先确定定时工夫,time(例如 50ms)。
    • 确定外部时钟周期,因为是 12T 模式,晶振 12MHz,所以外部频率 1MHz,周期 1us。
    • 定时计个数 = time ÷ 周期。(50000)
    • TL1 = 个数 % 256(取余);TH1 = 个数 / 256(取整)。

工作流程

  1. 设置定时器时钟源(作定时器应用时,须要外部的脉冲,这个脉冲来源于时钟源)
  2. 初始化定时器相干寄存器。
  3. 设置定时工夫(计数个数)
  4. 设置中断处理程序。
  5. 关上定时器。
  6. 运行时:定时器计数到设置值后产生中断,执行中断处理程序。

定时 / 计数器相干寄存器。

管制寄存器 TCON

  • TF1:定时器 / 计数器 T1 溢出标记位。T1 被容许计数后,从初值开始加一,计数实现后由硬件置位,收回中断请求;中断响应后硬件主动复位。
  • TR1:定时器 T1 容许管制位,由软件置位和清零。GATE(TMOD.7)= 0,TR1 = 1 时才容许 T1 开始计数。
  • IE1:内部中断 1 申请源标记。IE1 = 1,内部中断向 CPU 申请中断,CPU 响应后由硬件清零。、
  • IT1:内部中断 1 触发形式管制位。IT1 = 0 时,内部中断 1 为低电平触发形式;IT1 = 1 时,内部中断 1 为高电平触发形式。

工作模式寄存器 TMOD

  • GATE(TMOD.7):与 TCON.6(TR1)配合管制定时器运行
  • C/T(TMOD.6): 管制定时器 1 用作定时器还是计数器。清零用作定时器,置一用作计数器。
  • M1/M0(TMOD.5/TMOD4): 定时计数器模式抉择位。
  • (00)模式 0(13 位定时器 / 计数器);(01)模式 1(16 位定时器 / 计数器模式);(10)模式 2(8 位主动重装模式);(11)模式 3(两个 8 位定时器 / 计数器)。

示例代码

//TIM1 定时器初始化
void TIM1_Init()
{
    TMOD = 0x10;           // T0 设置工作在定时器模式下,模式一 16 位定时器
    TL1 = (65535 - 50000) % 256;    
    TH1 = (65535 - 50000) / 256;
    TR1 = 1;            // 开启计数器,开始计数了
    ET1 = 1;            // 开启 T1 中断
    EA = 1;                // 开启中断总开关

    count = 10;            // 10 次,对应 500ms
}

//TIM1 中断处理程序;定时 500ms
void timer1_isr(void) interrupt 1 using 1
{TL1 = (65535 - 50000) % 256;    
    TH1 = (65535 - 50000) / 256;            // 手工重装载计数值
    // 因为模式一不能主动重装载,所以要手工重装载计数值。if (count-- == 0)
    {
        // 阐明曾经中断了 10 次了,500ms 到了,该干活了
        LED = !LED;                // LED 取反
        count = 10;
    }
}

STM32 单片机的定时 / 计数器

独立看门狗(IWDG)

  • 当计数器达到给定的超时值时会产生零碎复位。
  • 独立看门狗 (IWDG) 由专用的低速时钟 (LSI) 驱动,即便主时钟产生故障它也依然无效。
  • 独立看门狗(IWDG)是减法计数器。
  • 看门狗被激活后,则在计数器计数至 0x000 时产生复位(复位的意思是指从 0xfff 开始递加)
  • 独立看门狗能够在任何时候进行喂狗操作。喂狗后,计数器从设定的值开始计数。
  • IWDG 最适宜利用于那些须要看门狗作为一个在主程序之外(次要是为了避免程序跑飞),可能齐全独立工作,并且对工夫精度要求较低的场合。

窗口看门狗(WWDG)

  • 当计数器达到给定的超时值时会产生零碎复位或触发一个中断。
  • 窗口看门狗由从 APB1 时钟分频后失去的时钟驱动。
  • 窗口看门狗(WWDG)是减法计数器。
  • 窗口看门狗(WWDG)喂狗工夫有严格控制。必须要在规定的工夫内(窗口)喂狗才无效。如果在其余工夫喂狗则会产生复位,如果在窗口没有喂狗,则计数完后也会产生复位。
  • WWDG 最适宜那些要求看门狗在准确计时窗口起作用的应用程序。

通用定时器(TIMx)((TIM2、TIM3、TIM4、TIM5)

TIMx 简介

  • 16 位向上(加法计数)、向下(减法计数)、向上 / 向下主动装载计数器。
  • 向上 / 向下计数(地方对齐模式):计数器从 0 加到(设定值 -1)触发溢出中断,再从(设定值 -1)减到 1 触发下溢中断。
  • 加法计数和减法计数:例如想计数 500 次,加法计数器是从 0 开始计数到 500,而减法计数器是从 500 减到 0。
  • 性能:输出捕捉、输入比拟、PWM。
  • 16 位可编程 (能够实时批改) 预分频器,计数器时钟频率的分频系数为 1~65536 之间的任意数值。(计数器的时钟频率是由下级频率通过预分频器分频失去的,下级频率每个定时器可能不同,可能是 APB1 或 APB2,下级频率设置办法请查看另外一篇文章“STM32 时钟体系”)
  • 计数器、主动装载寄存器和预分频器寄存器能够由软件读写,在计数器运行时仍能够读写。
  • 计数器由预分频器的时钟输入 CK_CNT 驱动,仅当设置了计数器 TIMx_CR1 寄存器中的计数器使能位 (CEN) 时,CK_CNT 才无效。
  • 主动重装载寄存器、预装载寄存器、影子寄存器、计数器关系:(集体了解,不肯定对)

    • ARPE:管制寄存器 1(TIMx_CR1)中预装载寄存器容许位。(0:不应用预装载寄存器)
    • 计数器是计算次数的,而影子寄存器则是用来与计数器做比拟的。(实用于加法计数中)
    • 例如:以后计数值为 500,当初想将计数个数改为 1000。
    • 当 APRE 为 0 时:先将 1000 写入主动重装载寄存器,主动重装载寄存器立马将 1000 装入影子寄存器中。以后计数到 1000 后才触发中断,而不是 500。
    • 当 APRE 为 1 时:先将 1000 写入主动重装载寄存器,主动重装载寄存器将 1000 写入预装载寄存器中,当此次计数实现即计数到 500 后触发中断,预装载寄存器才将 1000 写入影子寄存器中。下次计数到 1000 触发中断。

TIMx 寄存器形容

管制寄存器 1(TIMx_CR1)

  • 复位值:0x0000
  • CKD: 时钟分频因子
  • ARPE:主动重装载预装载容许位(1:容许预装载)
  • CMS:抉择地方对齐模式。
  • DIR:抉择计数方向(0 上 1 下)
  • URS:URS:更新申请源(1:如果使能了更新中断或 DMA 申请,则只有计数器溢出 / 下溢才产生更新中断或 DMA 申请)
  • UDIS:禁止更新(1:禁止更新,不触发任何中断或事件)
  • CEN:使能计数器(1:使能计数器)

DMA/ 中断使能寄存器(TIMx_DIER)

  • 复位值:0x0000
  • TDE:容许触发 DMA 申请(1:容许)
  • UDE:容许更新的 DMA 申请(1:容许)
  • TIE:触发中断使能(1:使能触发中断)
  • UIE:容许更新中断(1:容许更新中断)
  • 中断服务程序程序执行完当前,要把中断关上(即把标记地位位),以便下一次还能触发该中断。这就是更新中断。

状态寄存器(TIMx_SR)

  • 复位值:0x0000
  • TIF:触发器中断标记(当产生触发事件时由硬件对该地位一,它由软件清零)(1:触发器中断期待响应)
  • UIF:更新中断标记(当产生更新事件时该位由硬件置一。它由软件清零)(1:更新中断期待响应)

事件产生寄存器(TIMx_EGR)

  • 复位值:0x0000
  • TG:产生触发事件,由软件置一硬件清零(1:当 TIMx_SR 寄存器的 TIF=1,若开启对应的中断和 DMA,则产生相应的中断和 DMA。)
  • UG:产生更新事件,由软件置一硬件清零(1:从新初始化计数器,并产生一个更新事件。)

示例



/*******************************************************************************
* 函 数 名         : TIM4_Init
* 函数性能           : TIM4 初始化函数
* 输    入         : per: 重装载值
                     psc: 分频系数
* 输    出         : 无
*******************************************************************************/
void TIM4_Init(u16 per,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);// 使能 TIM4 时钟
    
    TIM_TimeBaseInitStructure.TIM_Period=per;   // 主动装载值
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc; // 分频系数
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;            // 设置 CKD 时钟分频因子
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; // 设置向上计数模式
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
    
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); // 开启定时器中断
    TIM_ClearITPendingBit(TIM4,TIM_IT_Update);    // 革除中断挂起位
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;// 定时器中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;// 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;        // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ 通道使能
    NVIC_Init(&NVIC_InitStructure);    
    
    TIM_Cmd(TIM4,ENABLE); // 使能定时器    
}

/*******************************************************************************
* 函 数 名         : TIM4_IRQHandler
* 函数性能           : TIM4 中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void TIM4_IRQHandler(void)
{if(TIM_GetITStatus(TIM4,TIM_IT_Update))
    {led2=!led2;}
    TIM_ClearITPendingBit(TIM4,TIM_IT_Update);    
}


正文完
 0