''' This script analyzes a list of given quartz crystal frequencies for the possibility to create an 8-bit PWM signal with a given frequency f0 within a a given tolerance on a typical microcontroller timer with given prescalers and a clear-on-timer-compare CTC functionality Uwe Zimmermann, 2022 ''' f0 = 7000 tolerance = 2/100 xtals = [1e6, 1.8432e6, 2e6, 3.2768e6, 3.575e6, 3.579545e6, 3.580e6, 3.6864e6, 4e6, 4.194304e6, 4.9152e6, 5e6, 6e6, 7.3728e6, 8e6, 9.216e6, 9.8304e6, 10e6, 10.245e6, 10.738635e6, 11.0592e6, 12e6, 12.5e6, 13.56e6, 14.31818e6, 14.7456e6, 15e6, 16e6, 17.73447e6, 18e6, 18.432e6, 18.8696e6, 19.6608e6, 20e6, 20.48e6, 21e6, 24e6, 24.576e6] prescalers = [1,8,64,256,1024] results = [] for p in prescalers: for n in range(255): xtal = f0 * p * n for xt in xtals: if abs(xtal - xt)/xt <= tolerance: f = xt/(p*n) df = (f-f0)/f0*100 # percent results.append((f, df, n, p, xt)) def get_df(item): return abs(item[1]) if results: results.sort(key=get_df) for res in results: print("prescaler ={:4d} n={:4d} xtal = {:7.4f} MHz actual f = {:.3f} Δf = {:+3.2f}%".format(res[3], res[2], res[4]/1e6, res[0], res[1]))