Програма роботи АЦП в PIC16, Всі своїми руками

Під час написання однієї з програм, досить об'ємної, зіткнувся з нестачею обсягу пам'яті програм. Вихід був один, оптимізувати програму.

програма

Після того, як ми визначили в регістрі ADCON0 виведення порту A, через який будемо робити оцифрування вхідного сигналу, вибрали джерело тактового сигналу, і підключили модуль АЦП, програма буде в режимі очікування заряду конденсатора протягом 15 мксек. Про це говорить команда CALL MKS15. Програма затримки у файлі не показана. Далі піднімаємо прапор початку перетворення АЦП, тобто. записуємо «1» у розряд GO_DONE у регістрі ADCON0. З цього моменту модуль починає оцифровувати аналоговий сигнал на вході мікроконтролера RA0. Весь цей час програма зациклюється на перевірці цього прапора, команда btfsc ADCO0, GO_DONE. І як тільки прапор опуститься, що свідчить про закінчення перетворення, програма проігнорує команду goto $-1 і перейде до виконання команд зчитування результату перетворення з одночасним зсувом вмісту регістрів ADRESL і ADRESH вправо та перенесення даних у тимчасові регістри REZ_L і REZ_H. Одноразовий зрушення вправо, це нічим іншим, як розподіл значення регістрів на 2. Чому ділимо і чому на два. Оскільки перетворювач ми десятиразрядний, тобто. максимальна кількість перетворення дорівнюватиме в двійковому коді 11 1111 1111, а в десятковій системі числення — 1023. Значить, якщо як опорну напругу для АЦП використовувати джерело опорної напруги — ІОН з напругою 10,23 вольта, то наймолодший розряд двійкового числа відповідав 0,01 вольт. Але така напруга не можна подавати на висновки мікроконтролера. З цього є простий вихід. Розділимо результат перетворення на 2, отримаємо1023 : 2 = 511,5, а як опорну напругу будемо використовувати напругу живлення мікроконтролера величиною 5,115 вольта. Благо, налаштувавши мікроконтролер відповідним чином, це можливо. Але це не найкращий спосіб отримання оцифрованого сигналу, хоч і найпростіший. Точність оцифрування набагато підвищується, якщо використовувати окреме спеціалізоване джерело опорної напруги - ІОН. І так, за командою BSF bank_1 (bank_1 — це заміна тексту і відповідає STATUS, PR0), переходимо в перший банк, оскільки молодший регістр результату перетворення знаходиться в ньому. Зсуваючи вміст цього регістру, ділимо його на 2 і одночасно запам'ятовуємо результат поділу в робочому регістрі WREG. Запам'ятавши результат, повертаємося до нульового банку та переписуємо дані з WREG у допоміжний регістр REZ_L — команда MOVWF REZ_L . Після виконання інструкції зсуву вправо молодший розряд регістру ADRESL перемістився в регістр STATUS розряд Відомий, як прапор позики / переносу, і тепер, при зсуві регістра ADRESH це значення буде всунуто в старший розряд старшого байта ADRESH . Але цього не потрібно, тому ми інструкцією BCF STATUS,C ми обнуляємо значення цього біта. Тепер зрушуємо старший байт результату - RRF ADRESH, w. Запам'ятовуємо у WREG. При цьому зрушенні в біт С, регістру STATUS, запишеться значення молодшого біта старшого байта результату оцифрування. Далі визначаємо його значення та записуємо його у старший біт молодшого байта результату. Цією програмою, не воліючи над нею замислитися, я й користувався досі, доки життя не змусило. Я не претендую на оригінальність цієї програми, але я дуже радий. Так текст оптимізованої програми показаний як «Текст 2». В даному випадку, після закінчення роботи модуля АЦП, ми спочатку зрушуємостарший байт результату і запам'ятовуємо в WREG , у своїй значення молодшого біта, висунутого біта, перетворюється на регістр STATUS , місце біта З — прапора позики/переноса. Далі слідує команда, виконання якої не впливає на біт С - перехід у банк 1. Тепер зрушуємо молодший байт, одночасно значення біту С регістру STATUS приймає старший - сьомий біт молодшого байта. Запам'ятовуємо нове значення у робочому регістрі WREG, повертаємося до нульового банку і переписуємо отримані дані до допоміжний регістр REZ_L. Всі. І так виграш у шість команд. А враховуючи, що кількість перетворень, для збільшення достовірності, може бути і 256 і 1023, це економія і місця і часу. Удачі всім! К.В.Ю.