在这里插入图片描述

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

本系列教程目录:
- 瑞萨单片机开发教程[一] e2-studio + DAP LINK开发环境搭建
- 瑞萨单片机开发教程[二] Keil/RASC开发环境搭建
- 瑞萨单片机开发教程[三] 新建RASC工程
- 瑞萨单片机开发教程[四] GPIO输出——led实验
- 瑞萨单片机开发教程[五] GPIO输入——按键key实验
- 瑞萨单片机开发教程[六] ICU外部中断实验
- 瑞萨单片机开发教程[七] SCI UART串口通信实验
- 瑞萨单片机开发教程[八] DMAC 串口数据传输实验
- 瑞萨单片机开发教程[九] ADC 电压采集实验


GPT PWM 输出实验

本章目标:

  • 了解 RA6M5 处理器的 GPT 外设;
  • 学会使用 RASC 配置 GPT 实现 PWM 输出;

硬件设计

本实验使用开发板的 GPT 定时器外设,通过 PWM 输出通道输出方波信号,可使用示波器观察。

软件设计

新建工程

复制一份“07 SCI-UART_Recv_send”修改文件夹名“12 GPT_PWM_Timer”,双击打开 EBF_RA6M5.uvprojx 工程,通过 Keil 的新建文件新建 gpt_timer.cgpt_timer.h,保存到目录下的 \src 文件夹下。

FSP 配置

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

PWM 输出需要使用 IO 引脚进行输出,需要先在“Pins”配置页中为 GPT 配置引脚,将 GPT6 的 GTIOC6B 信号输出连接到 P600 引脚。

添加 GPT Stack 模块。

需要更改的配置如下:

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”部分的属性描述:

属性 描述
Custom Waveform > GTIOA/GTIOB > Initial Output Level 设置 GPT 初始化时 GTIOCxA/GTIOCxB 的电平(低电平或高电平)。
Custom Waveform > GTIOA/GTIOB > Cycle End Output Level 完成一个计数周期时 GTIOCxA/GTIOCxB 的输出电平(保持不变、输出高、输出低或反转电平)。
Custom Waveform > GTIOA/GTIOB > Compare Match Output Level 发生比较匹配时 GTIOCxA/GTIOCxB 的输出电平(保持不变、输出高、输出低或反转电平)。
Custom Waveform > GTIOA/GTIOB > Retain Output Level at Count Stop 在计数停止时保持 GTIOCxA/GTIOCxB 电平。
Custom Waveform > Custom Waveform Enable 使能自定义波形的配置。
Duty Cycle Percent (only applicable in PWM mode) 设定 PWM 占空比(仅用于 PWM 模式)
GTIOCA Output Enabled 使能 GTIOCA 输出到相应引脚
GTIOCA Stop Level 当 GPT 定时器停止时 GTIOCA 的输出电平
GTIOCB Output Enabled 使能 GTIOCB 输出到相应引脚
GTIOCB Stop Level 当 GPT 定时器停止时 GTIOCB 的输出电平

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

  1. GPT 的引脚信息

使用 GPT 往 P600 引脚输出 PWM,使用 RASC 配置 GPT 的通道且指定引脚后,生成的工程中的 pin_data.c 中的 g_bsp_pin_cfg_data[] 数组就会添加该引脚的配置信息。

const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
    ......(省略内容)
    {.pin = BSP_IO_PORT_06_PIN_00,
    .pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN 
              | (uint32_t) IOPORT_PERIPHERAL_GPT1)
    },
};
  1. GPT配置信息

GPT 模块的配置信息在 hal_data.c 中以 timer_cfg_t 类型的结构体变量表示。

const timer_cfg_t g_timer_gpt6_cfg =
{
    .mode                = TIMER_MODE_PWM,
    /* Actual period: 0.00005 seconds. Actual duty: 50%. */
        .period_counts = (uint32_t) 0x1388, 
        .duty_cycle_counts = 0x9c4, 
        .source_div = (timer_source_div_t)0,
    .channel             = 6,
    .p_callback          = NULL,
    /** If NULL then do not add & */
#if defined(NULL)
    .p_context           = NULL,
#else
    .p_context           = &NULL,
#endif
    .p_extend            = &g_timer_gpt6_extend,
    .cycle_end_ipl       = (BSP_IRQ_DISABLED),
#if defined(VECTOR_NUMBER_GPT6_COUNTER_OVERFLOW)
    .cycle_end_irq       = VECTOR_NUMBER_GPT6_COUNTER_OVERFLOW,
#else
    .cycle_end_irq       = FSP_INVALID_VECTOR,
#endif
};

mode 表示 GPT 的类型,此处是 PWM;

第 05~06 行:表示输出 PWM 的周期和占空比;

channel 表示使用的 GPT 的通道;

使用 GPT 的 open 函数打开 GPT 设备时,就会使用这些配置信息初始化 GPT。

程序设计

实现 GPT 的 PWM 输出功能,开启 P600 通道的 PWM,设置输出的占空比,接入示波器查看波形占空比,改变占空比,观察波形变化。

  1. 打开 GPT 设备
R_GPT_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. 开启/停止 GPT 计数
R_GPT_Start(timer_ctrl_t * const p_ctrl);
R_GPT_Stop(timer_ctrl_t * const p_ctrl);

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

  1. 设置 GPT 输出 PWM 的占空比
R_GPT_DutyCycleSet(timer_ctrl_t * const p_ctrl, uint32_t const duty_cycle_counts, uint32_t const pin);

在 PWM 驱动应用中,使用此函数来修改占空比,最后一个参数是指 GPT 的输出通道,而不是指 IO 引脚。

程序编写

gpt_pwm.h 头文件里定义初始化函数,设置占空比函数。

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

void gpt_PWM_Init(void);

void gpt_PWM_SetDuty(uint8_t duty);

#endif

gpt_pwm.c 里实现初始化函数、设置占空比函数。

初始化函数里打开 GPT 设备并启动定时器。

设置占空比输入 0~100 数值,先获取 GPT 的周期计时数,换算占空比的计数值,再设置输出占空比值。

#include "gpt_pwm.h"

//PWM输出引脚 GTIOC6B P600 


// 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占空比 0~100
void gpt_PWM_SetDuty(uint8_t duty)
{
    timer_info_t info;
    uint32_t current_period_counts;
    uint32_t duty_cycle_counts;

        //限制占空比范围:0~100
    if (duty > 100)
        duty = 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.c 文件中添加头文件 gpt_pwm.h,在 hal_entry 入口函数初始化 GPT。

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

    led_Init(); // LED 初始化
    uart0_Init();
    gpt_PWM_Init();
    printf("start PWM test\r\n");

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


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

下载验证

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

通过示波器探头连接 P600 和 GND,观察示波器检测到方波,占空比 80%,频率 20K Hz。

修改占空比,设置为 50%,观察波形。

更多推荐