瑞萨RA系列FSP库开发实战指南之使用GPT输入捕获进行脉宽和周期测量实验

描述

27.8

实验3:输入捕获——脉宽和周期测量

上一个实验使用了GPT的输出功能,本次实验要使用GPT的输入功能,通过GPT的输入捕获进行脉宽和周期测量。其测量的原理如下图所示。

瑞萨

首先启动GPT定时器,在上升沿A处进行捕获,记此时时间为A;紧接着在下降沿B处进行捕获,记此时时间为B;最后再次在上升沿C处进行捕获,记此时时间为C或者A’。设PWM的周期为T,占空比为D,频率为f,则:

瑞萨

27.8.1

硬件设计

以野火启明6M5开发板为例,本实验使用P600和P603这两个引脚,P600用于输出PWM信号,P603用于输入捕获。将P600与P603使用杜邦线连接,引脚在引出排针处,如下图所示。

瑞萨

野火启明6M5开发板例程选用的PWM输出引脚为:P600(GTIOC6B);选用的输入捕获引脚为:P603(GTIOC7A)。

野火启明4M2开发板例程选用的PWM输出引脚为:P405(GTIOC1A);选用的输入捕获引脚为:P414(GTIOC0B)。

野火启明2L1开发板例程选用的PWM输出引脚为:P115(GTIOC4A);选用的输入捕获引脚为:P113(GTIOC2A)。

本次实验需要将PWM输出引脚与输入捕获引脚使用杜邦线连接起来。

27.8.2

软件设计

27.8.2.1

新建工程

由于本实验的目标是测量PWM的周期、占空比,因此我们在上一个实验的基础上修改程序。

对于e2studio开发环境:拷贝一份我们之前的e2s工程“27_GPT_PWM_Output”,然后将工程文件夹重命名为“27_GPT_Input_Capture”,最后再将它导入到我们的e2studio工作空间中。

对于Keil开发环境:拷贝一份我们之前的Keil工程“27_GPT_PWM_Output”,然后将工程文件夹重命名为“27_GPT_Input_Capture”,并进入该文件夹里面双击Keil工程文件,打开该工程。

工程新建好之后,在工程根目录的“src/gpt”路径下面,新建源文件和头文件:

bsp_gpt_input_capture.c

bsp_gpt_input_capture.h

工程文件结构如下:

列表9:文件结构

左右滑动查看完整内容

 

27_GPT_Input_Capture
├─ ......
└─ 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
  │ ├─ bsp_gpt_input_capture.c //新增文件
  │ └─ bsp_gpt_input_capture.h //新增文件
  └─ hal_entry.c

 

27.8.2.2

FSP配置

下面以野火启明6M5开发板为例来讲解相关的FSP配置。

由于在上一个实验中我们已经配置好了P600用于输出PWM信号,因此本实验中只需要添加输入捕获需要使用到IO引脚P603,需要在“Pins”配置页面中配置GPT7所使用的引脚。

瑞萨

在“Stacks”配置页面中加入GPT,按如下图所示的配置进行设置。需要注意的是,因为“Input”里面的各类配置项目若是展开来的话篇幅比较长,因此在图中并未展开出来,我们要注意勾上以下几个选项:

展开Input->Capture ASource并勾上(在GTIOCA的上升沿启用输入捕获A,无论GTIOCB引脚是:

–GTIOCA Rising Edge While GTIOCB Low

–GTIOCA Rising Edge While GTIOCB High

展开Input->Capture BSource并勾上(在GTIOCA的下降沿启用输入捕获B,无论GTIOCB引脚是:

–GTIOCA Falling Edge While GTIOCB Low

–GTIOCA Falling Edge While GTIOCB High

瑞萨

点击可查看大图

GPT的“Input”选项卡的属性描述:
 

表7:GPT属性描述:“Input”

瑞萨

点击可查看大图

27.8.2.3

GPT初始化

初始化GPT模块用于输入捕获的函数如下。在这个函数中,我们先初始化GPT模块,然后调用R_GPT_Info Get函数获取GPT的配置信息,主要是为了获取计数器的计数周期,即GPT一个周期的计数次数,并保存到全局变量period中。

最后使能输入捕获,并启动GPT定时器。

列表10:GPT初始化

左右滑动查看完整内容

 

timer_info_t info; //用于获取定时器参数信息
uint32_t period; //输入捕获计数器的计数周期
/* GPT 初始化函数*/
voidGPT_InputCapture_Init(void)
{
    /* 初始化GPT 模块*/
    R_GPT_Open(&g_timer_gpt7_ctrl, &g_timer_gpt7_cfg);
    /* 获取当前参数*/
    (void) R_GPT_InfoGet(&g_timer_gpt7_ctrl, &info);
    /* 获取计数周期:GPT 的一个周期的计数次数*/
    period = info.period_counts;
    /* 使能输入捕获*/
    R_GPT_Enable(&g_timer_gpt7_ctrl);
    /* 启动GPT 定时器*/
    R_GPT_Start(&g_timer_gpt7_ctrl);
}

 

27.8.2.4

GPT中断回调函数

GPT输入捕获中断回调函数如下。

列表11:GPT中断回调函数

滑动查看完整内容

 

/* 保存所测量的PWM 信号的信息*/
uint32_t pwm_period; //PWM 周期
uint32_t pwm_high_level_time; //PWM 高电平的时间
uint32_t pwm_freq; //PWM 频率
uint32_t pwm_duty; //PWM 占空比
/* GPT 输入捕获中断回调函数*/
voidgpt7_input_capture_callback(timer_callback_args_t * p_args)
{
    staticuint32_t a_time; // A 上升沿捕获的时间
    staticuint32_t b_time; // B 下降沿捕获的时间
    staticuint32_t c_time; // C 上升沿捕获的时间(其实也就是A 可以用A'表示)
    staticuint32_t overflow_times; //计数器溢出次数
    staticuint8_t one_period_flag=0; //用于表示是否完成对一个完整周期的测量
    
    
    switch(p_args->event)
    {
        /* 捕获到上升沿-- 有可能是A 或者C (A') 位置*/
        case TIMER_EVENT_CAPTURE_A:
            /* A 开始对某个周期进行测量*/
            if (0 == one_period_flag)
            {
                a_time = p_args->capture; //记录捕获的时间A
                overflow_times = 0; //初始化计数器溢出次数
                one_period_flag ++; //表示即将完成对某个周期的测量
            }
            /* C (A') 如果测量完了一个周期,则计算PWM 信号周期和高电平的时间*/
            elseif (1 == one_period_flag)
            {
                c_time = p_args->capture + overflow_times * period; //记录捕
                获的时间C
                //计算PWM 周期
                pwm_period = c_time - a_time;
                //清零所有标志位
                overflow_times = 0;
                one_period_flag = 0; //标志位清0, 重新进入下一轮的测量
            }
            break;
            
        /* 捕获到下降沿-- 是B 位置*/
        case TIMER_EVENT_CAPTURE_B:
            //如果是在测量周期内检测到下降沿
            if (1 == one_period_flag)
            {
            b_time = p_args->capture + overflow_times * period; //记录捕
            获的时间B
            pwm_high_level_time = b_time - a_time; //计算高电平时间
            }
            break;
            
        /* 定时器计数溢出事件*/
        case TIMER_EVENT_CYCLE_END:案件 TIMER_EVENT_CYCLE_END:
            /* 输入捕获期间计数器溢出,则记录溢出次数+1 */
            overflow_times++;
            break;
            
        default:
            break;
    }
}

 

在GPT中断回调函数中,我们使用switch语句判断触发中断的事件类型。GPT在引脚输入PWM信号的上升沿触发捕获A事件,在PWM信号的下降沿触发捕获B事件,并在计数器溢出时触发定时器计数溢出事件。

警告

建议不要在中断回调函数中打印数据,因为PWM频率一般很高,而printf函数执行所消耗的时间比较长,可能会阻塞中断服务函数的运行。同时也应该时刻注意中断优先级的问题。

27.8.2.5

hal_entry入口函数

列表12:hal_entry入口函数

滑动查看完整内容

 

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




// 外部变量声明
externtimer_info_t info; //用于获取定时器参数信息
externuint32_t pwm_period; //PWM 周期
externuint32_t pwm_high_level_time; //PWM 高电平的时间
externuint32_t pwm_freq; //PWM 频率
externuint32_t pwm_duty; //PWM 占空比




voidhal_entry(void)
{
    /* TODO: add your own code here */
    LED_Init(); // LED 初始化
    Debug_UART4_Init(); // SCI4 UART 调试串口初始化
    
    GPT_PWM_Init(); // GPT PWM 输出初始化
    GPT_InputCapture_Init(); // GPT 输入捕获初始化
    
    printf("这是一个GPT 的PWM 输出+ 输入捕获功能实验
");
    printf("使用杜邦线连接P600 和P603 引脚,然后打开串口助手查看串口的打印信息

    ,→");
    
    
    while(1)
    {
        /* 计算PWM 的频率*/
        pwm_freq = info.clock_frequency / pwm_period;
        /* 计算PWM 的占空比*/
        pwm_duty = pwm_high_level_time * 100 / pwm_period;
        // 打印
        printf("High=%d, Period=%d, ", pwm_high_level_time, pwm_period);
        printf("Friquency = %dHz, Duty_Cycle = %d%%
", pwm_freq, pwm_
        ,→duty);
        pwm_period = pwm_high_level_time = pwm_freq = 0; //打印完后旧数据清零
        // LED1 闪烁指示程序正在运行...
        LED1_TOGGLE;
        // 间隔1s
        R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
    }
    
#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

 

27.8.3

下载验证

以野火启明6M5开发板为例,编译并下载程序后,复位开发板使程序重新运行,然后使用杜邦线连接P600和P603引脚,然后打开串口助手查看串口的打印信息。串口会打印出PWM信号的频率和占空比等信息,实验现象如下图所示。

瑞萨

点击可查看大图

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分