середа, 22 травня 2013 р.

Продовження експерименту 01. Ще трохи асемблера :-)

Ще раз поміняємо програму

     Тепер доведемо нашу програму до логічного завершення. Для початку поставимо завдання відображати свіченням світлодіодів натискання відповідних кнопок. (зараз у нас світлодіоди гаснуть при натисканні кнопки).
Тобто в початковому положенні у нас не повинен світитися ні один світлодіод, 
 - при натисканні кнопки, що підключена до PB0 - засвічується 1-ий;
 - при натисканні кнопки, що підключена до PB1 - засвічується 2-ий;
 - при натисканні кнопки, що підключена до PB2 - засвічується 3-ий;
 - при натисканні кнопки, що підключена до PB3 - засвічується 4-ий;
 - при натисканні кнопки, що підключена до PB4 - засвічується 5-ий;
 - при натисканні декількох кнопок одночасно світяться відповідні діоди.

     Отже, ми залишаємо нашу програму незмінною до моменту зчитування значень регістру PINB.
(до рядків: 
 out PORTB, r16; Виводимо значення регістра РРЗП r16 в керуючий регістр PORTB
 Main:
 in r16, PINB; Завантажуємо в регістр РРЗП r16 значення з регістра даних порта В. )

     А далі будемо працювати зі значенням регістру R16, в який ми і зчитали стан PINB.
Так як у вихідному стані виводи, до яких приєднані кнопки, мають підтяжку до живлення, то на них встановлений рівень лог.1, а при натисканні кнопки -лог.0 (вивід замикається на землю), то і у регістрі R16 перші 5 бітів будуть мати значення 1. Інші біти можуть мати будь-які значення, вільний вхід без підтягуючого резистора має невизначений стан.

     Отже, нам потрібно проінвертувати перші 5 бітів R16 
(ІНВЕРСІЯ, АБО "ЛОГІЧНЕ НЕ" - ЦЕ ОПЕРАЦІЯ, ЯКА ПОВЕРТАЄ лог.1, якщо операнд рівний лог.0 і навпаки. В загальному позначаэться штрихом над операндом, або знаком "!"перед ним. Також використовується англійське позначення NOT
     А залишкові 3 біти бажано взагалі обнулити, щоб вони ні на що не впливали. Зробити це можна двома способами, обидва з яких ми і розглянемо.

1 спосіб

Спочатку інвертуємо всі біти R16. Для цього після 
 in r16, PINB; Завантажуємо в регістр РРЗП r16 значення з регістра даних порта В. )
пишемо
com r16; Інвертуємо усі біти регістра R16.

Команда COM [РРЗП] здійснює побітову інверсію регістра РРЗП. Тобто у біти, що були рівні 1 запишеться  0, а у ті, що були рівні 0 - 1. Працює з усіма РРЗП.

А далі використаємо прийом, що називається накладанням бітової маски для обнулення бітів 5,6,7 регістра R16.
Для цього використовуємо команду:

andi r16,0b00011111; Обнуляємо останні  3 біти регістра r16

Команда ANDI [РРЗП],[КОНСТАНТА] здійснює побітове "логічне І"  РРЗП і константи. Працює з усіма РРЗП.

("ЛОГІЧНЕ І" - ЦЕ ЛОГІЧНА ОПЕРАЦІЯ, ЯКА ПОВЕРТАЄ лог.1 у випадку, коли ОБИДВА  операнда рівні лог.1. У інших випадках (0,1  1,0  0,0) результатом буде лог.0. В загальному позначається знаком "&" Також використовується англійське позначення AND

УВАГА!!! В асемблерних командах, результат записується у перщий операнд команди, змінюючи його початкове значення!!!! Є виключення але про них скажу окремо.


Неважко зрозуміти, що в такому випадку (andi r16,0b00011111) - у тих бітах, де в константі були 1 залишаться ті, що і були в регістрі (наприклад якщо у регістрі там була 1, то 1&1=1, якщо 0 - то 0&1=0). А от, там, де в константы були 0 , там результатом буде 0.

Після цього виводимо значення R16 у PORTA, як і було раніше в нашій програмі.

Змінений АСМ файл знаходится ТУТ.

     Тепер можна відкомпілювати програму (нагадую, F7). і перевірити її в дебагері (Debug - Start Debugging and break)

Відео процесу відлагодження програми:


2 спосіб

     Другий спосіб подібний до 1-ого тільки використовує інші команди:
Спочатку накладаємо "встановлюючу" бітову маску, тобто встановлюємо три старших біти регістра R16 в лог. 1. Для цього використаємо команду:

ori r16,0b11100000; Встановлюємо останні  3 біти регістра r16



Команда ORI [РРЗП],[КОНСТАНТА] здійснює побітове "логічне АБО"  РРЗП і константи. Працює з усіма РРЗП.

("ЛОГІЧНЕ АБО" - ЦЕ ЛОГІЧНА ОПЕРАЦІЯ, ЯКА ПОВЕРТАЄ лог.1 у випадку, коли ХОЧА Б ОДИН  операнд рівний лог.1.  Лог 0 видає лише коли обидва операнди рівнв лог.0  В загальному позначається знаком "|"  Також використовується англійське позначення OR

Отже після даної команди в регістрі R16 біти 5,6,7 стануть рівними 1, незалежно від свого попереднього значення (адже в константі там 1, операція АБО дасть 1), інші біти не змінять своїх значень - бо в константі там 0 - отже 0|0 =0   0|1=1

     А після цього інвертуємо значення регістра  R16 уже відомою нам командою
 com r16; Інвертуємо усі біти регістра R16.



     В результаті біти, де була  1 (а це біт 5,6,7 і біти, де кнопка не натиснута) стануть рівними 0, і навпаки. Таким чином - результат аналогічний до першого способу. Спробуйте у відладчику і прошийте МК цією програмою.

Файл АСМ ТУТ

     Відео:
     
    Так ми і "довели до розуму" нашу першу програму, ознайомилися ще з декількома командами асемблера і прийомами "накладання бітових масок", що часто використовуються для зміни одного або декількох бітів у регістрі, не чіпаючи інших. У наступній статті ми продовжимо знайомитись з програмуванням на асемблері, а також з деякими важливими нюансами роботи МК.

Немає коментарів:

Дописати коментар