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 
相关推荐
LuckyLay5 分钟前
Golang学习笔记_08——For循环
笔记·学习·golang
LuckyLay6 分钟前
Golang学习笔记_13——数组
笔记·学习·golang·数组·array
zhxueverme1 小时前
java面试八股文学习笔记
java·学习·面试
小A1592 小时前
STM32完全学习——独立看门狗和窗口看门狗
stm32·单片机·学习
爱喝coffee的人2 小时前
关于SpringBoot中AOP的深入理解
java·开发语言·spring boot·后端·学习·spring
Huazzi.2 小时前
Linux(Ubuntu)命令大全——已分类整理,学习、查看更加方便直观!(2024年最新编制)
linux·学习·ubuntu
CSBLOG2 小时前
Day26下 - 大语言模型的 训练train 和 微调fine-tune 的区别
人工智能·学习·语言模型
知识分享小能手2 小时前
Java学习教程,从入门到精通,Java ConcurrentHashMap语法知识点及案例代码(63)
java·大数据·开发语言·学习·intellij-idea·后端开发·java开发
Dnui_King3 小时前
从零开始学TiDB(6)深入学习Placement Driver(PD)
学习·tidb