Madf писал(а):Глянул ссылку и чот не понял, как у них на 16МГц получается "16-bit output PWM with full clock rate resolution (~18kHz PWM with a POWER_RANGE of 800 steps)"?
Там жесткий хак, все софтово и на асме. На асме можно и не такое
Смотреть тут:
- Код: Выделить всё • Развернуть
pwm_on_fast:
sbrc flags2, A_FET
PWM_A_on
sbrc flags2, B_FET
PWM_B_on
sbrc flags2, C_FET
PWM_C_on
ldi ZL, pwm_off
mov tcnt2h, duty_h
out TCNT2, duty_l
reti
pwm_wdr: ; Just reset watchdog
wdr
reti
pwm_off:
cpse tcnt2h, ZH ; 2 cycles to skip when tcnt2h is 0
rjmp pwm_again
wdr ; 1 cycle: watchdog reset
sbrc flags1, FULL_POWER ; 2 cycles to skip if not full power
rjmp pwm_on ; None of this off stuff if full power
lds ZL, pwm_on_ptr ; 2 cycles
mov tcnt2h, off_duty_h ; 1 cycle
sbrc flags2, A_FET ; 2 cycles if skip, 1 cycle otherwise
PWM_A_off ; 2 cycles (off at 12 cycles from entry)
sbrc flags2, B_FET ; Offset by 2 cycles here,
PWM_B_off ; but still equal on-time
sbrc flags2, C_FET
PWM_C_off
out TCNT2, off_duty_l ; 1 cycle
.if CPWM_SOFT
sbrc flags2, SKIP_CPWM ; 2 cycles if skip, 1 cycle otherwise
reti
.if DEAD_TIME_LOW > 9
.equ EXTRA_DEAD_TIME_LOW = DEAD_TIME_LOW - 9
.else
.equ EXTRA_DEAD_TIME_LOW = 0
.endif
cycle_delay EXTRA_DEAD_TIME_LOW - 2
.equ CPWM_OVERHEAD_LOW = 9 + EXTRA_DEAD_TIME_LOW
sbrc flags2, A_FET
PWM_COMP_A_on
sbrc flags2, B_FET
PWM_COMP_B_on
sbrc flags2, C_FET
PWM_COMP_C_on
.endif
reti ; 4 cycles