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);
    }
}
相关推荐
kyriewen12 小时前
白宫前脚下了限制令,OpenAI 后脚就把 GPT-5.6 发了
前端·gpt·openai
AI工程效率栈2 天前
AI 帮你补异常处理时,新人最容易犯的错:把失败悄悄变成成功
gpt·chatgpt
AlfredZhao4 天前
GPT 省钱,不是别用最新模型,而是别浪费缓存
gpt·ai
newbe365249 天前
对接 Reasonix 1.x 跑通 DeepSeek V4:ACP 模型选择器接入实战
gpt·claude·chatglm (智谱)
newbe365249 天前
如何使用 Upptime 免费搭建自己的状态站点
gpt·claude·chatglm (智谱)
gis分享者10 天前
GPT-Image-2 图像生成模型新手实战指南
gpt·ai·image·模型·图像生成
Nayxxu11 天前
GPT 多模态 API 接入思路:文本、图片、音频请求怎么拆分
gpt