Avr - как да се отървете от номерата на числа с плаваща запетая, AVR, програмиране

Един от най-силните ограничения AVR (на MCS51 на платформата не влияе) - бързо потребление на паметта, когато пишете C програми.

Какво можете да направите за удобство и бързина RISC C трябва да плати. Още по-примамливо - се използва за изчисление (например, при измерване на напрежение чрез ADC) номера поплавък (плаваща точка). Въпреки факта, че тези изчисления не са точни, те са твърде лесно и удобно за използване - можете да се делят и размножават без да се притеснявате за преливане и лесно да се представят резултатите от изчисленията във формат, разбираем за човека.

Но таксата за плувка е твърде висока - свръзката добавя библиотеки, математика, както и паметта на програмата свършва много бързо. Друго ограничение - изчисления поплавък е бавен (освен ако не се използва хардуер множител тип [1]). Ако няма възможност за изпълнение на алгоритъма програма с номера на приложението, поплавък (поради горните ограничения по отношение на код и скорост), едно от решенията на този проблем е да се премине към по-числа с фиксирана запетая. Техните математически операции (изваждане, Освен това разделение, умножение) не се различават от прости математически операции с цели числа, кодове са компактни и бързи.

Фиксирана точка номер (обикновено един байт или дума на два байта) се състои от цяло число част (разположен в горната 8 бита или 16-битов номер) и фракционна част (съхраняват в най-незначителните битове). Пример числа с фиксирана точка, посочени на фигурата, дължина на дума 8 бита (1 байт).

Преди да използвате числа с фиксирана точка най-важното - да се избере номера на бита (байт или дума), а също така да изберете позицията на десетичната запетая. С цифри като всички е ясно - ако вземем думата (16 бита), изчисленията са по-точни, но скоростта ще падне и обема на кода растат (и двете не по-малко от 2 пъти), и ако вземем байт (8 бита), ние получаваме максимално скорост и най-малката код, но ще се влоши точността. Както обикновено, е необходим компромис и вашата задача - да се вземе правилното решение. Позицията на десетичната точка не се отразява на обема на кода и скорост на математически операции. Тя просто разпространява съотношение точност между цялата и дробната част. Обикновено изчислява чрез колко цифри трябва да се разпределят за цялата част, а останалата част отива при дробна част.

Например, нашата 8-битов номер е запазен напрежение, което ще варира от 0 до 5 волта. Редица от 0 до 5, може да бъде кодиран от поне три цифри, така битовете 7, 6 и 5 ще се съхранява цялата част (3 бита), и битове 4, 3, 2, 1 и 0 - остават под дробна част (5 бита). Броят на дробна част ще покаже колко от 1/32 Volt ще бъде в дробна част. Например, ако битове 7, 6 и 5 е броят 4, и битове 4, 3, 2, 1 и 0 - 30 номера, ще кодира волта напрежение 4,9375 (0,9375 = 30/2 ^ 5 = 30/32) , Байт стойност в този случай ще 100.11110b или 0x9E.

В изчисленията на фиксирана точка (както с прости изчисления на цели числа), следва да се прилагат специални правила:

1. В резултат на добавянето на две числа могат да получават допълнителни разряди. Това се случва, когато се наблюдава преливане. Ако трябва да се вземе под внимание възможността за преливане, а след това допълнителните 1-битови числа трябва да се съхраняват някъде.

2. Резултатът от умножението на два 8-битови числа съхраняват в номер 16-битов, 16-битов два до 32-битов и т. П. (Bit чрез умножаване на сумата).

3. Когато разделяне (голям брой малки частност) трябва да бъде предварително умножава дивидент от постоянна. Най-прости - преместване на броя на ляво от необходимия брой пъти (всяка смяна се умножава по 2), място, изместена резултата в два пъти броя на бита, а след това тихо споделяне. Резултатът е номер фиксирана точка. Например, ако се разделят 8-битово число дивидент се измества наляво от 5 бита (получи 16-битов дивидент) за разделител, фракционна получи 16-битов номер фиксирана точка, където запетаята е между 4 и 5 бита.

4. По-добре е да се използва колкото е възможно повече на етапа на предварително изчислена константи компилация за почистване на код, който ще ги генерира. Например, ако трябва да се сравни напрежението на батерията на напрежението на 1,05 волта, на волта напрежение 1,05 е по-добре да се представи в правилния формат и идентифициране на директива #define.

Когато искате да се покаже броя на фиксирана точка като набор от десетични цифри, по прост алгоритъм:
- първо да вземе цялата част, и да го превърне в един вид характер по обичайния начин.
- за цялата страна на запетаята на равенство (или точка).
- отнеме дробна част, това доведе до десетична, просто умножаване на числителя и знаменателя на броя на фракционните дробна част (стойността на фракцията, както знаем, не се променя) - постоянен. Това постоянно се подбира така, че в знаменателя е броят - десетки градуса, а не на две - в същото време се десетична дроб. Изразът "чрез умножаване на фракционна номер" означава набор от операции целочислени (първоначално умножена с цяло число константа, и след това се разделя от цяло число константа), резултатът от което е, че тя може да бъде фракционна брой умножение. В операции на умножение и деление фактор е или дори или разделител, или и двете - и множител и делител са нечетен (защото са образуващи по този начин размножаването от цяло число). Както дори удобно да се използва постоянно, което е с мощност от две (2, 4, 8, и така нататък. D.), Тъй като постоянно умножение и деление се заменят с обикновено лявата и дясната изместване съответно.
- след числителя на получената стойност се превежда в десетични цифри определени и ги определя след десетичната запетая.

За да се обясни това "мъдрост" вземат всички същия пример - превежда фракционна фиксирана точка 100.11110b (== 0x9E, нашите 4.9375 волта) в символично представяне:
- неразделна част от нашия равен 100б, т. е. 4, да броят 4
- Равен за цялата част на фракционна точка 4.
- отнеме дробна част 11110b. Тя е на 30, т.е., нашата фракция - .. 30 на числителя и знаменателя на 32. Нашата задача - да избере дробно число, така че, когато тя се умножава по знаменателя на 32 получи число, което може да бъде представено десетки градуса, и това, което е степента на десетки, толкова много десетичната знака след десетичната запетая и се получават. Нека това е необходимо, за да получите 3 знака след десетичната запетая, т. Д. знаменателя на 32 настоящето до 1000. Броят на който искате да умножим числителя и знаменателя е равна 1000/32 = 31.25. Отлично, но умножена по дробно число, като само цяло число аритметика? Толкова е просто - първо се умножава по 125, след това разделете на 4 (т.е. равно на 125/4 31.25 ..). В този ред - на първо умножение (ще трябва временно 16-битово цяло число, за да се съхранява в резултат на умножение), и след разделянето, да не се губи точност преди да я изхвърлите остатъка от деление. Умножава по 125, както обикновено, и разделете на 4, броят на изместване 2 бита надясно. Така 30 * 31,25 = (30 * 125) / 4 = 3750/4 = 937,5, закръглено до 938. Така, фракцията 30/32 938/1000 превърна в фракция.
- числител 938 добавя след десетичната запетая, получаваме 4938.

При избора на константи за умножение / деление е удобен за използване изобретателност и добрите стари електронни таблици на Microsoft Excel.