Как задать частоту PWM в Klipper?
TL;DR: В Klipper частота PWM задаётся косвенно через параметр cycle time (время цикла). Частота равна 1 / cycle_time. Точный параметр конфигурации зависит от того, чем вы управляете.
Какой параметр конфигурации использовать
В Klipper нет единого параметра pwm_frequency. Вместо этого вы настраиваете период одного цикла PWM, и Klipper вычисляет из него частоту.
Вентиляторы и выходные пины: cycle_time
Для вентиляторов, обычных выходных пинов, каналов светодиодов и подобных устройств используйте cycle_time:
[fan]
pin: PA8
cycle_time: 0.010
hardware_pwm: False- По умолчанию для
[fan]:0.010с → 100 Гц. - По умолчанию для
[output_pin]:0.100с → 10 Гц. - По умолчанию для каналов светодиодов
[neopixel]/[dotstar]:0.010с → 100 Гц.
Параметр описан в docs/Config_Reference.md для [fan] (строки 3239-3242) и [output_pin] (строки 3678-3681).
Нагреватели: pwm_cycle_time
Для нагревателей (экструдер, нагревательный стол и т.д.) параметр называется pwm_cycle_time:
[extruder]
heater_pin: PA2
pwm_cycle_time: 0.100- По умолчанию:
0.100с → 10 Гц. - В документации отмечается, что “не рекомендуется изменять это значение, если нет электрической необходимости переключать нагреватель чаще 10 раз в секунду” (Config_Reference.md).
Изменяемое во время выполнения время цикла: [pwm_cycle_time]
Если вам нужно изменять время цикла PWM во время выполнения через G-code, используйте секцию [pwm_cycle_time]:
[pwm_cycle_time my_pin]
pin: PB0Затем во время выполнения:
SET_PIN PIN=my_pin VALUE=0.5 CYCLE_TIME=0.001Это описано в docs/Config_Reference.md и реализовано в klippy/extras/pwm_cycle_time.py.
Как значение используется внутри
В klippy/mcu.py класс MCU_pwm преобразует время цикла в такты часов MCU:
cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time)Для программного PWM это становится аргументом cycle_ticks функции set_digital_out_pwm_cycle (строка 488), а время включения в каждом цикле планируется в тех же единицах тактов. Для аппаратного PWM то же значение cycle_ticks передаётся в платформо-зависимую функцию gpio_pwm_setup(), которая затем выбирает делитель таймера и период, наилучшим образом соответствующие этому значению.
Предостережение по аппаратному PWM: фактическая частота может отличаться
Когда установлено hardware_pwm: True, запрашиваемая частота является лишь целевым значением. Периферия таймера MCU должна выбрать делитель и период счётчика, которые укладываются в её аппаратные ограничения, поэтому реальная частота может немного отличаться.
Например, реализация для STM32 в src/stm32/hard_pwm.c вычисляет ближайшие достижимые значения hwpwm_ticks и prescaler (строки 328-348). Итоговая частота на STM32 приблизительно равна:
frequency = CLOCK_FREQ / (prescaler * hwpwm_ticks * pclock_div)Если два аппаратных PWM-пина используют один и тот же таймер, они также должны использовать одинаковую частоту; иначе Klipper завершит работу с ошибкой “PWM already programmed at different speed” (строка 356).
Практические примеры
Вентилятор 25 кГц для 4-проводного PWM-управления
[fan]
pin: PA8
cycle_time: 0.00004
hardware_pwm: True1 / 0.00004 = 25 000 Гц. Поскольку это выходит за пределы надёжного диапазона программного PWM, требуется hardware_pwm: True.
Стандартный вентилятор охлаждения детали 100 Гц
[fan]
pin: PA8
cycle_time: 0.010Это значение по умолчанию, хорошо работает с программным PWM.
Нагреватель 10 Гц
[extruder]
heater_pin: PA2
pwm_cycle_time: 0.100Снова значение по умолчанию; нет необходимости изменять его, если ваш MOSFET/драйвер не требует более быстрого переключения.
Резюме
- Частота PWM в Klipper всегда равна
1 / cycle_time. - Используйте
cycle_timeдля вентиляторов, выходных пинов и светодиодов. - Используйте
pwm_cycle_timeдля нагревателей. - Программный PWM точно соблюдает время цикла.
- Аппаратный PWM может округлять время цикла из-за ограничений таймера MCU.