【瑞萨RA_FSP】AGT——低功耗定时器

文章目录

  • 一、AGT简介
  • 二、AGT的框图分析
    • 1. 16位计数器
    • 2. 16位重装载寄存器
    • 3. 计数时钟源
    • 4. 比较匹配功能
    • 5. 比较匹配输出引脚
    • 6. 输出引脚
    • 7. 下溢事件信号/测量完成事件信号输出
  • 三、AGT工作模式详解
  • 四、实验:比较匹配功能——PWM输出
    • 1. 硬件设计
    • 2. 文件结构
    • 3. FSP配置
    • 4. AGT初始化函数
    • 5. 设置PWM占空比函数
    • 6. hal_entry入口函数


RA MCU 有两种定时器外设:GPT(General PWM Timer)定时器和 AGT(Asynchronous General Purpose Timer)定时器。 在它们之间进行选择时,需要考虑以下因素:
【瑞萨RA_FSP】AGT——低功耗定时器_第1张图片

一、AGT简介

低功耗异步通用定时器(AGT)是 16 位的定时器,可用于基本的定时、脉冲输出、外部脉冲宽度或周期测量,以及外部事件计数。 该定时器主要由一个重加载寄存器和一个递减计数器组成。

RA MCU 的不同型号之间可能拥有不同数量的 AGT 定时器, 规格也有可能不同,比如适用于电机控制的 RA6T2 型号MCU拥有 AGTW 定时器,AGTW 的计数器位数加宽到了32位。 而对于野火启明6M5开发板上板载的 RA6M5 芯片拥有 6 个16位的 AGT 定时器(AGTn (n=0~5))。

AGT 定时器的详细功能参数如下表所示:

【瑞萨RA_FSP】AGT——低功耗定时器_第2张图片
AGT 的 I/O 引脚及其功能用途如下表所示:
【瑞萨RA_FSP】AGT——低功耗定时器_第3张图片

二、AGT的框图分析

【瑞萨RA_FSP】AGT——低功耗定时器_第4张图片

1. 16位计数器

见图中标注 ① 处。

AGT 的计数器是一个 16 位的递减计数器,因此它仅支持递减计数。

重装载寄存器和递减计数器被分配到相同的地址,并且可以通过 AGT 计数器寄存器(AGT Counter Register)访问。 当我们向该地址写入值的时候,写入的值会被写入重载寄存器,读取的值会从计数器中读取。

2. 16位重装载寄存器

见图中标注 ② 处。

16 位的重装载寄存器对应的是 16 位的计数器。

一般当计数器产生下溢时,重装载寄存器会对计数器进行重装载。

3. 计数时钟源

见图中标注 ③ 处。

主要有四类时钟输入源:

PCLKB:PCLKB, PCLKB/2, PCLKB/8

LOCO, SUBCLK:AGTLCLK/d, AGTSCLK/d (d = 1, 2, 4, 8, 16, 32, 64, 128)

仅 AGTn (n = 1, 3, 5) 也可以连接到 AGTn (n = 0, 2, 4) 的下溢信号进行计数

外部事件输入(通过 AGTIO 引脚)

4. 比较匹配功能

见图中标注 ④ 处。

比较匹配功能可以用来输出 PWM。

5. 比较匹配输出引脚

见图中标注 ⑤ 处。

比较匹配的结果输出到 AGTOAn、AGTOBn 引脚。

6. 输出引脚

见图中标注 ⑥ 处。

这部分连接到 AGTOn 输出引脚。

7. 下溢事件信号/测量完成事件信号输出

见图中标注 ⑦ 处。

下溢事件信号/测量完成事件信号属于内部信号,通过这两个信号均可触发中断。

三、AGT工作模式详解

定时器模式
在定时器模式下,计数值在计数源的每个上升沿递减1。 当计数值到达 0x0000 并输入下一个计数源时,发生计数器下溢事件并产生中断请求。

脉冲输出模式
可以从 AGTIOn 和 AGTOn 引脚输出脉冲。每次发生下溢时,输出电平都会反转。

事件计数器模式
在事件计数器模式下,计数器由输入到 AGTIOn 引脚的外部事件信号(计数源)驱动(递减计数)。

脉冲宽度测量模式
在脉冲宽度测量模式下,测量输入到 AGTIOn 引脚的外部信号的脉冲宽度。

脉冲周期测量模式
在脉冲周期测量模式下,测量输入到 AGTIOn 引脚的外部信号的脉冲周期。 仅测量周期长于计数源周期两倍的输入脉冲。此外,低电平和高电平宽度都必须长于计数源的周期。 如果输入比这些条件短的脉冲周期,输入可能会被忽略。

比较匹配功能:PWM模式
比较匹配功能可用于 PWM 输出。

四、实验:比较匹配功能——PWM输出

1. 硬件设计

PWM 输出引脚使用的开发板引出的 IO 引脚: P500,如下图所示。
【瑞萨RA_FSP】AGT——低功耗定时器_第5张图片

2. 文件结构

_AGT_PWM_Output
├─ ......
└─ src
   ├─ led
   │  ├─ bsp_led.c
   │  └─ bsp_led.h
   ├─ debug_uart
   │  ├─ bsp_debug_uart.c
   │  └─ bsp_debug_uart.h
   ├─ agt
   │  ├─ bsp_agt_pwm_output.c
   │  └─ bsp_agt_pwm_output.h
   └─ hal_entry.c

3. FSP配置

因为 PWM 输出需要使用 IO 口进行输出,因此需要先在“Pins”配置页中为 AGT 配置引脚, 将 AGT 的 AGTOA0 信号输出连接到 P500 引脚,如下图所示。
【瑞萨RA_FSP】AGT——低功耗定时器_第6张图片
随后在“Stacks”配置页中加入 AGT 模块,并对其作如下图所示的配置。
【瑞萨RA_FSP】AGT——低功耗定时器_第7张图片
AGT 的“Output”部分属性描述如下表所示。
【瑞萨RA_FSP】AGT——低功耗定时器_第8张图片

4. AGT初始化函数

/* AGT初始化函数 */
void AGT_PWM_Init(void)
{
    /* 初始化 AGT 模块 */
    R_AGT_Open(&g_timer_agt0_ctrl, &g_timer_agt0_cfg);

    /* 启动 AGT 定时器 */
    R_AGT_Start(&g_timer_agt0_ctrl);

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

需要注意的是,在 AGT 初始化函数里面,我们重新设置了占空比:50% → 80%。 设置PWM占空比使用了我们自己写的 AGT_PWM_SetDuty 函数。

5. 设置PWM占空比函数

/** 自定义函数:设置PWM占空比
    @param duty 占空比范围:0~100 %
*/
void AGT_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

    /* 获得AGT的信息 */
    R_AGT_InfoGet(&g_timer_agt0_ctrl, &info);

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

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

    /* 最后调用FSP库函数设置占空比 */
    R_AGT_DutyCycleSet(&g_timer_agt0_ctrl, duty_cycle_counts, AGT_OUTPUT_PIN_AGTOA);
}

该函数的主要思路是需要先知道计数器的计数周期(即当前输出的PWM信号的一个周期需要计数的值 current_period_counts), 然后计算与要设定的占空比(duty)对应的计数值(duty_cycle_counts), 最后调用FSP库函数 R_AGT_DutyCycleSet 写入该占空比对应的计数值。

调用 R_AGT_DutyCycleSet 函数时需要注意传入的第三个参数是 AGT_OUTPUT_PIN_AGTOA, 因为使用的PWM输出引脚 P500 连接到的是 AGT0 的 AGTOA 信号。 如果换用别的引脚,需要注意检查这个参数是否需要修改。

6. 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 调试串口初始化
    AGT_PWM_Init();     // AGT 初始化

    printf("这是一个 AGT 的PWM输出功能实验\r\n");
    printf("使用示波器测量 P500 输出的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
}

你可能感兴趣的:(瑞萨RA6M5,linux,运维,服务器,瑞萨RA,RASC)