Zdravim.
Mám takovej menší problém. Potřebuju pomoct s rutinou pro co nejrychlejší dělení 16b čísla, číslem 100.
Mám tabulku 51 hodnot, který podle určitých závislostí potřebuju násobit číslem menším než 1.
Hodnoty v tabulce představují 100% a já potřebuju kvůli regulaci zmenšovat hodnoty v tabulce po skocích 1%. Nejvíce bude tabulka zmenšená na 10%. NA příliš velké přesnosti výpočtu nezáleží, když mi výsledné 8b číslo uletí o ±2 tak to zas tolik nevadí.
Zatím to řeším tak, že to číslo vynásobím třeba 98 a pak vydělím 100.
Problém je to, že to potřebuju stihnout do 50 us. Když to pic stihne spočítat za kratší čas, tak to bude jenom lepší.
Mám PIC16F1936 taktovaný na 20MHz.
Na násobení mám celkem dobrou rutinu z PIClistu, nejdelší násobení trvá do 16us.
Přechod na řadu 18F není možný, krystal bych taky nerad měnil za vyšší, docela nerad bych měnil časování v programu.
Pokud jde jen o vnitřní výpočet, zkus zauvažovat o jeho “přeměřítkování” na mocninu dvojky (nejbližší je 128). Z důvodu optimalizace jsem tak již program předělával.
Maximální hodnotu (100%) vynásob 2^n/100 (pro 128 to je 1,28 ) a pak místo dělení 128 proveď jen n posunů vpravo (pro 128 je to 7 posunů).
Moje původní úprava byla trochu odlišná, ale myslím, že by to mělo makat protože je to lineární operace. Ještě si to zkusím vykreslit a přidám to sem.
Jde jen o vnitřní výpočet. Díky moc.
Je to mírně nepřesný, uvidím co pak řekne na výstupní průběh osciloskop. V té tabulce mám uložené hodnoty střídy, které se mají dotlačit do PWM modulu. Pokud budu mít stejnou chybu v celém rozsahu tabulky, tak to bude dobrý a nebude mi vznikat bramboroid.
Můžeš to trochu upřesnit? V čem je ta nepřesnost?
Je jasné, že pouhý shift je jako nezaokrouhlené dělení takže chyba 1LSB. To lze odstranit přičtením 1 na řádu n-1 a teprve potom provedení shiftu. Taková chyba ti ovšem nevadila. V tabulkovém procesoru mi vycházely výsledky úplně shodné. Do výpočtu stále dosazuješ požadovaná procenta (0-100), jen se zvětší základ a dělitel. Spíš bych si zkontroloval, jesli ti nepřetejká výpočet. Pokud počítáš v unsigned 16bit, tak tvoje přepočítaná maximální hodnota nesmí být nad 65535/100=655. Z toho máš maximální hodnotu do pwm (při dosazování % 0-100) 655/1.28=511,7=>511 (= téměř 9 bit). Širší pwm v 16ti bitech nespočítáš.
Nebo je tam ještě jiná zásadní nepřesnost?
Včera jsem tím algorytmem počítal několik čísel pro oěření a porovnával s výsledkama z kalkulačky. Lítalo mi to o cca ±5. Teď to je zase přesný. Asi jsem měl vybitý baterky v kalkulačce nebo jsem už včera počítal kdoví co.
Já mám tabulku kde mám hodnoty od 0 do 200. Ty přímo odpovídají výstupní střídě. Při daném výstupním kmitočtu 25kHz a krystalu PIC 20MHz mi vychází ještě 8b široká PWM, ale pouze do hodnoty 200 ne 255.
TAbulku střídy násobím přepočítanou tabulkou s procentními skoky, celou ji už mám vynásobenou 1,28. Když násobím spolu nejvyšší čísla tak mi vychází 25600.
Netuším jestli mám signed nebo unsigned násobení, přiznám se, že nevím ani jaký je v tom rozdíl, jen že signed bývá programově dělší.
Signed je se znaménkem (celá čísla od -(2^(n-1)) do +(2^(n-1))-1 ) a unsigned bez (přirozená čísla od 0 do (2^n)-1). Signed trvá déle, protože musí mcu kontrolovat i to znaménko.
Zálečí na překladači, ale int by měl být znaménkový (někde nutné předepsat “signed”) a “unsigned int” je vždy bez znaménka. Ve tvém případě by to nepřeteklo ani pro jeden typ.