ARM嵌入式学习--第七天(GPT)

GPT

-介绍

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

-特征

1.一个带时钟源选择的32位向上计数器 ,包括外部时钟

2.俩个具有可编程触发边缘的输入捕获通道

3.三个具有可编程输出模式的输出比较通道 (还提供强制比较功能)

4.可编程为在低功耗调试模式 下处于活动状态

5.在捕获比较翻转 事件时中断生成

6.为计数器操作重新启动或自由运行模式

-GPT的工作原理

选择时钟信号

IMX6ULL有4个时钟源可供GPT选择输入到预分频器,分别为:

1.高频参考时钟 (ipg_clk_highfreq)

2.低频参考时钟 (ipg_clk_32k)

3.外围时钟 (ipg_clk)

4.外部时钟 (GPT_CLK)或者晶体振荡器时钟 (ipg_clk_24M)

(外部时钟或晶体振荡器只能选择一个)

这里选择ipg_clk=66MHZ作为GPT定时器的输入时钟源,芯片在启动的时候,芯片内部的程序已经做了系统时钟的初始化

预分频设置寄存器(GPT_PR)

时钟频率与预分频数的关系 :最终输入频率=时钟频率/(预分频数+1)

GPT计数器工作模式

GPT计数器可以编程为以俩种模式之一工作:重新启动模式自由运行模式

在重新启动模式下 (可通过GPT控制寄存器GPT_CR选择),当计数器达到比较值 时,计数器复位并从0x000000000再次启动 (重新启动功能仅与比较通道1相关联)

在自由运行模式下 ,当所有3个通道发生比较事件时,计数器不会重置 ;相反,计数器会继续计数,直到0xffffffffff,然后归零

GPT操作

通用计时器(GPT)有一个计数器 (GPT_CNT),它是一个32位自由运行的向上计数器 ,它在软件启用后开始计数 (EN=1)

tips

1.如果禁用GPT计时器(EN=0),则主计数器和预分频计数器将冻结其当前计数值 。ENMOD位确定设置EN位并再次启用计数器时GPT计数器的值

2.如果设置了ENMOD位(=1),则启用GPT时,主计数器和预分频器计数器值将重置为0 (EN=1)

3.如果ENMOD位被编程为 0,则当GPT再次启用时(EN=1),主计数器和预分频器计数器从其冻结值重新开始计数

软件复位(GPT_CR控制寄存器中的 SWR )复位除EN,ENMOD,STOPEN,WAITEN和DBGEN位之外的所有寄存器位 。这些位的状态不受软件复位的影响 (禁用GPT时,可以进行软件复位)

-GPT的输入捕获

使用场景

在嵌入式开发中,经常需要捕获传感器的高电平(或低电平)信号的持续时间,如红外解码信号,编码器输入信号等

直观的理解,就是要不断的检测这个信号 ,当信号从0变成1 时,记录一个时间time1,再从1变成0 时,记录另一个时间time2,俩个时间差就是高电平的持续时间(time2-time1)

工作原理

1.启动定时器,让CNT计数器在不停的计数

2.首先配置定时器的输入通道为上升沿捕获 ,这样当检测到从0到1的跳变时,ICR(捕获寄存器 )就会先保存当前的CNT值

3.然后将定时器的输入通道为下降沿捕获 ,当检测到从1到0的跳变时,ICR就会保存当前的CNT值

4.最终根据俩次捕获的值,就可以计算出高电平持续时间

tips:

IMX6ull芯片有俩个GPT定时器

-GPT的输出比较

工作原理

有三个输出比较通道 ,它们使用相同的计数器(GPT_CNT) 作为输入捕获通道。当输出比较寄存器的编程内容与GPT_CNT中的值匹配时设置输出比较状态标志并生成中断

(还有一个"强制比较 "(forced-compare)功能,一但设置,就会马上产生比较事件,不管当前计数器的值是否等于比较值 ,强制比较的产生的事件,跟正常的输出事件相同 ,只是它不会设置状态标记位并且不会产生中断 ,一旦设置force-compare位,该事件就会即刻产生,这个位是自动清除的)

-高精度延时实现

实现思路

1.软件复位GPT定时器

2.确定GPT定时器的时钟源

3.预分频器的设置

4.确定比较寄存器的值(根据延时时间来确定)

5.开启GPT定时器

6.等待输出比较事件的产生

7.关闭GPT定时器

代码实现
gpt.c
cs 复制代码
#include "gpt.h"

//初始化
void gpt_int(){
//停止gpt
    GPT1->CR &= ~(0x1<<0);
//软件复位gpt
    GPT1->CR |= (0x1<<15);
//等待复位状态
    while(GPT1->CR & (0x1<<15));
//时钟源选择
    GPT1->CR &= ~(0x7<<6);
    GPT1->CR |=(0X1<<6);
}

//预分频器设置
void gpt_divide(){
    GPT1->PR &= ~(0xfff<<0);
    GPT1->PR |= (0x41<<0);
}


//开始GPT
void gpt_start(){
//设置ENMOD
    GPT1->CR |= (0x1<<1);
//设置工作模式FRR
    GPT1->CR |=(0x1<<9);
//使能gpt
    GPT1->CR |= (0x1<<0);
}

//关闭GPT
void gpt_stop(){
    GPT1->CR &= ~(0x1<<0);
}


//设置比较寄存器的值
void gpt_compare(int value){
    GPT1->OCR3 = value;
}

//等待比较事件的发生
void gpt_wait_compare(){
    while(!(GPT1->SR & (0x1<<2)));
}

void gpt_delay_useconds(int value){
    gpt_int();
    gpt_divide();
    gpt_compare(value);
    gpt_start();
    gpt_wait_compare();
    gpt_stop();
}

void gpt_delay_mseconds(int value){
    gpt_int();
    gpt_divide();
    gpt_compare(value*1000);
    gpt_start();
    gpt_wait_compare();
    gpt_stop();
}

void gpt_delay_seconds(int value){
    gpt_int();
    gpt_divide();
    gpt_compare(value*1000*1000);
    gpt_start();
    gpt_wait_compare();
    gpt_stop();
}
gpt.h
cs 复制代码
#ifndef __GPT_HEAD__
#define __GPT_HEAD__


#include "../../include/imx6ull.h"
#include <stdio.h>


extern void gpt_delay_seconds(int value);
extern void gpt_delay_mseconds(int value);
extern void gpt_delay_useconds(int value);
#endif 
相关推荐
朱友斌17 分钟前
【Golang笔记01】Golang基础语法规则
笔记·学习·golang·go语言·golang笔记
摇摇奶昔x18 分钟前
webpack 学习
前端·学习·webpack
海尔辛41 分钟前
学习黑客Kerberos深入浅出:安全王国的门票系统
学习·安全·kerberos·window
霸王蟹1 小时前
React 19中如何向Vue那样自定义状态和方法暴露给父组件。
前端·javascript·学习·react.js·typescript
Moonnnn.1 小时前
【数字电路】第七章 脉冲波形的产生与整形电路
笔记·学习
猴子请来的逗比4892 小时前
tomcat查看状态页及调优信息
服务器·学习·tomcat·firefox
贺函不是涵3 小时前
【沉浸式求职学习day43】【Java面试题精选3】
java·开发语言·学习
maray3 小时前
ETL 学习
数据仓库·学习·etl
海尔辛4 小时前
学习黑客Active Directory入门
学习·ad·window
superior tigre4 小时前
C++学习:六个月从基础到就业——C++20:协程(Coroutines)
c++·学习·c++20