PWM输出频率范围不够怎么办

板子支持的PWM频率范围是48khz-192mhz,但是舵机云台需要50hz的频率才能转,不在支持范围内啊。该用什么方法解决呢?
#!/usr/bin/env python3
import sys
import signal
import Hobot.GPIO as GPIO
import time

舵机参数配置

SERVO_MIN_DUTY = 2.5 # 0度位置占空比 (2.5%)
SERVO_MAX_DUTY = 12.5 # 270度位置占空比 (12.5%)
SERVO_FREQ = 50 # 舵机PWM频率 (50Hz = 20ms周期)

支持PWM的管脚: 32 or 33

output_pin = 33

def signal_handler(signal, frame):
sys.exit(0)

def angle_to_duty(angle):
“”“将角度(0-270)转换为占空比(2.5%-12.5%)”“”
angle = max(0, min(270, angle)) # 限制角度范围
return SERVO_MIN_DUTY + (SERVO_MAX_DUTY - SERVO_MIN_DUTY) * (angle / 270.0)

def main():
# 初始化GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)

# 创建PWM实例
pwm = GPIO.PWM(output_pin, SERVO_FREQ)

# 初始位置设为135度(中间位置)
init_angle = 135
pwm.start(angle_to_duty(init_angle))

print(f"舵机云台控制中 (0-270度), 当前: {init_angle}度. 按CTRL+C退出")

try:
    while True:
        # 示例动作: 0° -> 135° -> 270° -> 135° 循环
        for target_angle in [0, 135, 270, 135]:
            duty_cycle = angle_to_duty(target_angle)
            pwm.ChangeDutyCycle(duty_cycle)
            print(f"转到: {target_angle}度, 占空比: {duty_cycle:.1f}%")
            time.sleep(1)  # 等待舵机转动
            
except KeyboardInterrupt:
    pass
finally:
    pwm.stop()
    GPIO.cleanup()

if name == ‘main’:
signal.signal(signal.SIGINT, signal_handler)
main()

硬件不支持低频。可以尝试使用软件模拟低频

软件模拟低频的话,对GPIO引脚有什么特殊要求吗

引脚必须能被设置为输出模式
最好使用通用性引脚

好滴好滴,谢谢大佬 。我马上试一试

请问S600的MCU这边的PWM支持的频率范围也是这个吗?不支持低频?

0.047 Hz ~ 200 MHz

收到谢谢,刚才通过示波器测量反推PWM的模块频率是300MHz,通过这个频率去分频的,想问下这种时钟树配置在哪个文档里面有提到呢,谢谢

针对你提到的 S600 MCU PWM 时钟树配置问题,目前官方文档中没有直接公开时钟树详细配置章节,但可以通过以下途径获取相关信息:

结论

S600 MCU PWM 时钟源确实为 300MHz,通过分频实现 0.047Hz~200MHz 的输出范围。时钟树配置信息分散在以下文档中:

排查路径

1. 核心文档位置

2. 时钟配置相关信息来源

方式一:查看 SDK 代码

# 在 S600 SDK 中查找时钟配置文件
find . -name "*clock*" -type f
find . -name "*pll*" -type f

# 关键文件路径(参考 S100 结构)
Config/McalCdd/gen_xxx/Pwm/src/Pwm_PBCfg.c  # PWM 预编译配置
McalCdd/Pwm/src/Pwm_Lld.c                   # 底层驱动,含时钟分频设置

方式二:通过寄存器反推
使用 pwmdumpregs 命令查看实际寄存器值:

# 查看 PWM 通道寄存器
pwmdumpregs <pwm_hwipid> <pwm_hwchid>

# 重点关注 CLK_DIV_RATIO 寄存器
# 时钟树配置 = 300MHz / (分频比 + 1)

方式三:联系官方获取

  • 在论坛发帖询问(如本贴)
  • 通过地平线技术支持获取《S600 MCU 参考手册》
  • 查看 SDK 示例代码中的初始化配置

3. 已知信息整理

根据文档和实测:

  • PWM IP 时钟源:300MHz
  • 分频机制:通过 CLK_DIV_RATIO 寄存器配置
  • 周期计算周期寄存器值 = 300,000,000 / 目标频率
  • 最大计数值:4294967295 (32 位)

4. 建议操作

如果你需要精确配置时钟树:

  1. 查看 SDK 示例

    # 在 SDK 中搜索 clock 初始化代码
    grep -r "ClockRatio" samples/Pwm/
    
  2. 实验验证

    # 设置不同分频比,用示波器测量实际频率
    pwmtest 0x0 0x4 <period> <duty_cycle>
    
  3. 在社区沉淀
    建议你将反推的时钟树配置整理成文档分享到社区,帮助其他开发者。


需要我帮你查找 SDK 中具体的时钟初始化代码示例吗? 或者你有具体的频率配置需求,我可以帮你计算对应的寄存器值。