I.MX6ull GPT高精度定时器

这篇具有很好参考价值的文章主要介绍了I.MX6ull GPT高精度定时器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一 简介

GPT的全称是General Purpose Timer,它是一个32位的向上的定时器, GPT 定时器也可以跟一个值进行比较,当计数器值和这个值相等的话就发生比较事件,产生比较中断。GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频。 分析方式同EPTI 

它具有以下特点:

1.一个可选时钟源的32位向上计数器。

2.两个输入捕获通道,可以设置触发方式。

3.三个输出比较通道,可以设置输出模式。

4.可以生成捕获中断、比较中断和溢出中断。

5.计数器可以运行在重新启动(restart)或(自由运行)free-run模式。

二 结构原理图

2.1  时钟源

五个时钟源,分别为:ipg_clk_24M、GPT_CLK(外部时钟)、ipg_clk=66MHz、ipg_clk_32k和ipg_clk_highfreq   

I.MX6ull GPT高精度定时器

 2.2  内部结构

I.MX6ull GPT高精度定时器

 2.3 工作原理

        通过设置定时器工作频率确定计数器加1耗时t,延时时间 D/t = N 确定计数器计数值,轮询读取计数器( GPTx_CNT )值为N即为延时 D.

         比如选择ipg_clk =66MHz,然后时钟源通过一个12位的分频器,分频以后进入32位的GPT定时器内部。我们选择分频参数为66,那么进入GPT定时器的频率就是1MHz了。1MHz的周期是1us,也就是说GPT的计数器每加一,就是经过了1us,如果累计加了20个数,就是20us。所以我们可以通过读取GPT计数器中的数值累加的个数,就知道经过的时间了。比如我们现在要延时50us,那么我们进入到延时函数,读取到GPT计数器的当前计数为100,那么当GPT计数器中的值变成200的时候(200-100=100个数),我们就知道延时经过了100us。     

2.3.1 GPT 定时器结构中各部分意义如下:

①、此部分为 GPT 定时器的时钟源,前面已经说过了,本章例程选择 ipg_clk 作为 GPT 定时器时钟源。

②、此部分为 12 位分频器,对时钟源进行分频处理,可设置 0~ 4095,分别对应 1~ 4096 分频。

③、经过分频的时钟源进入到 GPT 定时器内部 32 位计数器。

④和⑤、这两部分是 GPT 的两路输入捕获通道,本章不讲解 GPT 定时器的输入捕获。

⑥、此部分为输出比较寄存器,一共有三路输出比较,因此有三个输出比较寄存器,输出比较寄存器是 32 位的。

⑦、此部分位输出比较中断,三路输出比较中断,当计数器里面的值和输出比较寄存器里面的比较值相等就会触发输出比较中断。

           

2.3.2 工作模式

1 重新启动(restart)模式:

        当 GPTx_CR(x=1,2)寄存器的 FRR 位清零的时候 GPT 工作在此 模式。在此模式下,当计数值和比较寄存器中的值相等的话计数值就会清零,然后重新从0X00000000 开始向上计数,只有比较通道 1 才有此模式!向比较通道 1 的比较寄存器写入任何 数据都会复位 GPT 计数器。对于其他两路比较通道(通道 2 和 3),当发生比较事件以后不会 复位计数器。

2 自由运行(free-run)模式

        当 GPTx_CR(x=1,2)寄存器的 FRR 位置 1 时候 GPT 工作在此模 式下,此模式适用于所有三个比较通道,当比较事件发生以后并不会复位计数器,而是继续计 数,直到计数值为 0XFFFFFFFF,然后重新回滚到 0X00000000。 接下来看一下 GPT 定时器几个重要的寄存器,第一个就是 GPT 的配置寄存器 GPTx_CR, 此寄存器的结构如图 20.1.1.3 所示:

2.4 重要寄存器

GPTX_CR    GPTX_PR    GPTx_SR  GPTx_CNT

2.4.1 GPT 的配置寄存器 GPTx_CR

I.MX6ull GPT高精度定时器

描述
SWR(bit15) 复位 GPT 定时器,向此位写 1 就可以复位 GPT 定时器,当 GPT 复位完成以后此为会自动清零。
FRR(bit9) 运行模式选择,当此位为 0 的时候比较通道 1 工作在重新启动(restart)模式。当此位为 1 的时候所有的三个比较通道均工作在自由运行模式(free-run)。
CLKSRC(bit8: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(bit1) GPT 使能模式,此位为 0 的时候如果关闭 GPT 定时器,计数器寄存器保存定时器关闭时候的计数值。此位为 1 的时候如果关闭 GPT 定时器,计数器寄存器就会清零。EN(bit): GPT 使能位,为 1 的时候使能 GPT 定时器,为 0 的时候关闭 GPT 定时器。

2.4.2、GPT 定时器的分频寄存器 GPTx_PR 

I.MX6ull GPT高精度定时器

PRESCALER(bit11:0),这就是 12 位分频值, 可设置 0~4095,分别对应 1~4096 分频

2.4.3 状态寄存器 GPTx_SR

I.MX6ull GPT高精度定时器

ROV(bit5):回滚标志位,当计数值从 0XFFFFFFFF 回滚到 0X00000000 的时候此位置 1。

IF2~IF1(bit4:3):输入捕获标志位,当输入捕获事件发生以后此位置 1,一共有两路输入捕 获通道。如果使用输入捕获中断的话需要在中断处理函数中清除此位。

OF3~OF1(bit2:0):输出比较中断标志位,当输出比较事件发生以后此位置 1,一共有三路 输出比较通道。如果使用输出比较中断的话需要在中断处理函数中清除此位。

2.4.4 计数寄存器 GPTx_CNT

I.MX6ull GPT高精度定时器

三 使用实验

通过 GPT 延时500ms 控制LED0 的亮灭 文章来源地址https://www.toymoban.com/news/detail-479161.html

3.1 配置步骤

  • 1、设置 GPT1 定时器
  • 首先设置 GPT1_CR 寄存器的 SWR(bit15)位来复位寄存器 GPT1。复位完成以后设置寄存 器 GPT1_CR 寄存器的 CLKSRC(bit8:6)位,选择 GPT1 的时钟源为 ipg_clk。设置定时器 GPT1的工作模式, Restart模式,当CNT等于OCR1的时候就产生中断,为了实现较大的计数,我们将比较值设置为最大的0XFFFFFFFF
  • 2、设置 GPT1 的分频值
  • 设置寄存器 GPT1_PR 寄存器的 PRESCALAR(bit111:0)位,设置分频值。
  • 3、设置 GPT1 的比较值 
  • 如果要使用 GPT1 的输出比较中断,那么 GPT1 的输出比较寄存器 GPT1_OCR1 的值可以 根据所需的中断时间来设置。本章例程不使用比较输出中断,所以将 GPT1_OCR1 设置为最大 值,即:0XFFFFFFFF。
  • 4、使能 GPT1 定时器
  • 设置好 GPT1 定时器以后就可以使能了,设置 GPT1_CR 的 EN(bit0)位为 1 来使能 GPT1 定 时器。
  • 5、编写延时函数
  • GPT1定时器已经开始运行了,可以根据前面介绍的高精度延时函数原理来编写延时函数, 针对 us 和 ms 延时分别编写两个延时函数。 

3.2 代码 

/***************************************************************
Copyright © zuozhongkai Co., Ltd. 1998-2019. All rights reserved.
文件名	: 	 bsp_delay.c
作者	   : 左忠凯
版本	   : V1.0
描述	   : 延时文件。
其他	   : 无
论坛 	   : www.wtmembed.com
日志	   : 初版V1.0 2019/1/4 左忠凯创建

		 V2.0 2019/1/15	左忠凯修改
		 使用定时器GPT实现高精度延时,添加了:
		 delay_init 延时初始化函数
		 gpt1_irqhandler gpt1定时器中断处理函数
		 delayus us延时函数
		 delayms ms延时函数
***************************************************************/
#include "bsp_delay.h"

/*
 * @description	: 延时有关硬件初始化,主要是GPT定时器
				  GPT定时器时钟源选择ipg_clk=66Mhz
 * @param		: 无
 * @return 		: 无
 */
void delay_init(void)
{
	GPT1->CR = 0; 					/* 清零,bit0也为0,即停止GPT  			*/

	GPT1->CR = 1 << 15;				/* bit15置1进入软复位 				*/
	while((GPT1->CR >> 15) & 0x01);	/*等待复位完成 						*/
	
	/*
   	 * GPT的CR寄存器,GPT通用设置
   	 * bit22:20	000 输出比较1的输出功能关闭,也就是对应的引脚没反应
     * bit9:    0   Restart模式,当CNT等于OCR1的时候就产生中断
     * bit8:6   001 GPT时钟源选择ipg_clk=66Mhz
     * bit
  	 */
	GPT1->CR = (1<<6);

	/*
     * GPT的PR寄存器,GPT的分频设置
     * bit11:0  设置分频值,设置为0表示1分频,
     *          以此类推,最大可以设置为0XFFF,也就是最大4096分频
	 */
	GPT1->PR = 65;	/* 设置为65,即66分频,因此GPT1时钟为66M/(65+1)=1MHz */

	 /*
      * GPT的OCR1寄存器,GPT的输出比较1比较计数值,
      *	GPT的时钟为1Mz,那么计数器每计一个值就是就是1us。
      * 为了实现较大的计数,我们将比较值设置为最大的0XFFFFFFFF,
      * 这样一次计满就是:0XFFFFFFFFus = 4294967296us = 4295s = 71.5min
      * 也就是说一次计满最多71.5分钟,存在溢出
	  */
	GPT1->OCR[0] = 0XFFFFFFFF;

	GPT1->CR |= 1<<0;			//使能GPT1

	/* 一下屏蔽的代码是GPT定时器中断代码,
	 * 如果想学习GPT定时器的话可以参考一下代码。
	 */
#if 0
	/*
     * GPT的PR寄存器,GPT的分频设置
     * bit11:0  设置分频值,设置为0表示1分频,
     *          以此类推,最大可以设置为0XFFF,也就是最大4096分频
	 */
	GPT1->PR = 65;	//设置为1,即65+1=66分频,因此GPT1时钟为66M/66=1MHz


	 /*
      * GPT的OCR1寄存器,GPT的输出比较1比较计数值,
      * 当GPT的计数值等于OCR1里面值时候,输出比较1就会发生中断
      * 这里定时500ms产生中断,因此就应该为1000000/2=500000;
	  */
	GPT1->OCR[0] = 500000;

	/*
     * GPT的IR寄存器,使能通道1的比较中断
     * bit0: 0 使能输出比较中断
	 */
	GPT1->IR |= 1 << 0;

	/*
     * 使能GIC里面相应的中断,并且注册中断处理函数
	 */
	GIC_EnableIRQ(GPT1_IRQn);	//使能GIC中对应的中断
	system_register_irqhandler(GPT1_IRQn, (system_irq_handler_t)gpt1_irqhandler, NULL);	//注册中断服务函数	
#endif
	
}

#if 0
/* 中断处理函数 */
void gpt1_irqhandler(void)
{ 
	static unsigned char state = 0;

	state = !state;

	/*
     * GPT的SR寄存器,状态寄存器
     * bit2: 1 输出比较1发生中断
	 */
	if(GPT1->SR & (1<<0)) 
	{
		led_switch(LED2, state);
	}
	
	GPT1->SR |= 1<<0; /* 清除中断标志位 */
}
#endif
 
/*
 * @description		: 微秒(us)级延时
 * @param - value	: 需要延时的us数,最大延时0XFFFFFFFFus
 * @return 			: 无
 */
void delayus(unsigned    int usdelay)
{
	unsigned long oldcnt,newcnt;
	unsigned long tcntvalue = 0;	/* 走过的总时间  */

	oldcnt = GPT1->CNT;
	while(1)
	{
		newcnt = GPT1->CNT;
		if(newcnt != oldcnt)
		{
			if(newcnt > oldcnt)		/* GPT是向上计数器,并且没有溢出 */
				tcntvalue += newcnt - oldcnt;
			else  					/* 发生溢出    */
				tcntvalue += 0XFFFFFFFF-oldcnt + newcnt;
			oldcnt = newcnt;
			if(tcntvalue >= usdelay)/* 延时时间到了 */
			break;			 		/*  跳出 */
		}
	}
}

/*
 * @description		: 毫秒(ms)级延时
 * @param - msdelay	: 需要延时的ms数
 * @return 			: 无
 */
void delayms(unsigned	 int msdelay)
{
	int i = 0;
	for(i=0; i<msdelay; i++)
	{
		delayus(1000);
	}
}

/*
 * @description	: 短时间延时函数
 * @param - n	: 要延时循环次数(空操作循环次数,模式延时)
 * @return 		: 无
 */
void delay_short(volatile unsigned int n)
{
	while(n--){}
}

/*
 * @description	: 延时函数,在396Mhz的主频下
 * 			  	  延时时间大约为1ms
 * @param - n	: 要延时的ms数
 * @return 		: 无
 */
void delay(volatile unsigned int n)
{
	while(n--)
	{
		delay_short(0x7ff);
	}
}


到了这里,关于I.MX6ull GPT高精度定时器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 016——DHT11驱动开发(基于I.MX6uLL)

    016——DHT11驱动开发(基于I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 电路描述 1.3 通信协议 二、 驱动程序 三、 应用程序 四、 上机实验         DHT11 是一款可测量温度和湿度的传感器。比如市面上一些空气加湿器,会测量空气中湿度,再根据测量结果决定是否继续加湿。DHT11 数字温湿度传感器是一款含有已

    2024年04月16日
    浏览(9)
  • I.MX6ULL ARM驱动开发---网络设备驱动框架

    I.MX6ULL ARM驱动开发---网络设备驱动框架

      网络驱动是 linux 里面驱动三巨头之一,linux 下的网络功能非常强大,嵌入式 linux 中也常常用到网络功能。前面我们已经讲过了字符设备驱动和块设备驱动,本章我们就来学习一下 linux 里面的网络设备驱动。   网络设备驱动程序的体系结构分为4层,依次为网络协议驱

    2023年04月17日
    浏览(8)
  • 018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

    018——红外遥控模块驱动开发(基于HS0038和I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 协议 二、 驱动代码 三、 应用代码 四、 实验 五、 程序优化         红外遥控被广泛应用于家用电器、工业控制和智能仪器系统中,像我们熟知的有电视机盒子遥控器、空调遥控器。红外遥控器系统分为发送端和接收端,如图下图所示。

    2024年04月16日
    浏览(10)
  • 017——DS18B20驱动开发(基于I.MX6uLL)

    017——DS18B20驱动开发(基于I.MX6uLL)

    目录 一、 模块介绍 1.1 简介 1.2 主要特点 1.3 存储器介绍 1.4 时序 1.5 命令 1.5.1 命令大全    1.5.2 命令使用 1.5.3 使用示例 1.6 原理图 二、 驱动程序 三、 应用程序 四、 测试         DS18B20 温度传感器具有线路简单、体积小的特点,用来测量温度非常简单,在一根通信线上

    2024年04月12日
    浏览(11)
  • i.MX6ULL驱动开发 | 27 - 使用WM8960 CODEC播放音频

    i.MX6ULL驱动开发 | 27 - 使用WM8960 CODEC播放音频

    WM8960是欧胜公司(wolfson)的一款低功耗、高质量的立体声音频编解码芯片。 其内部集成D类喇叭功放,每个通道可以驱动一个1W喇叭(8Ω),内部集成3个立体声输入源,可以灵活配置,拥有一路完整的麦克风接口。 WM8960内部ADC和DAC都为24位,主要特性如下: DAC的SNR(信噪比)

    2024年02月02日
    浏览(10)
  • linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)

    linux驱动开发 ST7789 LCD驱动移植(I.MX6ULL平台)

    前言 I.MX6ULL的板子未选配RGB的屏幕,无法在板子上进行GUI的开发调试,不过手头上有块控制器为ST7789V3的LCD屏幕(1.3inch),通过简易接线后可以很方便进行驱动的移植 如有异议,欢迎留言指正 ST7789 LCD控制器 ST7789是一款单芯片TFT-LCD控制器,支持并口与SPI通信方式 特性 控制器支

    2023年04月09日
    浏览(12)
  • 使用一根网线,让Ubuntu和正点原子I.MX6ULL开发板互相ping通

    使用一根网线,让Ubuntu和正点原子I.MX6ULL开发板互相ping通

    准备一根网线即可 2.1 找根网线将I.MX6ULL和电脑连起来 2.2 让I.MX6ULL通电运行起来,我这里使用的是正点原子版本的内核、 2.3 进入电脑的网络连接后,按照如下步骤操作 2.4 将ip地址、子网掩码、默认网关设置如下,= 注意,子网掩码一定要是255.255.255.0 IP地址推荐使用192.168.5.

    2024年02月19日
    浏览(19)
  • i.MX6ULL移植NXP官方Linux内核imx_5.4.47_2.2.0

    i.MX6ULL移植NXP官方Linux内核imx_5.4.47_2.2.0

    系统:Ubuntu18.04 参考资料:百问网 IMX6ULL开发板(从零移植篇-预览版)-V0.1,正点原子驱动开发指南 开发板:100ask i.MX6ULL PRO 交叉编译工具链的获取就不写了 打开 .bashrc 文件。 vi ~/.bashrc 。在该文件最后面添加如下(根据自己的交叉编译工具链) (1)直接从官网下载,非常慢而

    2024年02月12日
    浏览(47)
  • 【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本

    【Linux 裸机篇(五)】I.MX6ULL BSP工程管理下的 Makefile编写、链接脚本

    文件夹 描述 bsp 存放驱动文件 imx6ul 存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件 obj 存放编译生成的.o 文件 project 存放 start.S 和 main.c 文件,也就是应用文件 行 描述 1~7 定义了一些变量,除了第 2 行以外其它的都是跟编译器有关的,如果使用其它编译器的话只需要修改第

    2023年04月20日
    浏览(14)
  • 基于I.MX6ULL的Linux C多线程物联网网关+STM32+Qt上位机+Linux C++多线程服务器(含web)的多种无线通信系统的智慧农场

    我国是农业大国,而非农业强国。近30年来农业高产量主要依靠农药化肥的大量投入,大部分化肥和水资源没有被有效利用而随地弃置,导致大量养分损失并造成环境污染。我国农业生产仍然以传统生产模式为主,传统耕种只能凭经验施肥灌溉,不仅浪费大量的人力物力,也

    2024年04月14日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包