相关的配置过程参考这个内容:
https://bbs.elecfans.com/jishu_2505389_1_1.html
我在这个基础之上做了一点修改,就是通过示波器观察一下pwm波形的变化。
根据配置文件:
timer1的pwm输出引脚定义为P109

)
在视频中可以自行找到的。
完整代码如下:
```
#include "hal_data.h"
/***********************************************************************************************************************
* Private function prototypes
**********************************************************************************************************************/
void servo_set_angle(float angle); // 函数原型声明
/***********************************************************************************************************************
* Private global variables
**********************************************************************************************************************/
// 定义舵机控制参数
#define SERVO_MIN_PULSE_WIDTH_US (500) // 舵机0°对应的脉宽 (单位: 微秒)
#define SERVO_MAX_PULSE_WIDTH_US (2500) // 舵机180°对应的脉宽 (单位: 微秒)
#define SERVO_MAX_ANGLE (180.0f) // 舵机的最大角度
/*******************************************************************************************************************//**
*
@Brief 设置舵机转动到指定角度
* @param[in] angle 目标角度 (0.0 - 180.0)
**********************************************************************************************************************/
void servo_set_angle(float angle)
{
fsp_err_t err;
timer_info_t info;
uint32_t period_counts;
uint32_t duty_counts;
uint32_t pulse_width_us;
/* 1. 角度范围限制 */
if (angle < 0.0f)
{
angle = 0.0f;
}
else if (angle > SERVO_MAX_ANGLE)
{
angle = SERVO_MAX_ANGLE;
}
/* 2. 计算目标角度对应的脉冲宽度 (单位: 微秒) */
pulse_width_us = SERVO_MIN_PULSE_WIDTH_US + (uint32_t)(((SERVO_MAX_PULSE_WIDTH_US - SERVO_MIN_PULSE_WIDTH_US) * angle) / SERVO_MAX_ANGLE);
/* 3. 获取定时器信息,包括时钟频率和周期计数值 */
err = R_GPT_InfoGet(&g_timer1_ctrl, &info);
if (FSP_SUCCESS != err)
{
return; // 获取失败则退出
}
period_counts = info.period_counts;
/* 4. 将微秒单位的脉宽,转换为定时器的计数值 */
/* 公式: duty_counts = (pulse_width_us * timer_clock_freq_hz) / 1,000,000 */
/* 简化计算: duty_counts = (pulse_width_us * period_counts) / timer_period_us */
/* 舵机周期固定为20000微秒 (20ms) */
duty_counts = (uint32_t)(((uint64_t)pulse_width_us * period_counts) / 20000);
/* 5. 设置新的占空比(脉宽) */
err = R_GPT_DutyCycleSet(&g_timer1_ctrl, duty_counts, GPT_IO_PIN_GTIOCA);
if (FSP_SUCCESS != err)
{
// 错误处理
}
}
/*******************************************************************************************************************//**
* 主程序入口
**********************************************************************************************************************/
void hal_entry(void)
{
fsp_err_t err;
float angle = 0.0f; // 角度变量,从0度开始
int8_t step = 1; // 步进方向和大小
/* 1. 打开GPT定时器实例 */
/* 确保在FSP中已将g_timer1配置为50Hz (周期20ms) */
err = R_GPT_Open(&g_timer1_ctrl, &g_timer1_cfg);
if (FSP_SUCCESS != err)
{
while(1);
}
/* 2. 启动定时器,开始输出PWM波形 */
err = R_GPT_Start(&g_timer1_ctrl);
if (FSP_SUCCESS != err)
{
R_GPT_Close(&g_timer1_ctrl);
while(1);
}
/* 3. 主循环,实现舵机来回摆动效果 */
while(1)
{
/* 调用函数来设置舵机到当前角度 */
servo_set_angle(angle);
/* 更新下一次的角度值 */
angle += step;
/* 检查是否到达边界,如果到达则改变步进方向 */
if (angle >= 180.0f)
{
angle = 180.0f;
step = -1;
}
else if (angle <= 0.0f)
{
angle = 0.0f;
step = 1;
}
/* 延时,控制舵机摆动的速度 */
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/* --- TrustZone 相关代码保持不变 --- */
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif
```
实际效果看视频: