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 
相关推荐
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。5 天前
2026.2.25监控学习
学习
im_AMBER5 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J5 天前
从“Hello World“ 开始 C++
c语言·c++·学习