GPT介绍
通用 PWM 定时器(GPT,General PWM Timer)是 RA MCU 的其中一种 32/16 位的定时器外设。 在 GPT 当中,可分为 GPT32 和 GPT16,它们最主要的区别是计数器的不同。 GPT32 是 32 位的定时器,包含的计数器是 32 位的,所能计数的范围为:0 ~ 0xFFFF_FFFF; 而 GPT16 是 16 位的定时器,包含的计数器是 16 位的,所能计数的范围为:0 ~ 0xFFFF。
定时器(Timer)最基本的功能就是定时,比如定时发送串口数据、定时采集AD数据、定时触发中断处理其它事务等等。 如果把定时器与 GPIO 引脚结合起来使用的话可以实现更加丰富的功能, 可以对输入信号进行计数,可以测量输入信号的脉冲宽度,可以输出单个脉冲、PWM 等波形,等等。 通过定时器生成 PWM 波形信号来控制电机状态是工业控制的普遍方法,这方面知识非常值得深入了解。
GPT 模块可用于计数事件、测量外部输入信号、作为通用计时器并产生周期性中断、以及输出周期性或 PWM 信号到 GTIOC 引脚。 GPT 也可用于输出单个脉冲,但是注意这是通过软件来实现的,GPT 硬件本身不支持输出单个脉冲(One-Shot)功能。 当使用单个脉冲(One-Shot)模式时,必须要开启中断,计时器需要在脉冲周期结束后在 ISR 中断服务函数中被停止。
PWM介绍
PWM 的全称是脉冲宽度调制(Pulse Width Modulation),简称脉宽调制,通俗的讲就是调节脉冲的宽度。 其原理是通过将有效的电信号分散成离散形式从而来降低电信号所传递的平均功率, 根据面积等效法则,可以通过对改变脉冲的时间宽度,来等效地获得所需要合成的相应幅值和频率的波形。 PWM 有着非常广泛的应用,比如直流电机控制、开关电源、逆变器等等。
配置GPT-PWM
将项目01_I2C_OLED复制一份,重命名为02_PWM
查看原理图得知,P102引脚可用GPT功能。
点击configuration.xml文件,按下面几张图所示内容配置。
打开引脚配置界面(Pin Configuration)。
在左侧 "Pin Selection" 区域,展开 "Timers" 选项,勾选 "GPT2"。
在右侧 "Pin Configuration" 区域,设置 "Operation Mode" 为 "GTIOCA or GTIOCB"。
找到 "GTIOC2B",将其值设置为 "P102"。

进入堆栈配置界面(Stacks Configuration)。
New Stack" 按钮,在弹出的菜单中依次选择 "Timers" -> "Timer, General PWM (r_gpt)",添加通用 PWM 定时器堆栈。

选中添加的 "Timer, General PWM (r_gpt)" 堆栈,进入其设置界面。
在 "Common" 部分,将 "Pin Output Support" 设置为 "Enabled"。
在 "Module" -> "General" 部分,设置 "Name" 为 "g_timer2","Channel" 为 "2","Mode" 为 "Saw - wave PWM","Period" 为 "1","Period Unit" 为 "Kilohertz"。
在 "Output" 部分,将 "GTIOCB Output Enabled" 设置为 "True"。

设置好后生成代码
软件部分
PWM调占空比
在src文件夹下新建pwm文件夹
里面新建pwm.c文件
#include "hal_data.h"
void GPT_PWM_SetDuty(uint8_t duty)
{
timer_info_t info;
R_GPT_InfoGet(&g_timer2_ctrl, &info);
uint32_t current_period_counts = info.period_counts;
uint32_t duty_cycle_counts = (uint32_t)(((uint64_t)current_period_counts * duty) / 100);
R_GPT_DutyCycleSet(&g_timer2_ctrl, duty_cycle_counts, GPT_IO_PIN_GTIOCB);
}
新建pwm.h文件
#ifndef PWM_H_
#define PWM_H_
void GPT_PWM_SetDuty(uint8_t duty);
#endif
hal_entry文件
头文件部分新增
#include "pwm/PWM.h"
hal_entry函数如下:
void hal_entry(void)
{
uint8_t duty = 0;
uint8_t direction = 0;
UART_Init();
R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
OLED_Init();
R_GPT_Open(&g_timer2_ctrl, &g_timer2_cfg);
R_GPT_Start(&g_timer2_ctrl);
printf("实验02 PWM实验\r\n");
OLED_ShowString(0, 0, "PWM test", 16);
while(1){
if(duty==100)
direction = 1;
if(duty == 0)
direction = 0;
if(direction)
duty-=10;
else
duty+=10;
GPT_PWM_SetDuty(duty);
sprintf(disp_buff, "duty: %03d %%", duty);
OLED_ShowString(0, 16, disp_buff, 16);
R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
实验结果
使用杜邦线,将P102和P103引脚相接,在屏幕上能看到占空比的变化,小灯的亮度也随之改变。实验结果如顶部视频所示。