96SEO 2026-02-20 10:38 13
定时器是最常用的外设常常需要使用定时器来完成精准的定时功能I.MX6U

定时器使其按照给定的时间周期性的产生定时器中断在定时器中断里面我们可以做其它的处理
首先我们也需要知道定时器的基本原理定时器是一种根据时钟信号进行及时或产生中断的硬件模块基本工作流程就是从时钟源获得时钟信号并对时钟脉冲进行计数通过计数这些脉冲定时器能够在设定的时间后产生中断或信号
计数时钟脉冲定时器通过对时钟脉冲的计数来实现计时。
当计数器的值从一个初始值递减到零或者递增到某个值时定时器认为计时完成。
产生中断或信号当计数器到达设定值时定时器会触发中断告知系统已达到预定时间。
这种机制可以用于定时触发某个任务例如在嵌入式系统中实现周期性任务调度。
这里举个简单的例子若时钟源是
时钟源驱动定时器的工作定时器通过计数时钟源的信号来实现计数功能定时器的核心就是基于时钟信号来计数。
在开始工作前需要获得一个时钟源时钟源可以来自系统时钟或外部时钟。
时钟源的频率决定了定时器的计数精度
定时器通常通常配置有预分频器是介于时钟源和定时器之间的一个模块用来进一步调整时钟频率。
用于对输入的时钟源进行分频。
预分频器通过将时钟信号频率降低延长定时器的计数周期。
预分频器的设置决定了定时器每次计数所代表的时间单位。
定时器的核心是一个计数器它根据分频后的时钟信号进行计数一般分为两种计数方式递增模式计数器从0开始递增时钟脉冲递增在每次接收到时钟脉冲时就会加1直到达到设定的比较值或者最大计数值。
递减模式计数器从预设值递减到0在每次接收到时钟脉冲的时候就会减1
计数器的增加是由时钟信号的边沿触发来句欸的那个时钟信号的上升沿或下降沿会触发计数器的工作一般为上升沿触发和下降沿触发在时钟信号从低电平变为高电平的瞬间计数器会响应并增加或减少计数值或者时钟信号从高电平变为低电平的瞬间计数器会响应并更新计数值。
时钟信号不仅是定时器技术的驱动力还确保了计时的准确性和稳定性每个时钟脉冲代表一个基本的时间单位因此时钟源频率越高计数的精度就越高。
通过配置预分频器定时器可以根据需要放慢时钟频率从而控制计数周期。
个时钟脉冲如果预分频器设为100计数器每接受到100个时钟脉冲才递增或递减一次从而将时钟周期调整为每秒10000次。
在硬件实现中计数器的设计通常基于触发器Flip-Flop和加法器Adder。
计数器的每一位由触发器保存时钟脉冲通过加法器将当前计数值加
1。
该过程在硬件层面完全由时钟信号驱动确保了定时器的高效和稳定运行。
在生成PWM信号时计数器也通过时钟脉冲来递增当计数器的值到达设定的比较值时定时器输出信号会发现变化从而调节PWM信号的占空比。
因此PWM信号的周期长度与时钟频率和比较直直接相关
上面讲解了定时器会计数与设定的比较值进行比较当计数器的值与比较直相等的时候便会触发中断或者输出信号等操作
当计数器到达设定的最大值或比较值后定时器可以自动重载初始值从而开始新一轮的计数。
叫做自动重载一般用于周期性产生中断和信号还有一种模式为单次计时模式在一些情况下定时器可能只运行一次当达到设定的计数值后停止工作不会自动重载
如果有中断的情况当定时器达到设定的比较值或发生溢出时定时器会触发中断。
此CPU会暂时停止当前任务跳转到定时器的中断服务程序ISR中处理相应的任务
在中断处理完成后定时器的状态寄存器中会设置标志位表明中断已经触发。
系统必须清楚这个标志位以便定时器能够继续工作开始下一次的计时
定时器有非常多的种类在STM32中我们经常会用到通用定时器、高级定时器、滴答定时器以及高精度定时器等等这些定时器之所以存在主要是因为它们各自具有不同的特性和用途适用于不同的应用场景和开发板。
分别的作用我在这里也做一个简单的讲解对于知道的读者也就再复习以一下吧
首先通用定时器是功能相对简单但是运用很广泛的定时器模块具有最基本的定时功能一般适用于多种应用场景例如电机控制、测量系统、定时任务通用
然后就是高级定时器功能丰富支持多种高级功能如死区时间控制刹车功能简单来说死区时间控制和刹车功能是电子控制系统中不可或缺的重要功能而高级定时器因其功能集成度高、精度高、可靠性好以及具有丰富的外部引脚和接口等优点成为实现这些功能的理想选择。
总结来说一般就适用于需要高精度定时和复杂控制逻辑的场合如电机控制、伺服系统等
高精度定时器一般强调时间测量的高精度和准确性适用于需要精确控制时间的场合例如音频处理、视频同步等高精度定时器能够提供纳秒级或更高精度的分辨率以满足对事件精度要求极高的应用
最后再简单介绍一下滴答定时器一般也称为系统滴答定时器通常作为操作系统的内部时钟源用于提供系统时间基准和调度任务。
一般就主要用于操作系统的任务调度和时间测量滴答定时器是操作系统运行的基础提供了系统所需的时间基准和调度功能
定时器之所以搭载在不同的开发板上主要是因为不同的开发板和应用场景对定时器的需求不同。
例如一些开发板可能需要高精度的定时器来确保系统的实时性和稳定性而另一些开发板则可能更注重定时器的易用性和广泛适用性。
因此开发者在选择开发板时会根据具体的应用需求和系统要求来选择合适的定时器类型和配置。
总的来说多种类型的定时器为开发者提供了更多的选择和灵活性使他们能够根据具体的应用场景和需求来选择合适的定时器从而实现最佳的系统性能和稳定性。
而这次实验我们要接触到的是EPIT寄存器也是我们IMX6UL开发板上面最基本的EPIT定时器首先按还是来做一个介绍
Timer,翻译过来为增强的周期中断定时器它的主要任务是为了完成周期性中断定时的。
再上面介绍的定时器有很多功能但是EPTI定时器只是完成周期性中断定时并且只有这么一个功能
EPIT是一个32位的定时器在处理器几乎不需要介入的情况下提供精准的定时中断软件使能后EPIT就会开始运行这个在具体介绍完EPTI定时器就会明白
那么为什么需要强调它是一个32位的定时器呢32定时器又有什么样的优势呢首先定时器是32位可以支持非常大的计数范围而其余非32位定时器技术范围可能相对较小
且32位定时器具有丰富的配置选项和功能例如后面会讲解它具有的工作模式时钟源分频器等使开发者可以灵活的配置定时器而相对于非32位定时器可能具有一定的配置选项和功能灵活性和可选性可能就相对较低
①部分是一个多路选择器用来选择EPTI定时器的时钟源如上图可以看出EPTI一共有3个时钟源可以选择在上面我们也说过了时钟频率越高时钟的计数精度越高
②是一个12位的分频器主要就是对时钟源进行分频12位对应的值是0~4095也就是可以经过0~4095系数的分频通过配置预分频器定时器可以根据需要放慢时钟频率从而控制计数周期。
③顺着框图的顺序在时钟信号经过分频后进入到EPIT的内部在EPIT的内部有三个非常重要的寄存器计数寄存器EPIT_CNR、加载寄存器EPIT_LR和比较寄存器EPIT_CMPR这三个寄存器都是32位的。
EPIT是一个向下计数器在上面我们也讲过向下计数器给予它们一个初值它们会从这个给定的初值它就会从这个给定的初值开始递减直到减为0。
计数寄存器里面保存的就是当前的计数值。
如EPIT如果工作在set-and-forget模式下当计数寄存器里面的值减少到0。
就会重新从加载寄存器读取数值到计数寄存器里面重新开始向下计数。
加载寄存器用于在计数寄存器递减到0时重新加载计数值。
它是一个可写的寄存器允许用户设置初始计数值或周期性计数值。
比较寄存器里面保存的数值用于和计数寄存器里面的计数值进行比较如果相等的话就会产生一个比较事件
那么我们继续看下图到CMP也就是比较器主要负责将计数寄存器中的值与比较寄存器中的设定值进行比较具体来说当计数器中的当前值等于比较寄存器的值时CMP会输出一个信号信号会沿着这个框图继续走经过CMP后有一个信号箭头返回到Counter
Register它的作用通常是自动重载当计数器到达终点比如达到比较值
Register来重新开始计数。
这种设计常用于需要重复计时的场景如周期性触发中断或者产生周期性信号比如
标记为中断标志是当计数器的值达到比较寄存器值时由CMP比较产生的。
ITIF本身是一个标志位它表示计数器已经完成了一次及时或达到比较条件产生ITFT并不等同于直接触发中断只有满足ITIEInterruput
中断使能位被设置为有效才能触发以及系统允许响应中断请求如果ITIE被设置为有效且
Mode模块它控制定时器的输出信号EPITn_OUT1。
即使中断没有被触发但任然可能通过OM单元产生一个输出信号后如PWM信号或其他外部信号或者某些外部设备需要注意的是ITIF
的产生取决于计数比较而不是中断的触发。
即使没有触发中断ITIF
⑥产生比较中断也就是定时中断触发条件自然通过与笔计时器的值与比较寄存器产生比较后如果系统允许响应中断请求或者
下面将介绍EPIT定时器的两种工作模式这个是EPIT控制寄存器用于配置EPIT的操作设置
如图置1就是set-and-forget模式此模式下的EPIT计数器从加载寄存器EPITx_LE中获取初始值不能直接向计数器寄存器写入数据。
无论什么时候只要计数器计数到0那么就会从加载寄存器EPITx_LR重新加载数据到计数器中周而复始
那么置0为free-running模式EPITx_CR寄存器的RLD位清零的时候EPIT工作在此模式下当计数器计数到0以后会重新从0XFFFFFFFF开始计数并不是从加载寄存器EPITx_LE中获取数据
除了常用的用于EPIT的模式切换位第三位以外还有其余一些重要的位如25-24位为0的时候关闭时钟源为1的时候是选择Peripheral时钟ipg_clk为2的时候是选择High-frequency参考时钟ipg_clk_highfreq为3的时候选择Low_frequency参考时钟ipg_clk_32k
EPIT时钟源分频值可设置范围0~4095分别对应1~4096分频
以及刚刚提到的第三位用于模式切换还有第二位OCIEN主要作用就是比较中断使能位为0的时候关闭比较中断为1的时候使能比较中断
下面翻译为当EPIT被禁用EN0时主计数器和预分频计数器都会将其计数值冻结在当前值。
ENMOD位是一个可读/可写位用于确定当通过设置EN位再次启用EPIT时计数器的值。
如果ENMOD位被设置那么在EPIT启用EN1时主计数器将被加载为加载值如果RLD1/0xFFFF_FFFF如果RLD0预分频计数器将被重置。
如果ENMOD被编程为0那么在EPIT启用EN1时主计数器和预分频计数器将从它们被冻结的值重新开始计数。
如果EPIT被编程为在低功耗模式STOP/WAIT/DEBUG下禁用那么当EPIT进入低功耗模式时主计数器和预分频计数器都会冻结在其当前的计数值。
当EPIT退出低功耗模式时无论ENMOD位如何主计数器和预分频计数器都会从它们被冻结的值开始计数。
此位由硬件复位重置。
软件复位不会影响此位。
1计数器从加载值如果RLD1或0xFFFF_FFFF如果RLD0开始计数。
1时EPIT计数器和预分频器的值取决于ENMOD位和RLD位如ENMOD位描述中所述。
建议在设置此位之前正确编程所有寄存器。
此位由硬件复位重置软件复位不会影响此位。
还要介绍一个寄存器为EPITx_SR此寄存器为EPIT的状态寄存器有一个用于输出比较事件的状态位。
这个位是一个写1清零位
31-1位全部作为此寄存器的保留位而第一个字节位0CIF位翻译为
输出比较中断标志位。
此位是中断标志位当计数器的内容与比较寄存器EPIT_CMPR的内容相等时设置。
该位是一个写1清零位。
简单来说此寄存器只有一个有效位就是OCIFbit0这个位是比较中断标志位为0的时候表示没有比较事件发生为1的时候表示由比较事件发生。
当比较中断发生以后需要手动清除此位也就是需要写1去清零
剩下还有三个寄存器分别为EPITx_LREPITx_CMPREPITx_CNR
它们都只有一个作痛就是来存放数据它们的存放数据的目的在上面EPIT的定时器原理当中也讲过这里不过多赘述
在上面我们根据EPIT的框图对EPTI进行了大致讲解现在我们根据框图来进一步完善对于EPIT定时器的配置思路
1.首先就是选择时钟源一共有三种时钟源可以选择就需要通过EPIT_CR寄存器的CLKSRC(bit25:24)位来选择
2.设置分频值需要通过EPIT1_CR寄存器的PRESCALAR(bit15:4)位来进行设置
3.设置EPIT的工作模式通过寄存器EPIT1_CR的RLDbit3位
4.设置计数器的初始值来源通过寄存器EPIT_CR的ENMOD(bit1)位设置计数器的初始值来源也就是设置计数器初始值
5.因为我们后面的实验需要通过比较中断来进行实验产生比较中断自然就需要使能对应的寄存器EPIT_CR的OCIENbit2位
6.使能了比较中断那么如何比较既然是将EPIT1_LR中的加载值和EPIT2_CMPR中的比较值通过这两个就可以决定定时器的中断周期
7.设置了中断周期就需要在中断中完成我们需要完成的事情使能GIC中对应的EPIT中断注册中断服务函数如果有特殊要求的话可以设置中断优先级再编写中断函数
8.最终配置好EPIT后就可以使能EPIT1了通过寄存器EPIT1_CR的ENbit0位来设置
原理这方面就讲解完成了最后就开始具体的代码实现部分首先在之前中断的基础上我们将文件复制一份然后改名为10_EPIT_Timer然后在BSP的文件夹下创建一个文件夹epittimer再文件夹的下方创建两个文件分别为bsp_epittimer.h和bsp_epittimer.c
然后就开始编写.c文件首先按照思路的分析第一步就是要先初始化EPIT定时器初始化函数代码如下
0XFFF)/*如果分频值超过4095,则最大设置为4095*/{frac
/*使能GIC对应的EPTI中断*/GIC_EnableIRQ(EPIT1_IRQn);/*注册中断服务函数*/system_register_irqhandler(EPIT1_IRQn,(system_irq_handler_t)epit1_irqhandler,NULL);EPIT1-CR
每个代码的大致作用我已经注释了这边再大致梳理一下思路首先函数接受两个参数一个是unsigned
函数里面内容先对我们写入的frac分频值进行一个判断因为我们的寄存器最多进行1-4096的分频所以不能超出寄存器的值所以判断是否大于规定值如果超出则frac就默认输出为最大分频值4096
我们要配置EPIT控制寄存器首先还是代码标准性对此EPTIx_CR进行清零然后就开始配置这个32位的寄存器每一位为什么需要配置为这么多上面的注释也做了讲解所以下面我们就直接对位进行操作就可以了
将之后我们要写入的Value传入到加载寄存器为什么说这个Value值会决定这个定时器的周期待会儿我们进行讲解
使能中断控制器中控制的EPIT1_IRQn这个是中断号这个函数即是在
下面就是注册中断服务函数也就是产生中断过后需要执行的程序将指定的中断号与处理该中断的服务程序关联起来。
将指定的中断号与处理该中断的服务程序关联起来这个函数是我们在讲解中断的时候就已经写好了的EPTI1_IRQn就对应触发中断的中断号这个参数表示你要为哪个中断号注册中断服务程序这里就是为
epit1_irqhandler这是中断服务函数ISR的名称。
当
产生中断时系统会自动调用这个函数来处理定时器中断事件。
最后一个参数是传递给中断处理函数的上下文参数通常用于传递额外的信息。
如果不需要额外信息则传递
下一步就是开始编写我们的中断服务函数既然产生了中断自然就需要有对于相关的中断处理还是先把代码放在下面
(10)){led_switch(LED0,state);}EPIT1-SR
首先创建一个变量来定义灯的状态然后再通过!来进行取反下一步则进行一个IF判断因为SR是用来判断比较事件是否发生所以IF为真也就是判断事件发生则执行里面的led_switch这个函数最后将SR寄存器给清零也就是清除中断标志位
然后现在现在讲一下为什么Value决定是如何控制这个定时器的周期时长还是说回来epit1_init
Value和Frac的参数都已经讲解过了Tclk是EPIT1的输入时钟频率单位HzTout是溢出时间单位S例如再钱买你我们已经设置了时钟源是ipg_clk66Mhz我们再这里假如要设定周期500ms可以设置分频值为0也就是一分频进入EPIT1的时钟就是66MHz。
那么如果要设置500ms的中断那EPIT加载寄存器就应该是66000000/233000000
所以bsp_epittimer.c的文件最后只需要将在.c文件里面编写的函数在.h文件里面声明一下就可以了bsp_epittimer.h文件代码如下
所有的代码就编写完成了最后将代码烧写到板子当中就可以看到LED灯以500ms为周期在进行闪烁那么如果使用IMX6UL的EPIT定时器这一节实验就讲解到这里欢迎大家的评论与指正
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback