带后置分频器的分数分频器参数计算算法及优化咨询
核心公式与参数约束
分数分频器输出频率计算公式:
fout = fin / (i + n/d) / p
所有参数均为整数,取值范围:
i: 整数部分 2..256 d: 除数 1..512 n: 被除数 0..511 p: 后置分频器 1..64
要求在微控制器上1ms内完成计算,暴力遍历全部32768种d/p组合速度过慢,仅取最小p保证i不超256会遗漏更优参数。
问题需求
- 是否存在高效的参数计算算法?现有相关问题未给出有效方案,且未覆盖带后置分频器的复杂场景。
- 若无合适算法,暴力法可做哪些优化?比如仅检查d=256512(因d=1255的组合可在d的上半区间找到等效值),能否进一步消除冗余的d/p组合?
- 需要针对三种场景生成参数集:
- 生成最接近且高于目标fout的参数;
- 生成最接近且低于目标fout的参数;
- 生成最接近或精确匹配目标fout的参数;
其中前两类参数用于实现fout的最小步长增减。
可行思路与方案
一、高效解析算法方向
直接推导所有参数的解析解难度较高,但可以通过参数转换缩小搜索空间来提速:
将公式变形为:
fin/(fout*p) = i + n/d
令K = fin/(fout*p),则K必须满足2 ≤ K ≤ 256 + 511/512(因为i最小为2,n/d最大为511/512)。
快速过滤无效p值:
根据K的约束,计算p的有效范围:- p的最小值:
p_min = ceil(fin/(fout*(256 + 511/512))) - p的最大值:
p_max = floor(fin/(fout*2))
直接跳过p_min到p_max之外的所有值,无需遍历全部64个p,能大幅减少遍历次数。
- p的最小值:
拆分K为整数与小数部分,快速匹配n/d:
对每个有效p,计算K = fin/(fout*p),拆分出整数部分i_candidate = floor(K),小数部分f = K - i_candidate。- i的有效取值为
max(2, floor(K))到min(256, ceil(K)),超出范围直接跳过。 - 对于小数部分f,用连分数展开法快速找到满足
0 ≤ n < d ≤512的最优n/d组合,这是数论中逼近小数的经典方法,无需遍历所有d值,能在数步内找到最接近的分数。
- i的有效取值为
二、暴力法的优化方案
如果无法实现解析算法,可通过以下优化大幅压缩搜索空间:
消除d的冗余组合:
对于任意n/d,都可以找到等价的(n*k)/(d*k)(只要d*k ≤512),比如1/2等价于256/512,3/4等价于384/512。因此只需遍历d ∈ [256,512],就能覆盖所有可能的分数值,直接将d的搜索空间从512减半到256。结合i的约束过滤p:
用前面提到的p_min和p_max计算逻辑,只遍历有效范围内的p,避免无效遍历。比如当fin/fout较小时,p_max会远小于64,能排除大量无用p。提前终止无效分支:
对每个p,计算K = fin/(fout*p),如果K < 2或K > 256 + 511/512,直接跳过该p;计算i时,若i不在[2,256]范围内,直接终止该分支的后续计算。预计算分数表:
预计算所有有效n/d的分数值(去重后),存储为{分数值: (n,d)}的键值对。计算时直接查表匹配最接近的小数部分f,无需实时计算所有n/d组合,能节省大量计算时间。
三、三种场景的参数生成逻辑
最接近且高于目标fout:
遍历所有有效参数组合,计算实际输出频率,筛选出所有fout ≥ 目标值的组合,再从中找出与目标值差值最小的一组。若有多个组合差值相同,可优先选择p最小(或i最小,根据硬件偏好)的组合。最接近且低于目标fout:
类似上述逻辑,筛选出所有fout ≤ 目标值的组合,找出差值最小的一组。最接近或精确匹配:
遍历所有有效组合,计算每个组合的fout与目标值的绝对差值,找出差值最小的一组;若存在差值为0的精确匹配组合,直接返回。
内容的提问来源于stack exchange,提问作者p.g.

