SHOW:
|
|
- or go back to the newest paste.
| 1 | """ | |
| 2 | Inspiriert von | |
| 3 | BitBastelei #398 - Die "Magie" hinter PWM (analogWrite, Timer, Preload, etc) | |
| 4 | https://www.youtube.com/watch?v=nf8MB7FkRaI | |
| 5 | ||
| 6 | """ | |
| 7 | ||
| 8 | ||
| 9 | import math | |
| 10 | from collections import namedtuple | |
| 11 | ||
| 12 | ||
| 13 | class Frequency: | |
| 14 | def __init__(self, value): | |
| 15 | self.value = value | |
| 16 | ||
| 17 | def __float__(self): | |
| 18 | return float(self.value) | |
| 19 | ||
| 20 | def __index__(self): | |
| 21 | return int(self.value) | |
| 22 | ||
| 23 | def __str__(self): | |
| 24 | units = ("Hz", "kHz", "MHz")
| |
| 25 | value = self.value | |
| 26 | for unit in units: | |
| 27 | if value < 1000: | |
| 28 | break | |
| 29 | value /= 1000 | |
| 30 | return f"{value:.3f} {unit}"
| |
| 31 | ||
| 32 | def __repr__(self): | |
| 33 | return f"{self.__class__.__name__}({self.value})"
| |
| 34 | ||
| 35 | ||
| 36 | def pwm_calc(freq, bits=8, board_freq=16_000_000): | |
| 37 | result = namedtuple( | |
| 38 | "Configuration", | |
| 39 | "board_freq scaled_freq prescaler count_bits count_start target_freq", | |
| 40 | ) | |
| 41 | increments = 2 ** bits | |
| 42 | counter_max = increments - 1 | |
| 43 | ||
| 44 | for prescaler in (2 ** n for n in range(11)): | |
| 45 | if (current_freq := board_freq / prescaler / increments) < freq: | |
| 46 | break | |
| 47 | ||
| 48 | # math.ceil aufrunden, math.floor abrunden | |
| 49 | offset = round(counter_max * current_freq / freq) | |
| 50 | resulting_freq = current_freq / offset * counter_max | |
| 51 | return result( | |
| 52 | Frequency(board_freq), | |
| 53 | Frequency(current_freq), | |
| 54 | prescaler, | |
| 55 | bits, | |
| 56 | counter_max - offset, | |
| 57 | Frequency(resulting_freq), | |
| 58 | ) | |
| 59 | ||
| 60 | ||
| 61 | result = pwm_calc(420) | |
| 62 | print("Prescaler:", result.prescaler)
| |
| 63 | print("Frequency:", result.target_freq)
| |
| 64 | print("Counter-Start:", result.count_start)
| |
| 65 | ||
| 66 | # Prescaler: 256 | |
| 67 | # Frequency: 420.648 Hz | |
| 68 | # Counter-Start: 107 | |
| 69 |