Klipper використовує програмний чи апаратний PWM?

Коротко: Klipper використовує програмний PWM за замовчуванням, але може використовувати апаратний PWM на підтримуваних MCU, якщо ви явно увімкнете його в конфігурації.

Програмний PWM за замовчуванням

Коли ви налаштовуєте вентилятор, нагрівач або загальний вихідний пін у Klipper без спеціальних прапорців, Klipper використовує програмний PWM. Важливо розуміти, що бітове маніпулювання не виконується на стороні хоста/Linux — хост лише планує переходи та надсилає їх до MCU. Фактичне перемикання GPIO відбувається всередині прошивки MCU.

У klippy/mcu.py клас MCU_pwm вирішує, який шлях обрати. Якщо hardware_pwm має значення False (за замовчуванням), він налаштовує пін як звичайний цифровий вихід і надсилає config_digital_out та set_digital_out_pwm_cycle до MCU (рядки 509-530). Для кожного оновлення робочого циклу він надсилає queue_digital_out зі значенням on_ticks, яке повідомляє MCU, скільки тактів годинника пін повинен залишатися високим у межах PWM-циклу.

На стороні MCU src/gpiocmds.c реалізує кінцевий автомат soft-PWM:

  • digital_load_event() зчитує наступне оновлення з черги, встановлює початковий стан піна та обчислює, чи потрібно перемикнути пін.
  • digital_toggle_event() перемикає пін і переплановує себе для тривалості увімкнення або вимкнення в межах циклу.

Отже, PWM-хвилі генеруються планувальником переривань таймера MCU, керованим списком майбутніх переходів хоста.

Апаратний PWM — опціональний

Апаратний PWM вмикається для кожного піна за допомогою hardware_pwm: True у конфігурації. Коли це встановлено, хост надсилає команди config_pwm_out та queue_pwm_out замість попередніх, а MCU використовує PWM-периферію платформи.

Диспетчер на стороні MCU знаходиться у src/pwmcmds.c. Специфічні для платформи реалізації існують для кількох MCU:

Наприклад, реалізація STM32 у gpio_pwm_setup() знаходить таймер/канал для запитаного піна, обчислює прескалер та період лічильника, що найкраще відповідають запитаному часу циклу, а потім записує значення робочого циклу в регістр захоплення/порівняння таймера.

Документація Klipper прямо попереджає, що “більшість вентиляторів не працюють добре з апаратним PWM, тому не рекомендується вмикати це, якщо немає електричної потреби перемикати на дуже високих швидкостях” (Config_Reference.md).

Що визначає частоту PWM?

Частота — це просто 1 / cycle_time, що задається в конфігурації:

  • [fan]: cycle_time: 0.010 → 100 Гц (за замовчуванням).
  • [output_pin]: cycle_time: 0.100 → 10 Гц (за замовчуванням).
  • [extruder] / [heater_bed]: pwm_cycle_time: 0.100 → 10 Гц (за замовчуванням).

Для програмного PWM це фактична частота, на якій перемикається MCU. Для апаратного PWM це запитана частота, але апаратний таймер MCU може округлити її до найближчого досяжного значення через обмеження прескалера/лічильника. Крім того, кілька апаратних PWM-пінів, що поділяють один таймер, повинні працювати на однаковій частоті; інакше Klipper видає помилку “PWM already programmed at different speed”.

Приклад конфігурації

Вентилятор з програмним PWM (за замовчуванням)

example.ini
[fan]
pin: PA8
cycle_time: 0.010
hardware_pwm: False

Вихідний пін з апаратним PWM

example.ini
[output_pin my_pwm]
pin: PB0
pwm: True
cycle_time: 0.001
hardware_pwm: True

Період PWM нагрівача

example.ini
[extruder]
heater_pin: PA2
pwm_cycle_time: 0.100

Дивіться схожі статті за категоріями: Klipper 3D-друк