Advertisement
DeaD_EyE

fast pwm calculation

Jul 11th, 2021
976
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.71 KB | None | 0 0
  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.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement