[IMX] 04.定时器 - Timer

发布于:2025-05-20 ⋅ 阅读:(17) ⋅ 点赞:(0)

目录

1.周期中断定时器 - EPIT

1.1.工作模式

1.2.配置寄存器 - EPIT_CR

1.3.状态寄存器 - EPIT_SR

1.4.加载寄存器 - EPIT_LR

1.5.比较寄存器 - EPIT_CMPR

1.6.计数寄存器 - EPIT_CNR

2.通用定时器 - GPT

2.1. 时钟源

2.2.模块结构

2.3.工作模式

2.4.配置寄存器 - GPT_CR

2.5.分频寄存器 - GPT_PR

2.6.状态寄存器 - GPT_SR

2.7.计数寄存器 - GPT_CNT

2.8.比较寄存器 - GPT_OCR

2.9.高精度定时原理


1.周期中断定时器 - EPIT

I.MX6ULL 包含两个 EPIT(Enhanced Periodic Interrupt Timer)定时器,EPIT 是一个 32 位定时器,用于提供精准的定时中断,软件使能后 EPIT 就会开始运行,EPIT 定时器有如下特点:

  • 可选择时钟源:ipg_clk、ipg_clk_32k、ipg_clk_highfreq;

  • 32 位向下计数;

  • 12 位分频,分频值 1~4096;

  • 计数值和比较值相等时产生中断;

其结构如下所示:

图中各模块的功能如下:

  1. 多路选择器:选择 EPIT 定时器的时钟源,EPIT 有 3 个可选时钟源: ipg_clk、ipg_clk_32k、ipg_clk_highfreq;

  2. 12-bit 分频器:对时钟源进行分频,12-bit 对应的值是 0~4095,对应 1~4096 分频;

  3. 经过分频的时钟信号进入 EPIT 内部,EPIT 内部有三个重要的寄存器:

    1. 32-bit 计数寄存器 EPIT_CNR;

    2. 32-bit 加载寄存器 EPIT_LR;

    3. 32-bit 比较寄存器 EPIT_CMPR;

    4. EPIT 为向下计数器,初始值设置后开始向下递减直至为 0,EPIT_CNR 寄存器保存当前的计数值,在 Set-and-Forget 模式下,计数寄存器的值减少为 0 时,EPIT 会重新从加载寄存器读取数值到计数寄存器,重新开 始向下计数;

  4. 比较器:比较寄存器中的值用于和计数寄存器的计数值比较,如果相等会产生一个比较事件;

  5. EPIT 可以设置引脚输出,设置后通过指定的引脚输出信号;

  6. 中断信号输出;

1.1.工作模式

EPIT 定时器有两种工作模式:set-and-forget 和 free-running,这两个工作模式的区别如下:

  • set-and-forget 模式:EPITx_CR (x = 1~2) 寄存器的 RLD 位为 1 时 EPIT 工作在该模式,该模式下 EPIT 计数寄存器从加载寄存器 EPITx_LR (x = 1~2) 中获取初始值,无法直接向计数寄存器写入数据,当计数器计数到 0 时,会从加载寄存器 EPITx_LR (x = 1~2) 中重新加载计数值到计数寄存器,并开始新一轮计时;

  • free-running 模式:EPITx_CR (x = 1~2) 寄存器的 RLD 位为 0 时 EPIT 工作在该模式,计数器计数到 0 后,会重新从 0xFFFF,FFFF 开始计数,而非从加载寄存器 EPITx_LR (x = 1~2) 中获取数据;

1.2.配置寄存器 - EPIT_CR

其中,重点关注如下位域:

  • CLKSRC[25:24]:EPIT 时钟源选择:

    • 0:禁用时钟源;

    • 1:选择 Peripheral 时钟 (ipg_clk);

    • 2:选择 High-frequency 参考时钟 (ipg_clk_highfreq);

    • 3:选择 Low-frequency 参考时钟 (ipg_clk_32k);

    • 例程中设置为 1,即选择 ipg_clk 作为 EPIT 的时钟源,ipg_clk = 66MHz;

  • PRESCALAR[15:4]:EPIT 时钟源分频值,可设置范围 0~4095,对应 1~4096 分频;

  • RLD[3]:EPIT 工作模式:

    • 0:free-running 模式;

    • 1:set-and-forget 模式;

    • 例程中设置为 1,即工作模式为 set-and-forget;

  • OCIEN[2]:比较中断使能位:

    • 0:禁用比较中断;

    • 1:使能比较中断;

    • 例程中需要使能比较中断;

  • ENMOD[1]:计数器初始值设置:

    • 0:计数器初始值等于上次关闭 EPIT 定时器后计数寄存器中的值;

    • 1:计数器初始值从加载寄存器中读取;

  • EN[0]:EPIT 使能位:

    • 0:禁用 EPIT;

    • 1:启用 EPIT;

1.3.状态寄存器 - EPIT_SR

EPIT_SR 寄存器只有一个有效位 OCIF[0],该位是比较中断标志位:

  • 为 0 时表示没有比较事件发生;

  • 为 1 时表示有比较事件发生;

1.4.加载寄存器 - EPIT_LR

LOAD[31:0] 保存计数值,当 EPIT_CR.RLD 为 1 时,计数器从该寄存器中加载计数值

1.5.比较寄存器 - EPIT_CMPR

COMPARE[31:0] 保存比较值,当计数值与其相等时触发一次比较事件

1.6.计数寄存器 - EPIT_CNR

COUNT[31:0] 保存当前的计数值,软件可以读取当前计数值而不影响计数

2.通用定时器 - GPT

GPT(General Purpose Timer)是一个 32-bit 向上定时器(即从 0x0000,0000 开始向上递增计数)

GPT 定时器可以设置比较值,当计数器中的值和比较值相等时产生比较事件,并输出中断信号

GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频

GPT 定时器的特性如 下:

  • 时钟源可选;

  • 32-bit 向上计数;

  • 12-bit 分频(1~4096 分频);

  • 2 个输入捕获通道,可以设置触发方式;

  • 3 个输出比较通道,可以设置输出模式;

  • 可以生成捕获中断、比较中断和溢出中断;

  • 计数器可以运行在 Restart 或 Free-Run 模式;

2.1. 时钟源

GPT 可选择的时钟源如下所示:

GPT 可选的时钟源有五个:

  • ipg_clk_24M;

  • GPT_CLK (外部时钟);

  • ipg_clk;

  • ipg_clk_32k;

  • ipg_clk_highfreq;

  • 例程选择 ipg_clk 为 GPT 的时钟源:ipg_clk = 66MHz;

2.2.模块结构

GPT 定时器的结构如下所示:

其中各部分的作用如下:

  1. 时钟源:例程选择 ipg_clk 作为 GPT 定时器的时钟源;

  2. 12-bit 分频器:对时钟源进行分频,可设置 0~4095,分别对应 1~4096 分频;

  3. 经过分频的时钟信号:输入至 GPT 定时器内部的 32 位计数器;

  4. 输入捕获通道 1;

  5. 输入捕获通道 2;

  6. 输出比较寄存器:共有三路输出比较,因此有三个输出比较寄存器,输出比较寄存器为 32-bit;

  7. 输出比较中断:共三路输出比较中断,当计数器中的值和输出比较寄存器中的值相等时触发比较中断;

2.3.工作模式

GPT 有 Restart 和 Free-Run 两种工作模式,其特点如下:

  • Restart:GPTx_CR(x=1~2) 寄存器的 FRR 位为 0 时 GPT 工作在该模式,该模式下,当计数值和比较寄存器中的值相等时计数值会清零,然后重新从 0x00000000 开始向上计数,仅比较通道 1 才可以使用该模式,向比较通道 1 的比较寄存器写入任何数据都会复位 GPT 计数器,对于其他两路比较通道(通道 2 和 3),发生比较事件后不会复位计数器。

  • Free-Run:GPTx_CR(x=1~2) 寄存器的 FRR 位为 1 时 GPT 工作在该模式,该模式适用于所有三个比较通道,比较事件发生后不会复位计数器,而是继续计数,直到计数值为 0xFFFFFFFF,然后重新回滚到 0x00000000;

2.4.配置寄存器 - GPT_CR

该寄存器用于配置 GPT 定时器:

其中,主要关注如下几个位域:

  • OM3[28:26]:输出比较通道 3 的运行模式:

    • 0b000:输出断开,引脚无响应;

    • 0b001:翻转输出引脚的电平;

    • 0b010:清空输出引脚(引脚低电平);

    • 0b011:设置输出引脚(引脚高电平);

    • 0b1xx:在输出引脚上产生一个低电平有效脉冲(一个输入时钟宽度);

  • OM2[25:23]:输出比较通道 2 的运行模式:

    • 同上;

  • OM1[22:20]:输出比较通道 1 的运行模式:

    • 同上;

  • SWR[15]:复位 GPT 定时器,向该位写 1 可以复位 GPT 定时器,GPT 复位完成后该位会自动清零;

  • FRR[9]:运行模式选择,该位为 0 时比较通道 1 工作在 Restart 模式,该位为 1 时所有的三个比较通道均工作在 Free-Run 模式;

  • CLKSRC[8:6]:GPT 定时器的时钟源选择:

    • 为 0 时关闭时钟源;

    • 为 1 时选择 ipg_clk 作为时钟源;

    • 为 2 时选择 ipg_clk_highfreq 作为时钟源;

    • 为 3 时选择外部时钟为时钟源;

    • 为 4 时选择 ipg_clk_32k 作为时钟源;

    • 为 5 时选择 ip_clk_24M 作为时钟源;

    • 例程中选择 ipg_clk 作为 GPT 定时器的时钟源,因此该位设置为 1 (0b001);

  • ENMOD[1]:GPT 使能模式,该位为 0 时,如果关闭 GPT 定时器,计数寄存器中会保存 GPT 定时器关闭时的计数值,该位为 1 时,如果关闭 GPT 定时器,计数器寄存器就会清零;

  • EN[0]:模块使能,为 1 时使能 GPT 定时器,为 0 时关闭 GPT 定时器;

2.5.分频寄存器 - GPT_PR

该寄存器用于保存 GPT 定时器的分频系数:

  • PRESCALER24M[15:12]:24MHz 晶振分频系数,若时钟源未选择 24MHz 晶振,该位无效,该位可设置为 0x0~0xF,分别对应 1~16 分频;

  • PRESCALER[11:0]:分频系数,选择非 24MHz 晶振的其他时钟源时该位有效,其为 12-bit 分频器,可设置 0~4095,分别对应 1~4096 分频;

2.6.状态寄存器 - GPT_SR

其中,主要关注以下位域:

  • ROV[5]:回滚(溢出)标志位,当计数值从 0xFFFFFFFF 回滚到 0x00000000 的时候此位置 1;

  • IF2[4]:输入捕获通道 2 的输入捕获标志位,输入捕获事件发生以后该位置 1,共有两路输入捕获通道,如果使用输入捕获中断,则需要在中断处理函数中清除此位;

  • IF1[3]:输入捕获通道 1 的输入捕获标志位,输入捕获事件发生以后该位置 1,共有两路输入捕获通道,如果使用输入捕获中断,则需要在中断处理函数中清除此位;

  • OF3[2]:输出比较中断标志位,输出比较事件发生后此位置 1,共有三路输出比较通道;如果使用输出比较中断,则需要在中断处理函数中清除此位;

  • OF2[1]:输出比较中断标志位,输出比较事件发生后此位置 1,共有三路输出比较通道;如果使用输出比较中断,则需要在中断处理函数中清除此位;

  • OF1[0]:输出比较中断标志位,输出比较事件发生后此位置 1,共有三路输出比较通道;如果使用输出比较中断,则需要在中断处理函数中清除此位;

2.7.计数寄存器 - GPT_CNT

32-bit 的 COUNT 字段保存计数值:

2.8.比较寄存器 - GPT_OCR

每个 GPT 模块包含三路输出中断,每路输出均有对应的输出比较寄存器,32-bit 的 COMP 保存用户设置的比较值:

当计数器值和寄存器 GPT_OCR 中的值相等时会产生比较事件,如果比较中断使能则会触发相应的中断

2.9.高精度定时原理

高精度定时函数的实现需要借助硬件定时器,例程使用 GPT 定时器实现高精度延时

如果设置 GPT 定时器的时钟源为 ipg_clk = 66MHz,设置 66 分频,则进入 GPT 定时器的最终时钟频率为 66 / 66 = 1MHz,周期为 1us

GPT 计数器每计一个数就表示 “过去” 了 1us,如果计 10 个数就表示 “过去” 了 10us,通过读取寄存器 GPT_CNT 中的值就知道计了多少个数(即时间过去了多少),比如现在要延时 100us,进入延时函数后纪录下寄存器 GPT_CNT 中的值为 200,当 GPT_CNT 中的值为 300 时就表示 100us 过去了,表示延时结束

GPT_CNT 为 32-bit 寄存器,如果时钟为 1MHz,则 GPT_CNT 最多可以实现 0xFFFFFFFFus = 4294967295us ≈ 4294s ≈ 72min,也就是说 72 分钟以后 GPT_CNT 寄存器就会回滚到 0x00000000,也就是出现溢出,所以需要在延时函数中要处理溢出的情况


网站公告

今日签到

点亮在社区的每一天
去签到