I.MX6U 裸机开发18.GPT定时器实现高精度延时

I.MX6U 裸机开发18.GPT定时器实现高精度延时

  • 一、GPT定时器简介
    • 1. GPT 功能
    • 2. 时钟源
    • 3. 框图
    • 4. 运行模式
      • (1)Restart mode
      • (2)Free-Run Mode
    • 5. 中断类型
      • (1)溢出中断 Rollover Interrupt
      • (2)输入捕获中断 Input Capture Interrupt 1,2
      • (3)输出捕获中断 Output Compare Interrupt 1,2,3
    • 6. 寄存器
      • (1) GPTx_CR
        • bit 0
        • bit 1
        • bit 2
        • bit 3
        • bit 4
        • bit 5
        • bits 6-8
        • bit 9
        • bit 10
        • bit 11-14
        • bit 15
        • bit22-20 OM1, bit25-23 OM2, bit 28-26 OM3
        • bit 29 FO1, bit30 FO2, bit31 FO3
      • (2) GPTx_PR 分频寄存器
      • (3) GPTx_SR 状态寄存器
        • **bit 0**: Output Compare 1 Flag (OF1)
        • **bit 1**: Output Compare 2 Flag (OF2)
        • **bit 2**: Output Compare 3 Flag (OF3)
        • **bit 3**: Input Capture 1 Flag (IF1)
        • **bit 4**: Input Capture 2 Flag (IF2)
        • **bit 5**: Rollover Flag (ROV)
      • (4) GPTx_IR 中断寄存器
      • GPTx_IR 中断寄存器
  • 二、定时器中断实现500ms定时
    • 1. 初始化 GPT 定时器
    • 2. 中断函数里实现LED闪烁
  • 三、实现高精度延时
    • 1. 实现高精度延时的做法
    • 2. 实现us延时
    • 3. 实现 ms 延时

一、GPT定时器简介

1. GPT 功能

IMX6ULL 的GPT定时器(General Purpose Timer)是一种通用定时器,可以用于生成精确的时间延迟、测量时间间隔、产生周期性中断等,以下是它的几个特性:

  • GPT 有一个 32 位的向上计数器。定时器的计数值可以通过外部引脚上的事件被捕获到一个寄存器中。
  • 捕获触发可以被编程为上升沿和/或下降沿。
  • GPT 还可以在输出比较引脚上生成一个事件,并在定时器达到编程值时产生一个中断。
  • GPT 有一个 12 位的预分频器,它从多个时钟源中提供一个可编程的时钟频率。

相比较,EPIT:

  • 32位向下计数器
  • 没有捕获功能

2. 时钟源

在这里插入图片描述
本文使用 ipg_clk 作为时钟源,即66MHz。

3. 框图

在这里插入图片描述

  1. 从左上角开始,输入时钟
  2. 时钟进入 Prescaler 12位分频器(值0~4095)
  3. 分频后进入 Timer Counter,即32位计数器
  4. GET_CAPTURE1, GET_CAPTURE2 实现捕获功能
  5. TIMER Output Reg1~3, 是三路时钟输出,Timer Count要与这三路值进行比较,
  6. GET_COMPARE1~3,三路比较输出

4. 运行模式

(1)Restart mode

自由运行模式,计数器从零开始计数,并在达到最大值后回到零,继续计数。这个模式通常用于测量时间间隔或生成周期性中断。
比较的时候,是比较定时器的计数值和比较寄存器OCR。

特点:

  1. 计数器不断循环计数。
  2. 可以配置中断,在计数器溢出时触发中断。
  3. 只有比较通道1适用这种模式。

(2)Free-Run Mode

输入捕获模式,计数器在检测到外部事件(如信号边沿)时捕获当前计数值,并将其存储在捕获寄存器中。这个模式通常用于测量外部事件的时间间隔。

特点:

  1. 计数器在检测到外部事件时捕获当前计数值。
  2. 可以配置中断,在捕获事件发生时触发中断。
  3. 三个通道都适用, 从0开始一直加到 0xFFFFFFFF,然后重新从0开始。

5. 中断类型

(1)溢出中断 Rollover Interrupt

计数器达到其最大值并回到零时,会触发溢出中断。这个中断通常用于周期性任务或需要精确时间间隔的应用。

(2)输入捕获中断 Input Capture Interrupt 1,2

可以捕获外部事件的时间戳。GPT有两个输入捕获通道,分别为输入捕获中断1(Input Capture Interrupt 1)和输入捕获中断2(Input Capture Interrupt 2)。

(3)输出捕获中断 Output Compare Interrupt 1,2,3

在计数器达到预设值时触发中断。GPT有三个输出比较通道,分别为输出比较中断1(Output Compare Interrupt 1)、输出比较中断2(Output Compare Interrupt 2)和输出比较中断3(Output Compare Interrupt 3)。

6. 寄存器

(1) GPTx_CR

GPTx_CR 是 GPT的控制寄存器,用于配置和控制 GPT 定时器的各种功能。以下是 GPTx_CR 寄存器的各个功能位的详细说明:

bit 0

GPT Enable: 使能GPT定时器,1使能

bit 1

GPT Enable Mode: 使能模式,0表示GPT定时器计数值默认为上次关闭的时候值,为1表示默认值为0

bit 2

GPT Debug Enable: 调试模式使能

bit 3

GPT Wait Mode Enable: 等待模式使能

bit 4

GPT Doze Mode Enable: 休眠模式使能

bit 5

GPT Stop Mode Enable: 停止模式使能

bits 6-8

GPT Clock Source: 时钟源选择

  • 000: 时钟源关闭
  • 001: 使用IPG时钟源
  • 010: 使用高频IPG时钟源
  • 011: 使用外部时钟源
  • 100: 使用外设时钟源
  • 101: 使用晶体振荡器作为参考时钟,频率为24 MHz
bit 9

GPT Free-Run or Restart Mode: 自由运行或重启模式,0为Restart 模式, 1为 Free-Run模式。

bit 10

EN_24M: 使能24 MHz晶体振荡器输入时钟。

  • 硬件复位会重置EN_24M位。
  • 软件复位不会影响EN_24M位。
bit 11-14

未使用

bit 15

SWR: 软件复位,这是GPT模块的软件复位位。它是一个自清除位。

  • 当模块处于复位状态时,SWR位被置位。
  • 当复位过程完成时,SWR位被清除。
  • 设置SWR位会将所有寄存器重置为默认复位值,除了GPT控制寄存器中的EN、ENMOD、STOPEN、WAITEN和DBGEN位。
    • 0: GPT不处于复位状态
    • 1: GPT处于复位状态
bit22-20 OM1, bit25-23 OM2, bit 28-26 OM3

设置比较输出功能,比较事件发生以后,相应的IO输出:

  • 000: 输出断开。引脚上无响应。
  • 001: 切换输出引脚,翻转输出;
  • 010: 清除输出引脚,清0。
  • 011: 设置输出引脚,置1。
    1xx: 在输出引脚上生成一个有效低脉冲(即一个输入时钟宽度)。在比较事件发生时,输出引脚立即设置为1,并在下一个输入时钟时生成一个低脉冲。
bit 29 FO1, bit30 FO2, bit31 FO3

强制输出比较通道3

  • 0: 写0无效。
  • 1: 在定时器输出比较通道3引脚上执行编程的引脚操作;OF3标志不设置。

本文实验使用 IPG时钟源, Restart Mode。

(2) GPTx_PR 分频寄存器

用来设置分频值。
bits 0-11: 分频值(Prescaler Value)
这些位用于设置预分频值。预分频值的范围通常为0到4095。
实际的分频因子为(分频值 + 1),即如果分频值为0,则分频因子为1;如果分频值为1,则分频因子为2,以此类推。

这个用来设置 Crystal Oscillator 24M 的分频。

(3) GPTx_SR 状态寄存器

GPTx_SR(Status Register)是GPT的状态寄存器,用于指示定时器的各种状态和事件。功能位的作用如下:

bit 0: Output Compare 1 Flag (OF1)
  • 当输出比较通道1发生比较事件时,该位被置位。
  • 0: 没有发生比较事件
  • 1: 发生了比较事件
bit 1: Output Compare 2 Flag (OF2)
  • 当输出比较通道2发生比较事件时,该位被置位。
  • 0: 没有发生比较事件
  • 1: 发生了比较事件
bit 2: Output Compare 3 Flag (OF3)
  • 当输出比较通道3发生比较事件时,该位被置位。
  • 0: 没有发生比较事件
  • 1: 发生了比较事件
bit 3: Input Capture 1 Flag (IF1)
  • 当输入捕获通道1发生捕获事件时,该位被置位。
  • 0: 没有发生捕获事件
  • 1: 发生了捕获事件
bit 4: Input Capture 2 Flag (IF2)
  • 当输入捕获通道2发生捕获事件时,该位被置位。
  • 0: 没有发生捕获事件
  • 1: 发生了捕获事件
bit 5: Rollover Flag (ROV)
  • 当计数器发生溢出时,该位被置位。
  • 0: 没有发生溢出
  • 1: 发生了溢出

(4) GPTx_IR 中断寄存器

GPTx_IR 中断寄存器

GPTx_IR(Interrupt Register)是GPT的中断寄存器,用于配置和控制定时器的中断功能,各位作用如下:

  • bit 0: Output Compare 1 Interrupt Enable (OF1IE)

    • 0: 禁用输出比较通道1中断
    • 1: 使能输出比较通道1中断
  • bit 1: Output Compare 2 Interrupt Enable (OF2IE)

    • 0: 禁用输出比较通道2中断
    • 1: 使能输出比较通道2中断
  • bit 2: Output Compare 3 Interrupt Enable (OF3IE)

    • 0: 禁用输出比较通道3中断
    • 1: 使能输出比较通道3中断
  • bit 3: Input Capture 1 Interrupt Enable (IF1IE)

    • 0: 禁用输入捕获通道1中断
    • 1: 使能输入捕获通道1中断
  • bit 4: Input Capture 2 Interrupt Enable (IF2IE)

    • 0: 禁用输入捕获通道2中断
    • 1: 使能输入捕获通道2中断
  • bit 5: Rollover Interrupt Enable (ROVIE)

    • 0: 禁用溢出中断
    • 1: 使能溢出中断

二、定时器中断实现500ms定时

在 bsp_delay.c 里实现下面功能。

1. 初始化 GPT 定时器


/*** @brief 初始化GPT定时器*/
void gpt1_timer_init(void)
{// bit0 软复位GPT1->CR = 0;GPT1->CR = 1 << 15;while(GPT1->SR & (1 << 15));// bit1, GPT 定时器计数器的初始值,为1表示默认值为0,0表示为上次关闭时候的值GPT1->CR |= (1 << 1);// bit6~8 时钟源,001表示ipg_clkGPT1->CR |= (1 << 6);// bit9 运行模式,设置为Restart模式(默认就是0,也可以不设置)GPT1->CR &= ~(1 << 9);// 设置分频值,使用PR寄存器,设置为66分频,这样进入GPT1的时钟为66MHz/66=1MHzGPT1->PR = 65;// 设置输出比较寄存器1的值,设置为1000000,即500msGPT1->OCR[0] = TIMER_DURATION;// bit0 使能输出比较中断GPT1->IR = (1 << 0);// 设置GIC中断GIC_EnableIRQ(GPT1_IRQn);// 注册中断服务函数sys_irq_handle_register(GPT1_IRQn, (system_irq_handler_t)gpt1_timer_irqhandler, NULL);// 使能GPT1定时器GPT1->CR |= (1 << 0);
}

2. 中断函数里实现LED闪烁


/*** @brief GPT中断服务函数*/
void gpt1_timer_irqhandler(unsigned int gicciar, void *param)
{static unsigned char state = 0;if(GPT1->SR & (1 << 0)) {state = !state;led_switch(LED0, state);}// 清除中断标志位GPT1->SR |= (1 << 0);
}

三、实现高精度延时

1. 实现高精度延时的做法

上面代码段里,

    // bit0 软复位GPT1->CR = 0;GPT1->CR = 1 << 15;while(GPT1->SR & (1 << 15));// bit1, GPT 定时器计数器的初始值,为1表示默认值为0,0表示为上次关闭时候的值GPT1->CR |= (1 << 1);// bit6~8 时钟源,001表示ipg_clkGPT1->CR |= (1 << 6);// bit9 运行模式,设置为Restart模式(默认就是0,也可以不设置)GPT1->CR &= ~(1 << 9);// 设置分频值,使用PR寄存器,设置为66分频,这样进入GPT1的时钟为66MHz/66=1MHzGPT1->PR = 65;

这里实现了1MHz的时钟设置,即每个计数是1uS,只要计算 GPT1->CNT 数值即可。

2. 实现us延时

/**
* @brief 延时us
*/
void delay_us(unsigned int us){unsigned long old_cnt;unsigned long tcntvalue = 0;old_cnt = GPT1->CNT;while(1){unsigned long new_cnt = GPT1->CNT;if(new_cnt != old_cnt){if(new_cnt > old_cnt){tcntvalue += new_cnt - old_cnt;}else{tcntvalue += 0xffffffff - old_cnt + new_cnt;}}if(tcntvalue >= us){break;}}
}

3. 实现 ms 延时

/**
* @brief 延时ms
*/
void delay_ms(unsigned int ms){while(ms--){delay_us(1000);}
}

main 函数:

#include "inc/main.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
#include "bsp_int.h"
//#include "bsp_exti.h"
#include "bsp_epit.h"
#include "bsp_keyfilter.h"int main(void)
{bsp_int_init();  /* 初始化中断 */imx6u_clkinit();    /* 初始化系统时钟 */clk_enable();   /* 使能外设时钟 */led_init();     /* 初始化LED */beep_init();    /* 初始化蜂鸣器 */
//    exti_init();    /* 初始化外部中断 */
//    epit_init(EPIT1, 0, 66000000 / 2);  /* 初始化EPIT1, 1分频, 500ms中断一次 */
//    keyfilter_init();   /* 初始化按键 */
//    gpt1_timer_init();  /* 初始化GPT1定时器 */gpt1_delay_init();  /* 初始化GPT1高精度延时 */while(1) {delay_ms(500);led_switch(LED0, 0);delay_ms(500);led_switch(LED0, 1);}return 0;
}

本文代码开源地址;
https://gitee.com/xundh/learn_i.mx6u.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477242.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

key-value存储实现

文章目录 一、项目简介二、项目流程图三、网络3.1、epoll实现3.2、io_uring实现 四、协议五、存储5.1、array实现5.2、rbtree实现5.3、hash实现 六、测试 一、项目简介 key-value存储其实是一个小型的redis&#xff0c;用户在客户端输入存储相关的指令发送给服务器端&#xff…

大公司如何实现打印机共享的?如何对打印机进行管控或者工号登录后进行打印?异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务?

大公司如何实现打印机共享的&#xff1f;如何对打印机进行管控或者工号登录后进行打印&#xff1f;异地打印机共享的如何实现可以帮助用户在不同地理位置使用同一台打印机完成打印任务&#xff1f; 如果在局域网内&#xff0c;可以不需要进行二次开发&#xff0c;通过对打印机进…

微软发布Win11 24H2系统11月可选更新KB5046740!

系统之家11月22日报道&#xff0c;微软针对Win11 24H2系统推出2024年11月最新可选更新补丁KB5046740&#xff0c;更新后系统版本后升至26100.2454&#xff0c;此次更新后修复当应用程序以PDF和XLSX格式导出图表对象时停止响应、无法使用API查找旋转信息等问题。以下小编将给大家…

探索 RocketMQ:企业级消息中间件的选择与应用

一、关于RocketMQ RocketMQ 是一个高性能、高可靠、可扩展的分布式消息中间件&#xff0c;它是由阿里巴巴开发并贡献给 Apache 软件基金会的一个开源项目。RocketMQ 主要用于处理大规模、高吞吐量、低延迟的消息传递&#xff0c;它是一个轻量级的、功能强大的消息队列系统&…

李宏毅机器学习课程知识点摘要(6-13集)

pytorch简单的语法和结构 dataset就是数据集&#xff0c;dataloader就是分装好一堆一堆的 他们都是torch.utils.data里面常用的函数&#xff0c;已经封装好了 下面的步骤是把数据集读进来 这里是读进来之后&#xff0c;进行处理 声音信号&#xff0c;黑白照片&#xff0c;红…

Wekan看板安装部署与使用介绍

Wekan看板安装部署与使用介绍 1. Wekan简介 ​ Wekan 是一个开源的看板式项目管理工具&#xff0c;它的配置相对简单&#xff0c;因为大多数功能都是开箱即用的。它允许用户以卡片的形式组织和跟踪任务&#xff0c;非常适合敏捷开发和日常任务管理。Wekan 的核心功能包括看板…

【Mysql】开窗聚合函数----SUM,AVG, MIN,MAX

1、概念 在窗口中&#xff0c;每条记录动态地应用聚合函数&#xff08;如&#xff1a;SUM(),AVG(),MAX(),MIN(),COUNT(),&#xff09;可以动态计算在指定的窗口内的各种聚合函数值。 2、操作 以下操作将基于employee表进行操作。 sum() 进行sum的时候&#xff0c;没有order …

EWA Volume Splatting

摘要 本文提出了一种基于椭圆高斯核的直接体绘制新框架&#xff0c;使用了一种投影方法&#xff08;splatting approach&#xff09;。为避免混叠伪影&#xff08;aliasing artifacts&#xff09;&#xff0c;我们引入了一种重采样滤波器的概念&#xff0c;该滤波器结合了重建核…

Vue实训---0-完成Vue开发环境的搭建

1.在官网下载和安装VS Code编辑器 完成中文语言扩展&#xff08;chinese&#xff09;&#xff0c;安装成功后&#xff0c;需要重新启动VS Code编辑器&#xff0c;中文语言扩展才可以生效。 安装Vue-Official扩展&#xff0c;步骤与安装中文语言扩展相同&#xff08;专门用于为“…

C# 超链接控件LinkLabel无法触发Alt快捷键

在C#中&#xff0c;为控件添加快捷键的方式有两种&#xff0c;其中一种就是Windows中较为常见的Alt快捷键&#xff0c;比如运行对话框&#xff0c;记事本菜单等。只需要按下 Alt 框号中带下划线的字母即可触发该控件的点击操作。如图所示 在C#开发中&#xff0c;实现类似的操作…

赛氪媒体支持“2024科普中国青年之星创作交流活动”医学专场落幕

2024年11月15日下午&#xff0c;由中国科普作家协会、科普中国发展服务中心主办&#xff0c;什刹海文化展示中心承办&#xff0c;并携手国内产学研一体融合领域的领军者——赛氪网共同支持的“2024科普中国青年之星创作交流活动”医学科普专场&#xff0c;在什刹海文化展示中心…

《现代制造技术与装备》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《现代制造技术与装备》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第二批认定学术期刊。 问&#xff1a;《现代制造技术与装备》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;齐鲁工业大学&#xff0…

(十一)Python字符串常用操作

一、访问字符串值 Python访问子字符串变量&#xff0c;可以使用方括号来截取字符串。与列表的索引一样&#xff0c;字符串索引从0开始。 hh"LaoTie 666" hh[2] mm"床前明月光" mm[3] 字符串的索引值可以为负值。若索引值为负数&#xff0c;则表示由字符…

数据结构(初阶6)---二叉树(遍历——递归的艺术)(详解)

二叉树的遍历与练习 一.二叉树的基本遍历形式1.前序遍历(深度优先遍历)2.中序遍历(深度优先遍历)3.后序遍历(深度优先遍历)4.层序遍历&#xff01;&#xff01;(广度优先遍历) 二.二叉树的leetcode小练习1.判断平衡二叉树1&#xff09;正常解法2&#xff09;优化解法 2.对称二叉…

20.100ASK_T113-PRO 开发板开机自动QT程序简单的方法一

本文详细介绍了在嵌入式系统中实现程序开机自启动的多种方法&#xff0c;包括通过修改/etc/profile、/etc/rc.local文件&#xff0c;以及在/etc/init.d目录下创建启动脚本等方式。文章还解释了不同配置文件的作用及它们之间的区别。 开机自动启动QT应用程序 用户模式下的启动 …

Android蓝牙架构,源文件目录/编译方式学习

Android 版本 发布时间 代号&#xff08;Codename&#xff09; Android 1.0 2008年9月23日 无 Android 1.1 2009年2月9日 Petit Four Android 1.5 2009年4月27日 Cupcake Android 1.6 2009年9月15日 Donut Android 2.0 2009年10月26日 Eclair Android 2.1 2…

LeetCode 145.二叉树的后序遍历

题目&#xff1a;给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 思路&#xff1a;左 右 根 代码&#xff1a; /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* Tre…

GitLab|数据迁移

注意&#xff1a;新服务器GitLab版本需和旧版本一致 在旧服务器执行命令进行数据备份 gitlab-rake gitlab:backup:create 备份数据存储在 /var/opt/gitlab/backups/ 将备份数据传输到新服务器的/var/opt/gitlab/backups/下&#xff0c;并修改文件权限&#xff08;下载前和上传…

实验四:构建园区网(OSPF 动态路由)

目录 一、实验简介 二、实验目的 三、实验需求 四、实验拓扑 五、实验步骤 1、在 eNSP 中部署网络 2、设计全网 IP 地址 3、配置二层交换机 4、配置路由交换机并测试通信 5、配置路由接口地址 6、配置 OSPF 动态路由&#xff0c;实现全网互通 一、实验简介 使用路由…

外卖系统开发实战:从架构设计到代码实现

开发一套外卖系统&#xff0c;需要在架构设计、技术选型以及核心功能开发等方面下功夫。这篇文章将通过代码实例&#xff0c;展示如何构建一个基础的外卖系统&#xff0c;从需求梳理到核心模块的实现&#xff0c;帮助你快速掌握开发要点。 一、系统架构设计 一个完整的外卖系…