硬件设计
本次实验需要使用到LED灯来展示定时的效果,LED灯具体的电路讲解请读者参考本教程:8.4. 实验:使用寄存器点亮LED灯。
注:本实验仅用到LED1~3当中的其中一盏。
野火启明6M5开发板例程使用的PWM输出引脚为额外引出的IO引脚:P600,如下图所示。

注:
- 野火启明6M5开发板例程使用的PWM输出引脚为额外引出的IO引脚:P600(GTIOC6B)。
- 野火启明4M2开发板例程使用的PWM输出引脚为额外引出的IO引脚:P405(GTIOC1A)。
- 野火启明2L1开发板例程使用的PWM输出引脚为额外引出的IO引脚:P115(GTIOC4A)。
软件设计
新建工程
由于本实验需要用到LED,也会用到串口打印提示信息,因此我们在前面串口通信章节的“实验1:UART收发回显”例程的基础上修改程序。
- 对于e²studio开发环境:拷贝一份我们之前的e2s工程“19_UART_Receive_Send”,然后将工程文件夹重命名为“27_GPT_PWM_Output”,最后再将它导入到我们的e2studio工作空间中。
- 对于Keil开发环境:拷贝一份我们之前的Keil工程“19_UART_Receive_Send”,然后将工程文件夹重命名为“27_GPT_PWM_Output”,并进入该文件夹里面双击Keil工程文件,打开该工程。
工程新建好之后,在工程根目录的“src”文件夹下面新建“gpt”文件夹,再进入“gpt”文件夹里面新建源文件和头文件:“bsp_gpt_pwm_output.c”和“bsp_gpt_pwm_output.h”。工程文件结构如下。
列表5:文件结构
27_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配置
下面以野火启明6M5开发板为例来讲解相关的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频率设为20KHz,因此“Period”设置为20,单位“Period Unit”设置为Kilohertz,即千赫兹(KHz)。
- GTIOCB Output Enabled:使能GTIOCB输出。
- GTIOCB Stop Level:设置定时器停止时GTIOCB输出的电平为低电平。
- GTIOC6B:选择连接到P600引脚,这个软件会自动设置的,我们只要确认了就好。
GPT的“Output”部分的属性描述如下表所示。
表6:GPT属性描述:“Output“部分

GPT初始化函数
列表6: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占空比函数
列表7:设置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入口函数
列表8: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
}
下载验证
以野火启明6M5开发板为例,编译并下载程序后,复位开发板使程序重新运行,然后使用示波器测量P600引脚输出的PWM波形。实现现象如下。
频率20KHz,占空比为50%的PWM波形:

频率20KHz,占空比为80%的PWM波形:

小技巧
人眼对于每11毫秒闪烁一次(约83赫兹)基本感觉不到闪烁,每13毫秒闪烁一次(约66赫兹)感觉到轻微频闪。那么我们平时见到的LED灯,当它的频率大于50Hz的时候,人眼就会产生视觉暂留效果,基本就看不到闪烁了,而是一个常亮的LED灯。因此,我们可以通过PWM让LED高频闪烁,并控制PWM占空比实现LED的亮度变化,通过这个原理可以实现呼吸灯的效果,感兴趣的读者可自行尝试去实现它。
通过本文的实战,我们详细讲解了如何在瑞萨RA6M5 微控制器上使用FSP库配置GPT定时器输出PWM信号。从硬件引脚连接到软件配置、C语言编程,再到最终的波形验证,整个过程清晰明了。希望这篇来自云栈社区的指南能帮助你快速掌握瑞萨RA系列PWM输出的核心开发技能。