一、GPT比较匹配功能详解

比较匹配主要是用来实现输出 PWM 波形功能的一种机制。 其原理简单来讲就是通过比较 GTCNT 计数器的值与 GTCCRA 或 GTCCRB 的值,当比较匹配发生时,会生成相应的比较匹配事件信号, 同时,GPT 可以切换 GTIOCnA 或 GTIOCnB 输出引脚的输出信号,可以选择输出低电平、高电平或翻转输出。 在 GTCNT 完成一个周期的计数时,也可以切换 GTIOCnA 或 GTIOCnB 输出引脚的输出信号。

PWM 输出就是对外输出脉宽(即占空比)可调的方波信号, 信号频率由周期设定寄存器 GTPR 的值决定,占空比由比较寄存器 GTCCR 的值决定。

GPT 的输出模式有:

  • 锯齿波 PWM 模式(Saw-wave PWM mode)(该模式下单缓冲或双缓冲都可使用)

  • 锯齿波单脉冲模式(Saw-wave one-shot pulse mode)(该模式下使用固定的缓冲操作)

  • 三角波 PWM 模式1(Triangle-wave PWM mode 1)(波谷32位传输)(该模式下单缓冲或双缓冲都可使用)

  • 三角波 PWM 模式2(Triangle-wave PWM mode 2)(波峰和波谷32位传输)(该模式下单缓冲或双缓冲都可使用)

  • 三角波 PWM 模式3(Triangle-wave PWM mode 3)(波谷64位传输)(该模式下使用固定的缓冲操作)

我们在前面有提到过每个GPT定时器模块内部都有 6个 GTCCRx 寄存器(x = A,B,C,D,E,F), 下面就先来了解一下有关 GTCCRx 的缓冲操作。

单缓冲操作:

以 GTIOCA 输出为例,若需要修改占空比,则需要在 GTCCRC 写入要修改的比较值, GTCNT 计数完成后则会将 GTCCRC 的值写入 GTCCRA,如下图所示。

在这里插入图片描述

双缓冲操作:

在三角波 PWM 输出模式下,GTCCRA / GTCCRB 各有两个缓存,缓存传输的顺序分别为:

  • GTCCRD -> GTCCRC -> GTCCRA

  • GTCCRF -> GTCCRE -> GTCCRB

以 GTIOCA 为例,如下图所示。
在这里插入图片描述

1. 锯齿波PWM模式(普通PWM模式)

这里的锯齿波 PWM 模式即我们通常一般所说的 PWM 输出模式,该模式的效果是输出一个普通的 PWM 波形。 其原理是:GTCNT 进行递增计数,当 GTCNT 与 GTCCRA / GTCCRB 比较相等时, 输出到 GTIOCnA / GTIOCnB 引脚的 PWM 波形发生变化(一般是翻转电平), 然后当 GTCNT 计数到 GTPR 周期设置寄存器的值相等后,在下一个时钟计数是计数器清零, 此时输出到 GTIOCnA / GTIOCnB 引脚的 PWM 波形也发生变化。 在这整个过程中,GTCNT 计数器的计数值以锯齿波的方式变化(计数器递增计数或递减计数)。

需要注意,这里的锯齿波指的是,GTCNT 计数器的值以锯齿波的方式变化,也就是 GTCNT 向上递增计数或向下递减计数, 并不是指 GTIOCnA 和 GTIOCnB 这两个 IO 引脚输出锯齿波, 记住无论在哪个 PWM 模式下,IO 引脚输出的都是逻辑值为 0 或 1 的高低电平。

当 GTCNT 与 GTCCRA / GTCCRB 相等,以及 GTCNT 完成一个周期的计数时,IO引脚切换为高电平、低电平、翻转电平或者维持电平不变。 具体可以由寄存器 GTIOR 的位段 GTIOB / GTIOA 控制,这个位段的控制逻辑如下表所示。 b4为1时,初始化电平为高电平,其他与下表相同,为节省篇幅,省略这一部分。
在这里插入图片描述
在锯齿波 PWM 模式下可使用单缓冲操作或者双缓冲操作。 在单缓冲操作模式下,GTCCRC 作为 GTCCRA 的缓存,GTCCRE 作为 GTCCRB 的缓存。 如下图所示的示例是在 GTCNT 向上计数,发生比较匹配时输出高电平,计数周期结束时输出低电平, 即 GTIOA / GTIOB 的 b3~b0 依次为 0110 时,GTIOCxA / GTIOCxB 引脚的输出时序。

锯齿波 PWM 模式的输出波形时序图如下图所示。
在这里插入图片描述

2. 三角波PWM模式1(波谷32位传输)

这里的三角波同样指的是,GTCNT 内的值以三角波的方式变化,也就是 GTCNT 向上递增计数接着向下计数递减计数。 其他地方与锯齿波 PWM 模式基本相同。 如下图所示的示例是在初始化时 GTIOCnA 输出低电平,GTIOCnB 输出高电平,当 GTCCRA / GTCCRB 发生比较匹配时, GTIOCxA / GTIOCxB 反转电平,GTIOCxA/GTIOCxB 的输出时序。

三角波 PWM 模式 1 的输出波形时序图如下图所示。
在这里插入图片描述

3. 三角波PWM模式2(波峰和波谷32位传输)

该模式与三角波 PWM 模式1的区别在于在波峰和波谷都会传输缓冲。也属于单缓冲操作。

三角波 PWM 模式 2 的输出波形时序图如下图所示。
在这里插入图片描述

4. 三角波PWM模式3(波谷64位传输)

该模式与三角波 PWM 模式1一样都是在波谷传输缓冲,区别在于该模式属于双缓冲操作。

三角波 PWM 模式 3 的输出波形时序图如下图所示。
在这里插入图片描述

5. 设置死区时间

死区时间可通过设置 GTCCRA / GTCCRB 来配置。 自动死区时间设置功能可用于锯齿波单脉冲模式和所有三角波 PWM 模式。

二、GPT输入捕获功能详解

输入捕获是定时器的一项非常重要的功能。通过输入捕获功能, 可以测量高低电平脉冲的脉宽、信号的周期、频率和 PWM 占空比等。

在检测到在 GTICASR 和 GTICBSR 中设置的硬件源时,可以将 GTCNT 计数器值传输到 GTCCRA 或 GTCCRB,这便是 GPT 的输入捕获功能。 “输入捕获”根据“输入”来触发“捕获” GTCNT 计数器的值,更加具体地说: 硬件在检测到我们所设置的硬件源时,“捕获” GTCNT 计数器的值并转存到 GTCCRA 或 GTCCRB 寄存器。

可以设置如下硬件源来触发执行输入捕获:

  • 在 GTETRGA 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGA 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGB 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGB 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGC 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGC 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGD 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 在 GTETRGD 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnB 输入为 0 时,在 GTIOCnA 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnB 输入为 1 时,在 GTIOCnA 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnB 输入为 0 时,在 GTIOCnA 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnB 输入为 1 时,在 GTIOCnA 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnA 输入为 0 时,在 GTIOCnB 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnA 输入为 1 时,在 GTIOCnB 引脚输入的上升沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnA 输入为 0 时,在 GTIOCnB 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

  • 当 GTIOCnA 输入为 1 时,在 GTIOCnB 引脚输入的下降沿启用或禁用 GTCCRA / GTCCRB 的输入捕捉。

下图所示的示例清晰地展示了输入捕获的功能。 在该示例中,GTCNT 计数器通过计数时钟进行递增计数, 并且设置为在 GTIOCnA 输入引脚的两个边沿执行 GTCCRA 的输入捕捉,在 GTIOCnB 输入引脚的上升沿执行 GTCCRB 的输入捕捉。

在这里插入图片描述

三、编程实战:PWM输出

1. 硬件设计

LED灯相关的电路如下图所示。本实验仅用到 LED1~3 当中的其中一盏。
在这里插入图片描述
PWM 输出引脚使用的开发板引出的 IO 引脚: P600,如下图所示。
在这里插入图片描述

2. 软件设计

①文件结构

GPT_PWM_Output
├─ ......
└─ src
   ├─ led
   │  ├─ bsp_led.c
   │  └─ bsp_led.h
   ├─ debug_uart
   │  ├─ bsp_debug_uart.c
   │  └─ bsp_debug_uart.h
   ├─ gpt
   │  ├─ bsp_gpt_pwm_output.c
   │  └─ bsp_gpt_pwm_output.h
   └─ hal_entry.c

② FSP配置

因为 PWM 输出需要使用 IO 引脚进行输出,因此需要先在“Pins”配置页中为 GPT 配置引脚, 我们将 GPT6 的 GTIOC6B 信号输出连接到 P600 引脚,如下图所示。
在这里插入图片描述
然后在“Stacks”配置页中加入 GPT 模块,并对其作如下图所示的配置。
在这里插入图片描述
上图中框起来的部分是需要我们去修改的区域,其他的配置属性按照默认即可。 图中需要更改的配置如下:

  • Pin Output Support:这一项配置允许输出 PWM 信号到引脚,我们改为使能引脚输出。

  • Name 和 Channel:这两项分别设置 GPT 模块名字为 “g_timer_gpt6” 和选择第 6 个 GPT 定时器(第6个通道)。

  • Mode:配置 GPT 的工作模式为 PWM 输出模式。

  • Period 和 Period Unit:我们将PWM频率设为 20 KHz, 因此“Period”设置为 20,单位“Period Unit”设置为 Kilohertz,即千赫兹(KHz)。

  • GTIOCB Output Enabled:使能 GTIOCB 输出。

  • GTIOCB Stop Level:设置定时器停止时 GTIOCB 输出的电平为低电平。

  • GTIOC6B:选择连接到 P600 引脚,这个软件会自动设置的,我们只要确认了就好。

GPT的“Output”部分的属性描述如下表所示。
在这里插入图片描述

③GPT初始化函数

void GPT_PWM_Init(void)
{
    /* 初始化 GPT 模块 */
    R_GPT_Open(&g_timer_gpt6_ctrl, &g_timer_gpt6_cfg);

    /* 启动 GPT 定时器 */
    R_GPT_Start(&g_timer_gpt6_ctrl);

    /* 重新设置占空比为 80% */
    GPT_PWM_SetDuty(80);
}

④设置PWM占空比函数

/** 自定义函数:设置PWM占空比
    @param duty 占空比范围:0~100 %
*/
void GPT_PWM_SetDuty(uint8_t duty)
{
    timer_info_t info;
    uint32_t current_period_counts;
    uint32_t duty_cycle_counts;

    if (duty > 100)
        duty = 100; //限制占空比范围:0~100

    /* 获得GPT的信息 */
    R_GPT_InfoGet(&g_timer_gpt6_ctrl, &info);

    /* 获得计时器一个周期需要的计数次数 */
    current_period_counts = info.period_counts;

    /* 根据占空比和一个周期的计数次数计算GTCCR寄存器的值 */
    duty_cycle_counts = (uint32_t)(((uint64_t) current_period_counts * duty) / 100);

    /* 最后调用FSP库函数设置占空比 */
    R_GPT_DutyCycleSet(&g_timer_gpt6_ctrl, duty_cycle_counts, GPT_IO_PIN_GTIOCB);
}

⑤hal_entry入口函数

/* 用户头文件包含 */
#include "led/bsp_led.h"
#include "debug_uart/bsp_debug_uart.h"
#include "gpt/bsp_gpt_pwm_output.h"


void hal_entry(void)
{
    /* TODO: add your own code here */

    LED_Init();         // LED 初始化
    Debug_UART4_Init(); // SCI4 UART 调试串口初始化
    GPT_PWM_Init();     // GPT 初始化

    printf("这是一个 GPT 的PWM输出功能实验\r\n");
    printf("使用示波器测量 P600 输出的PWM波形\r\n");

    // LED1 闪烁指示程序正在运行...
    while(1)
    {
        LED1_ON;
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
        LED1_OFF;
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }


#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

频率 20 KHz,占空比为 50% 的PWM波形:
在这里插入图片描述
频率 20 KHz,占空比为 80% 的PWM波形:
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐