ARM裸机开发:GPT定时器
ARM裸机开发:GPT定时器
一、硬件平台:
正点原子I.MX6U阿尔法开发板

二、原理分析
I.MX6U 提供了多种硬件定时器,有些定时器功能强大;本章介绍的 GPT 定时器主要用来实现高精度延时,下面对 GPT原理做个简单的分析:
2.1 GPT定时器简介
GPT 定时器是一个 32 位向上定时器 (也就是从 0X00000000 开始向上递增计数),GPT 定时器可以跟一个值进行比较,当计数器值和这个值相等的话就发生比较事件,产生比较中断
GPT 定时器有一个 12 位的分频器,可以对 GPT 定时器的时钟源进行分频
GPT 定时器特性如下:
① 一个可选时钟源的 32 位向上计数器
② 两个输入捕获通道,可以设置触发方式
③ 三个输出比较通道,可以设置输出模式
④ 可以生成捕获中断、比较中断和溢出中断
⑤ 计数器可以运行在重新启动 (restart) 或(自由运行) free-run 模式
GPT 的时钟源可选 5 个:

这5个时钟源对应如下:
- ipg_clk_24M
- GPT_CLK(外部时钟)
- ipg_clk
- ipg_clk_32k
- ipg_clk_highfreq
我们选择 ipg_clk 为 GPT 的时钟源,ipg_clk 为 66MHz
GPT 定时器结构如下:

图中信号走线如下:
-  时钟源 
-  分频器 
-  定时器计数器 
-  输入捕获 
-  输入捕获 
-  输出比较 
-  输出比较中断 
2.2 GPT有关寄存器
2.2.1 GPT配置寄存器
寄存器结构:

SWR(bit15):复位 GPT 定时器
FRR(bit9):运行模式选择
CLKSRC(bit8:6):GPT 定时器时钟源选择位
ENMOD(bit1):GPT 使能模式
EN(bit0):GPT 使能位
2.2.2 GPT分频寄存器
寄存器结构:

PRESCALER(bit11:0): 12 位分频值
2.2.3 GPT状态寄存器
寄存器结构:

ROV(bit5):回滚标志位
IF2~IF1(bit4:3):输入捕获标志位
OF3~OF1(bit2:0):输出比较中断标志位
2.2.4 GPT计数寄存器
GPTx_CNT 保存着 GPT 定时器的当前计数值
2.3 GPT使用步骤
- 设置 GPT1 定时器
 先复位再设置具体参数
- 设置 GPT1 的分频值
 设置寄存器 GPT1_PR 寄存器配置分频值
- 设置 GPT1 的比较值
 用到比较输出中断时设置
- 使能 GPT1 定时器
- 编写延时函数
 编写延时函数进行高精度延时
三、程序编写
GPT 用于高精度延时,所以我们复制上一章的工程,修改其延时文件
bsp_delay.c 文件代码修改如下
#include "bsp_delay.h"
#include "imx6ul.h"
void delay(volatile unsigned int n)
{
	while(n--)
	{
		volatile unsigned int i = 0x7ff;
		while(i--);
	}
}
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
}
void delay_us(volatile unsigned int nus)
{
	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 >= nus)/* 延时时间到了 */
			break;			 		/*  跳出 */
		}
	}
}
void delay_ms(volatile unsigned int nms)
{
	int i = 0;
	for(i=0; i<nms; i++)
	{
		delayus(1000);
	}
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
bsp_delay.h 文件代码修改如下
#ifndef __BSP_DELAY_H
#define __BSP_DELAY_H
void delay(volatile unsigned int n);
void delay_init(void);
void delay_us(volatile unsigned int nus);
void delay_ms(volatile unsigned int nms);
#endif
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
主函数调用延时函数进行延时
#include "bsp_led.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_exit.h"
#include "bsp_epit.h"
#include "imx6ul.h"
int main(void)
{
    CLK_INIT();
    int_init();
    BSP_KEY_INIT();
    LED_INIT();
    delay_init();
    while (1)
    {
        /* code */
        LED_ON();
        delay_ms(1000);
        LED_OFF();
        delay_ms(1000);
    }
    return 0;
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
四、实验现象
LED 按照 1s 的频率进行翻转
文章来源: blog.csdn.net,作者:JeckXu666,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_45396672/article/details/121479719
- 点赞
- 收藏
- 关注作者
 
             
           
评论(0)