跳到主要内容

17 AGT 周期测量实验

在这里插入图片描述

开发板官网https://www.edevkit.com/)

本系列教程目录:


AGT 脉冲周期测量实验

本章目标:

  • 了解 RA6M5 处理器的 AGT 外设;
  • 学会使用 RASC 配置 AGT 脉冲周期测量功能;

硬件设计

(略,参见配套硬件原理图)

软件设计

新建工程

复制一份“15 AGT_PWM_Output”修改文件夹名“17 AGT_Pulse_Period”,双击打开 EBF_RA6M5.uvprojx 工程,通过 Keil 的新建文件新建 agt_pulse_period.cagt_pulse_period.h,保存到目录下的 src 文件夹下。

FSP 配置

Keil 界面选择“Tools”→“RA Smart Configurator”打开 RASC 界面。

周期测量需要配置输入引脚 P600,需要先在“Pins”配置页中为 AGT3 配置引脚,将 AGT3 的 AGTIO3 信号输出设置为 P600 引脚。

插图01

添加 AGT Stack 模块。

插图02

属性配置:

插图03

“Input”属性:

“Measurement Mode”:测量模式。

选择 AGT 是否用于测量脉冲宽度或脉冲周期。默认禁止测量,可选择测量低电平脉冲宽度、高电平脉冲宽度和脉冲周期。

“Input Filter”:输入滤波器。

该滤波器要求从 AGTIO 引脚输入信号在指定的滤波器频率下连续 3 次读取时处于同一电平。

“Enable Pin”:使能引脚。

选择 AGTEE 引脚的有效边缘。仅当 P402、P403 或者 AGTIO 作为时钟源的时候可用。

“Trigger Edge”:选择触发边缘。

不要同时选择触发边缘与脉冲周期。

配置完成之后可以按下快捷键“Ctrl + S”保存,最后点击“Generate Project Content”按钮,让软件自动生成配置代码即可。

程序设计

实现 AGT 的输入脉冲周期测量功能,开启 AGT3 通道的周期测量,设置 AGT0 输出的 PWM 占空比,连接 P500 和 P600,测量输入的 PWM 的脉冲周期,并打印到串口。

  1. 打开 AGT 设备
R_AGT_Open(timer_ctrl_t * const p_ctrl, timer_cfg_t const * const p_cfg);

p_ctrltimer_ctrl_t 结构体指针参数,本质是一个 void 类型的参数,指向 st_gpt_instance_ctrl 类型变量;

p_cfgtimer_cfg_t 结构体指针参数,在程序中会指向在 hal_data.c 中定义的 g_timer_cfg 静态全局变量;

  1. 开启/停止 AGT 计数
R_AGT_Start(timer_ctrl_t * const p_ctrl);
R_AGT_Stop(timer_ctrl_t * const p_ctrl);

必须要在 AGT 打开状态下使用这两个函数。

  1. 脉宽测量完成中断
void agt3_pulse_period_measurement_callback(timer_callback_args_t * p_args)
{
//测量完成事件
if (TIMER_EVENT_CAPTURE_A == p_args->event)
{

}
//定时器计数溢出事件
else if (TIMER_EVENT_CYCLE_END == p_args->event)
{

}
}

程序编写

agt_pulse_period.h 头文件里定义初始化函数、打印数据函数。

#ifndef __BSP_AGT_PULSE_PERIOD_H
#define __BSP_AGT_PULSE_PERIOD_H
#include "hal_data.h"

void agt_Pulse_Period_Init(void);

void scan_over_printf(void);

#endif

agt_pulse_period.c 里实现初始化函数、中断函数。

#include "agt_pulse_period.h"

timer_info_t agtInfo;
uint32_t periodCnts; //计数周期值

//初始化函数
void agt_Pulse_Period_Init(void)
{
//打开 AGT 模块
R_AGT_Open(&g_timer_agt3_ctrl, &g_timer_agt3_cfg);

// 获取计数周期
R_AGT_InfoGet(&g_timer_agt3_ctrl, &agtInfo);
periodCnts = agtInfo.period_counts;

//使能 AGT 定时器
R_AGT_Start(&g_timer_agt3_ctrl);
}

uint32_t pulse_height_time; //高电平宽度时间
uint8_t over_flag; //测量完成标志
uint32_t overflow_times = 0; //计数器溢出次数

//脉冲宽度测量中断函数
void agt3_pulse_period_callback(timer_callback_args_t * p_args)
{

//测量完成标志
if (TIMER_EVENT_CAPTURE_A == p_args->event)
{
//记录时间 B
pulse_height_time = p_args->capture + overflow_times * periodCnts;
overflow_times = 0;

over_flag = 1; //测量完成
}
//定时器计数溢出
else if (TIMER_EVENT_CYCLE_END == p_args->event)
{
//输入捕获期间计数器溢出,则记录溢出次数+1
overflow_times++;
}
}

//打印测量数据
void scan_over_printf(void)
{
float time_us = 0;

if(over_flag)
{
//打印PWM周期的计数
printf("High=%d, ", pulse_height_time);

//计算PWM的周期
time_us = (float)pulse_height_time / ((float)agtInfo.clock_frequency / (float)1000000);

printf("High Time=%f us\r\n", time_us);

overflow_times = 0;
over_flag = 0;
}
}

hal_entry.c 文件中添加头文件 agt_pulse_period.h,在 hal_entry 入口函数初始化 AGT。

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

led_Init();
uart0_Init();
agt_PWM_Init();
agt_Pulse_Period_Init();

printf("start AGT Pulse Period test\r\n");

while(1)
{
LED1_TOGGLE();
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒

scan_over_printf();
}


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

下载验证

连接下载器,将程序编译并下载到开发板之后,按下复位按键来复位开发板,程序启动初始化完成后,观察实验结果。

设置 AGT0 的 PWM 输出频率为 20 kHz,观察到测量数据,周期时间为 50 μs。

插图04