# Function to calc PSC and ARR for a desired frequency, fairly fast!

Question asked by 69.ninja on May 20, 2012
Latest reply on Sep 30, 2014 by ChrisO
The input to this function is a 'Desired Frequency' and the function, fairly quickly locates (out of the 4 billion possibilities! (ARR(16bit)*PSC(16bit)) the correct values for a given TIMER'S PRESCALER(PSC) and PERIOD(ARR) such that you get the TIMER as close as possible to your 'Desired Frequency.'

I just thought someone could use this, I have integrated this into my PHP web interface, but since it is practically C code, you guys could use it with little modification.

Enjoy...

Example outputs:
'Prescaler set at 0x2BFF
uC Response: PSC=P00002BFF
Period set at 0x0153
uC Response: ARR=A00000153
Desired Frequency = 11
Found Frequency = 11.000071500465, Prescaler = 2BFF, Period = 0153"
"Prescaler set at 0x0005
uC Response: PSC=P00000005
Period set at 0x0054
uC Response: ARR=A00000054
Desired Frequency = 100000
Found Frequency = 100000, Prescaler = 0005, Period = 0054"

`function` `SetTimeBase(``\$fdes``)`
`{`
`    ``\$fclk` `= 168000000;`
`    `
`    ``\$period` `= 65535;`
`    `
`    ``\$fd``=0;`
`    ``\$ff``=0;`
`    ``\$z``=0;`
`    `
`    ``for` `(``\$p``=1; ``\$p``<=65536; ``\$p``++)`
`    ``{`
`        ``\$f` `= ((``\$fclk``/2)/``\$p``);`
`    `
`        ``\$x1``=3;`
`        ``\$x2``=65535;  `
`        ``for` `(``\$t``=0; ``\$t``<16; ``\$t``++)`
`        ``{`
`            ``\$x3``=``floor``((``\$x2``-``\$x1``)/2);`
`            ``\$x4``=``\$x3``+``floor``((``\$x2``-``\$x3``)/2);`
`            ``\$x5``=``\$x3``-``floor``((``\$x3``-``\$x1``)/2);`
`            ``if` `((``\$x4``+1)%3 == 0)`
`            ``{`
`                ``\$x4` `+= 1;`
`            ``}`
`            ``else` `if` `((``\$x4``-1)%3 == 0)`
`            ``{`
`                ``\$x4` `-= 1;`
`            ``}`
`            ``if` `((``\$x5``+1)%3 == 0)`
`            ``{`
`                ``\$x5` `+= 1;`
`            ``}`
`            ``else` `if` `((``\$x5``-1)%3 == 0)`
`            ``{`
`                ``\$x5` `-= 1;`
`            ``}               `
`            ``if` `((``\$x4` `> 0) && (``\$x5` `> 0))`
`            ``{`
`                ``if` `(``abs``((``\$f``/``\$x4``/2)-``\$fdes``) < ``abs``((``\$f``/``\$x5``/2)-``\$fdes``))`
`                ``{`
`                    ``\$x1` `= ``\$x3``;  `
`                ``}`
`                ``else`
`                ``{`
`                    ``\$x2` `= ``\$x3``;`
`                ``}`
`            ``}`
`            ``else`
`            ``{`
`                ``break``;`
`            ``}`
`        ``}`
`        ``if` `((``\$x4` `> 0) && (``\$x5` `> 0))`
`        ``{`
`            ``if` `(``abs``((``\$f``/``\$x4``/2)-``\$fdes``) < ``abs``((``\$f``/``\$x5``/2)-``\$fdes``))`
`            ``{`
`                ``\$x` `= ``\$x4``;`
`            ``}`
`            ``else`
`            ``{`
`                ``\$x` `= ``\$x5``;`
`            ``}`
`            ``\$ftmp` `= (``\$f``/``\$x``/2);`
`            ``\$fdif` `= ``abs``(``\$fdes``-(``\$f``/``\$x``/2));`
`            ``if` `(``\$z` `== 0)`
`            ``{`
`                ``\$fd` `= ``\$fdif``;`
`                ``\$ff` `= ``\$ftmp``;`
`                ``\$xx` `= ``\$x``;`
`                ``\$pp` `= ``\$p``;`
`            ``}`
`            ``if` `(``\$fdif` `< ``\$fd``)`
`            ``{`
`                ``\$fd` `= ``\$fdif``;`
`                ``\$ff` `= ``\$ftmp``;`
`                ``\$xx` `= ``\$x``;`
`                ``\$pp` `= ``\$p``;`
`            ``}`
`            ``\$z``++;       `
`        ``}`
`    ``}`

`    ``if` `(``\$pp` `<= 0xFFFF && ``\$xx` `<= 0xFFFF && ``\$pp` `> 0 && ``\$xx` `> 0)`
`    ``{`
`        ``\$pp` `= ``strtoupper``(``str_pad``(``dechex``(``\$pp``),4,``"0"``,STR_PAD_LEFT));`
`        ``\$output` `.= ``"Prescaler set at 0x\$pp<br>uC Response: PSC="``;`
`        ``\$output` `.= shell_exec(``"./test.sh psc=0x"``.``\$pp``.``" 9"``).``"<br />"``;`
`        ``usleep(100);`
`        ``\$xx` `= ``strtoupper``(``str_pad``(``dechex``(``\$xx``),4,``"0"``,STR_PAD_LEFT));`
`        ``\$output` `.= ``"Period set at 0x\$xx<br>uC Response: ARR="``;`
`        ``\$output` `.= shell_exec(``"./test.sh arr=0x"``.``\$xx``.``" 9"``).``"<br />"``;        `
`    ``}`
`    ``else`
`    ``{`
`        ``\$pp` `= ``strtoupper``(``str_pad``(``dechex``(``\$pp``),4,``"0"``,STR_PAD_LEFT));`
`        ``\$xx` `= ``strtoupper``(``str_pad``(``dechex``(``\$xx``),4,``"0"``,STR_PAD_LEFT));`
`        ``\$output` `.= ``"Frequency is out of bounds!<br>Error codes: PSC=0x\$pp,ARR=0x\$xx<br />"``;`
`    ``}`

`    ``\$output` `.= ``"Desired Frequency = \$fdes<br />Found Frequency = \$ff, Prescaler = \$pp, Period = \$xx<br />"``;`

`    ``\$objResponse` `= ``new` `xajaxResponse();`
`    ``\$objResponse``->assign(``"SomeElementId"``,``"innerHTML"``, ``\$output``);`
`    ``return` `\$objResponse``;`
`}`