неділя, 14 липня 2013 р.

Продовження експерименту 05 - Приклади реального використання динамічної індикації

   

   Сьогодні я хочу спробувати показати приклади реального використання динамічної індикації у проектах на МК.



    Спершу напишу програмку, яка буде виводити на індикатор значення певного регістру у звичній нам десятковій формі. Таке застосування зустрічається дуже часто. Найпростіше використати за основу попередню програму. Заберемо з неї рядки ініціалізації значень розрядів
 ;***** Задаємо значення розрядів *****
 ldiall rozrad1,roz1;
 ldiall rozrad2,roz2;
 ldiall rozrad3,roz3;

і саме оголошення констант-значень

 .equ roz1=7;   Значення молодшого (1-го) розряду числа що виводится
 .equ roz2=8;   Значення середнього (2-го) розряду числа що виводится
 .equ roz3=2;   Значення старшого (3-го) розряду числа що виводится

Задамо регістр, значення якого будемо виводити, назвемо його TIM, і задамо його початкове значення.

.def TIM=r20;  Регістр, значення якого буде відображатись

 .equ timset=106;    Початкове значення числа що виводится

Перед початком головного циклу виконаємо ініціалізацію цього регістру:

 ;***** Задаємо значення  *****

 ldi TIM,timset; записуємо в регістр TIM початкове значення (константа timset=106)

    Але для підпрограми динамічної індикації нам потрібні значення десяткових розрядів числа, що міститься в регістрі. Напишемо підпрограму, що буде перетворювати значення регістру TIM в три значення розрядів rozrad1, rozrad2, rozrad3.
Я написав підпрограму, що працює на такому принципі:
    Перед виконанням цієї підпрограми необхідно обнулити значення rozrad1, rozrad2, rozrad3. Також, як ми бачимо, регістр ТІМ буде міняти своє значення, тому в підпрограмі буде використовуватись регістр темр, якому перед виконаням присвоюється значення регістра ТІМ (командою MOV). 
     Проте отримані значення будуть мати нюанс - якщо, припустимо в регістрі ТІМ було число 56, то в старшому розряді rozrad3 залишиться нульове значення. На індикаторі в такому випадку відобразиться 056. Ноль у старшому розряді "незначащий" і в загальному випадку на індикаторі не потрібен. Тому підпрограму треба доповнити процедурою "гасіння незначущого нуля"
     Для цього допишемо в таблицю кодів семисегментного індикатора ще одне значення, нульове (всі сегменти погашені) після кода числа 9. Таким чином, для гасіння розряду, в відповідний регістр rozrad потрібно записати число 10!!!.

    Сама процедура матиме такий вигляд:
Як бачимо, спочатку перевіряється старший 3-ій розряд, якщо він більше 0 то далі перевірка не потрібна, значення розрядів не міняємо, якщо він рівний 0, то записуємо в нього 10 (код погашеного індикатора), і виконуємо перевірку середнього розряда 2. Адже якщо в регістрі число 6 припустимо, то обидва старших розряда будуть нулі (006). Молодший розряд перевіряти не потрібно, 0 в молодшому розряді нам потрібен.

Разом ми отримуємо таку підпрограму (Асемблер):
BinToDigits:
 clr rozrad1; Обнулюємо значення регістрів розрядів
 clr rozrad2;
 clr rozrad3;
 mov temp,TIM; Копіюємо значення TIM в РРЗП temp
 Sotni:
  cpi temp,100; Порівнюємо значення РРЗП temp з константою (число 100)
  brlo Desjatki; Якщо менше то переходимо до мітки Desjatki
  subi temp,100; віднімаємо від значення РРЗП temp 100
  inc rozrad3; збільшуємо РРЗП  rozrad3 на 1
  rjmp Sotni; переходимо до мітки Sotni 
 Desjatki:
  cpi temp,10; Порівнюємо значення РРЗП temp з константою (число 10)
  brlo Odinici; Якщо менше то переходимо до мітки Odinici
 subi temp,10; віднімаємо від значення РРЗП temp 10
  inc rozrad2; збільшуємо РРЗП  rozrad2 на 1
  rjmp Desjatki; переходимо до мітки Desjatki
 Odinici:
  cpi temp,1; Порівнюємо значення РРЗП temp з константою (число 1)
  brlo Clnr; Якщо менше то переходимо до мітки Clnr
  subi temp,1; віднімаємо від значення РРЗП temp 1
  inc rozrad1; збільшуємо РРЗП  rozrad1 на 1
  rjmp Odinici; переходимо до мітки Odinici
 Clnr:
  tst rozrad3;   Перевіряємо rozrad3 на нульове значення
  brne GoOut; Якщо не рівне 0 то перехід до GoOut
  ldiall rozrad3,10; інакше записуємо в rozrad3 число 10
  tst rozrad2Перевіряємо rozrad2 на нульове значення
  brne GoOutЯкщо не рівне 0 то перехід до GoOut
  ldiall rozrad2,10інакше записуємо в rozrad2 число 10
 GoOut:
 ret; Вихід з підпрограми

Вона повністю повторює структури, описані вище.

УВАГА!!! При написанні програм на асемблері іноді корисно спочатку намалювати графічно або описати ту чи іншу частину. Потім простіше це перевсти в асемблерний код, ніж "думати" на асемблері.

Повний код отриманої програми можна скачати ТУТ.

Можете самі провести покрокову відладку і перевірити значення, що записуються в регістри розрядів. Я ж покажу кінцеве відео роботи програми.

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

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