I.MX6U-ALPHA开发板(高精度定时器)

高精度定时器

​ 我们需要高精度的延时函数,而且不随着主频的变化而改变。

​ STM32使用SYSTICK这个硬件定时器来实现高精度延时,因此我们可以在6U里面使用一个硬件定时器来实现高精度延时。

GPT定时器

​ 我们使用6U的GPT定时器来实现高精度延时。

GPT定时器是32位向上计数器

GPT定时器有捕获的功能

GPT定时器支持比较输出或中断功能

GPT定时器有一个12位的分频器

GPT时钟源可以选择,这里我们使用ipg_clk=66M作为GPT的时钟源。

GPT定时器有两种工作模式:restartfree-run

Restart模式下:定时器计数值和比较寄存器OCR的值相等的话定时器就会重新从0开始计时。注意!只有比较通道1才有此功能。

Free-run模式:所有三个输出比较通道都适用。从0开始一直加到0xffffffff,然后重新从0开始,周而复始。

GPT_CR寄存器

Bit0为GPT使能位,为0的时候关闭GPT,为1的时候使能GPT。

Bit1确定GPT定时器计数器的初始值,为0的时候表示GPT定时器计数值默认为上次关闭的时候遗留的值,为1的话计数值为0。

Bit8~6为时钟源的选择,设置为1,表示GPT时钟源为ipg_clk=66MHz。

Bit9设置GPT定时器工作模式,为0的时候工作在restart模式,为1的时候工作在free-run模式。

Bit15软件复位。

GPT_CR寄存器的Bit11~0为分频值,可设置0-4095,表示1~4096分频。

GPT_SR寄存器

Bit5表示溢出发生

Bit4和Bit3分别为输入通道2和1的捕获中断标志位。

Bit2~0,也就是OF3~OF1为比较中断。

GPT_IR寄存器,也就是中断使能寄存器

//bsp_delay.h
#ifndef __BSP_DELAY_H
#define __BSP_DELAY_H

#include "imx6ul.h"


/* 函数声明 */
void delay_init(void);
void delayus(unsigned    int usdelay);
void delayms(unsigned	 int msdelay);
void delay(volatile unsigned int n);
void gpt1_irqhandler(void);
#endif
//bsp_delay.c
#include "bsp_delay.h"

//延时有关硬件初始化,主要是GPT定时器,GPT定时器时钟源选择ipg_clk=66Mhz
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
 
//微秒(us)级延时
//需要延时的us数,最大延时0XFFFFFFFFus
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;			 		// 跳出
		}
	}
}

//毫秒(ms)级延时
//需要延时的ms数
void delayms(unsigned	 int msdelay)
{
	int i = 0;
	for(i=0; i<msdelay; i++)
	{
		delayus(1000);
	}
}

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

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

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值