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