Math 搜索最佳预分频器(最接近的整数倍)
假设我们有一个带计数器的计时器(Math 搜索最佳预分频器(最接近的整数倍),math,timer,microcontroller,Math,Timer,Microcontroller,假设我们有一个带计数器的计时器(cnt)和一个预分频器(psc),它触发每秒时钟频率(Hz),其中div=cnt*psc和clk\u freq是一个时钟频率,这是不相关的。计数器和预分频器的值范围为[1;65536] 选择cnt和psc的最佳(最快)方法是什么,以便cnt*psc尽可能接近一些所需的div值 例如: desired_div = 3849586 psc = 251, cnt = 15337, psc * cnt = 3849587, distance = 1 psc = 313,
cnt
)和一个预分频器(psc
),它触发每秒时钟频率(Hz),其中div=cnt*psc
和clk\u freq
是一个时钟频率,这是不相关的。计数器和预分频器的值范围为[1;65536]
选择cnt
和psc
的最佳(最快)方法是什么,以便cnt*psc
尽可能接近一些所需的div
值
例如:
desired_div = 3849586
psc = 251, cnt = 15337, psc * cnt = 3849587, distance = 1
psc = 313, cnt = 12299, distance = 1
psc = 1757, cnt = 2191, distance = 1
psc = 2191, cnt = 1757, distance = 1
psc = 12299, cnt = 313, distance = 1
psc = 15337, cnt = 251, distance = 1
用于获取这些值的代码(不够有效):
intmain(intargc,char*argv[])
{
uint32_t val,cnt,psc;
如果(argc<2){
printf(“用法:%s\n”,argv[0]);
返回1;
}
sscanf(argv[1]、“%u”、&val);
printf(“搜索%u\n”,val);
uint32_t hlimit=min(65536,val);
uint32_t llimit=最大值(1,val/65536);
uint32_t minpsc=0,minredif=0xFFFFFFFF;
对于(psc=llimit;psc不确定要快多少或慢多少,不调用任何库以便提供帮助(除了printf)
但是,不要马上知道情况是否总是这样(期望不是这样)
你不需要超过一半,因为你只需要测试两次相同的配对。ab=ba这是一个猜测游戏吗?我想从分解所需的开发开始。展示你所做的尝试以及你认为它们不好的原因。doh,是的,平方根,这需要时间,但仍然可以节省很多。如果(rb>ra)继续;
而不是if(rb>65536)继续;
以避免镜像结果。
int main(int argc, char *argv[])
{
uint32_t val, cnt, psc;
if (argc < 2) {
printf("Usage: %s <u32_value>\n", argv[0]);
return 1;
}
sscanf(argv[1], "%u", &val);
printf("Searching for %u\n", val);
uint32_t hlimit = min(65536, val);
uint32_t llimit = max(1, val / 65536);
uint32_t minpsc = 0, minredif = 0xFFFFFFFF;
for (psc = llimit; psc <= hlimit; ++psc) {
cnt = min(65536, val / psc);
uint32_t redif = abs(val - cnt * psc);
if (cnt < 65536) {
redif = min(redif, abs((cnt + 1) * psc - val));
}
if (redif < minredif) {
minpsc = psc;
minredif = redif;
}
printf("%u %u\n", psc, redif);
}
printf("Optimal psc: %u, difference: %u\n", minpsc, minredif);
return 0;
}
#include <stdio.h>
void fun ( unsigned int x )
{
unsigned int ra;
unsigned int rb;
unsigned int rc;
unsigned int rd;
unsigned int min;
min=0; min--;
for(ra=1;ra<32768;ra++)
{
rb=x/ra;
if(rb>65536) continue;
if(1)
{
rc=rb*ra;
if(rc>x) rd=rc-x;
else rd=x-rc;
if(rd<=min)
{
printf("%u %u %u\n",ra,rb,rd);
min=rd;
}
}
if(1)
{
rc=(rb+1)*ra;
if(rc>x) rd=rc-x;
else rd=x-rc;
if(rd<=min)
{
printf("%u %u %u\n",ra,rb+1,rd);
min=rd;
}
}
}
}
59 65247 13
61 63108 2
122 31554 2
183 21036 2
244 15777 2
251 15337 1
313 12299 1
1757 2191 1
2191 1757 1
12299 313 1
15337 251 1