ARM——General Purpose Timer (GPT)

配置延时函数

GPT 是一款 32 位多功能定时器,输入时钟经 12 位预分频器(1~4096 分频)后驱动 32 位计数器自由计数;它同时支持输入捕获输出比较两大核心功能:输入捕获通道可在引脚电平跳变时(如 GPT_CAPTURE1 的上升沿),将当前计数值锁存到对应 Timer Input Reg 并触发捕获中断;输出比较通道则通过将计数器值与 3 组 Timer Output Reg 比对,匹配后触发输出中断并通过输出模块控制引脚电平变化;此外计数器溢出时也可触发溢出中断,所有中断经汇总后发送给处理器,整体可实现精准定时、脉冲测量、PWM 输出等多种场景,且支持自由运行模式,无需 CPU 频繁干预。


这次用通用定时器进行delay函数的编写

该定时器的计数器Timer Counter 32-bit是往上加的,当计数器的值等于Timer Output Reg1 32-bit/Timer Output Reg 2 32-bit/Timer Output Reg3 32-bit这三个时,其对应的GPT_COMPARE的引脚便会发生变化(电平如何变化自己设置)。

进行寄存器的配置

1、GPT Control Register (GPTx_CR)

GPTx_CR 是 GPT 定时器的核心控制寄存器,用于全局启停、模式选择、时钟源配置、中断控制及功能使能,是 GPT 初始化和运行控制的关键入口。

本次由于只是当成计数器使用,CR寄存器IM/OM这些关于捕获的都不使用,此次仅配置FRR,选择free-run模式,CLCKSRC选择外设时钟(66M),ENMODE定时器失能后保留原来的值,以及EN使能寄存器

2、GPT Prescaler Register (GPTx_PR)

GPTx_PR 是 12 位可读可写寄存器,用于配置 GPT 定时器的预分频系数,对输入时钟源进行分频,从而得到驱动 32 位计数器的最终计数时钟。

本次将其配置为66分频

cpp 复制代码
void gpt1_init(void)
{
    gpt1_reset();  

    unsigned int tmp = GPT1->CR;
    tmp &= ~(0x1ff<<20);
    tmp &= ~(0xf << 16);

    tmp |= (1 << 9);
    tmp &= ~(0x7 << 6);
    tmp |= (1 << 6);
    tmp &= ~(1 << 1);
    GPT1->CR = tmp;

    tmp = GPT1->PR;
    tmp &= ~(0xfff << 0);
    tmp |= (65 << 0);
    GPT1->PR = tmp;

    GPT1->CR |= (1 << 0);
}

编写延时函数

GPTx_CNT 是 GPT 定时器的32 位只读计数寄存器,专门用于实时存放计数器当前的计数值;定时器使能后,它会在分频后的时钟驱动下持续递增计数,自由运行模式下计满溢出后自动从 0 重新开始,输入捕获触发时硬件会自动将该寄存器的值锁存到输入捕获寄存器,输出比较则实时将它与比较寄存器的值进行比对,匹配后触发对应动作,读取该寄存器可直接获取当前计时数值。

GPT1->CNT 就是一个一直在自己数数的计数器

刚进函数 → 记起点(old)

过一会儿 → 看现在(cur)

现在 - 起点 = 过去了多少时间

把过去的时间累加起来

累加到你要的数值 → 延时结束

处理溢出

定时器会从很大的数突然变回 0,所以你要补上一圈的长度,让差值正确

cpp 复制代码
void  inline delay_us(unsigned int num)
{
    unsigned int counter = 0;
    unsigned int old_counter = GPT1->CNT;
    unsigned int cur_counter = 0;
    while(1)
    {
        cur_counter = GPT1->CNT;
        if(cur_counter == old_counter)
            continue;
        if(cur_counter > old_counter)
            counter += cur_counter - old_counter;
        else if(cur_counter < old_counter)
            counter += cur_counter + 0xffffffff - old_counter;
        if(counter >= num)
            return;
        old_counter = cur_counter;
    }

}

void delay_ms(unsigned int num)
{
    while(num--)
    {
        delay_us(1000);
    }
}
相关推荐
智算菩萨11 小时前
【实战讲解】ChatGPT 5.4深度文献检索完全指南:提示词工程与学术实战策略
论文阅读·人工智能·gpt·搜索引擎·chatgpt·提示词·论文笔记
xuxie9913 小时前
N8 ARM第一个程序点灯
arm开发
somi718 小时前
ARM-06-时钟系统配置
arm开发·单片机·嵌入式硬件·时钟配置
坤坤藤椒牛肉面20 小时前
ARM时钟配置
arm开发
-Try hard-21 小时前
ARM | 点亮LED灯!
arm开发·单片机·嵌入式硬件
泛凡(Linyongui)21 小时前
一款基于LP4057芯片的单节 4.2V 锂电池线性充电管理电路,带电源路径自动切换功能
arm开发·单片机·py32
victory04311 天前
karpathy 4种GPT仓库在做基础LLM研究情况下应该如何选择
gpt
惶了个恐1 天前
嵌入式硬件第五弹——ARM(2)
arm开发·嵌入式硬件
EnglishJun1 天前
ARM嵌入式学习(十一)--- IMX6ULL时钟配置
arm开发·学习