Lumini Rulante, subrutina Delay

 Să se proiecteze un sistem bazat pe microcontroler care ar permite deplasarea luminilor rulante, materializat în baza unei subrutine de reținere. Inițializarea configurației  luminilor va fi realizată cu subrutinele.
Schema electrică propusă:


  
     Realizarea sarcinii

   Atmega16 are 4 porturi. Acestea ne permit conectarea a 8x4=32 de leduri fără scheme electrice suplimentare.



În setul de comenzi a microcontrollerului AVR nu avem instrucțiuni de prelucrare direct a datelor într-un registru periferic. Pentru aceasta va fi necesar să transferăm datele din port într-un registru de uz general P→R, prelucrarea registrului, transferarea datelor din registru în port R→P.
   Conform principiului operațiilor aritmetico-logice atunci cînd reprezentarea rezultatului va ieși din cadrul operandului cu 1 bit, asemenea situație o vom numi transport și bitul suplimentar va fi înregistrat în carry . 




   

     În cazul cînd scriem programul fără  subrutine la un moment dat codul scris devine greu descifrat. Se recomandă utilizarea subrutinelor ce ne dau posibilitatea reutilizării codului scris și modularizarea programului. În acest caz soluția va fi scrisă în secvențe de cod parametrizate accesibile prin chemare. Cauta informatii suplimentare pentru lucrul cu subrutinele şi stiva.

Realizarea problemei va conține 3 subrutine:
  1. Inițializarea porturilor (setarea valorii inițiale a luminilor) va permite configurarea întregului set de leduri cu o valoare, configurație care va fi continuu deplasată pe întreg șirul de led: InitLights.
  2. Reținere în deplasare, va permite reglarea vitezei de deplasare: Delay.
  3. Implementarea algoritmului de deplasare prezentat mai sus: ShiftLight. 
Conform mecanismului de chemare a subrutinei este imposibil apelul de subrutină dacă nu este inițializată stiva. Deci pentru a chema o subrutină oarecare trebuie să inițializăm stiva.
    Schema bloc:                   
1. Schema generala a programului:
2. Schema bloc a subrutinei Delay:
În problema dată este necesar de un timp de reţinere mai îndelungat deoarece frecvenţa MCU este destul de mare. In dependenta de registrul R18 vom putea regula timpul de reţinere în intervale destul de insemante.

3. Schema bloc a subrutinei InitLights:
În registrii R16, R17, R18, R19 setăm valorile dorite, astfel vom putea configura luminele în dependenţă de conectarea ledurilor în schema, cu "0" sau cu "1" logic. Putem pune orice valori, în dependenţă de dorinţă.  

4. Schema bloc a subrutinei ShiftLights:
 Schema algoritmului pentru deplasarea luminilor:
Descrierea algoritmului:


În numerele din cerculeţe este indicat pasul îndeplinirii algoritmului. Deplasarea se va efectua spre partea stîngă. Fiecare port va putea fi setat independent, astfel putem seta valori diferite. Deplasarea se va începe de la PORTD  PORTC  PORTB  PORTA. Astfel de la început se va prelucra PORTD.
PORTD:
1.      Datele din PORTD se încarcă într-un registru de uz general ;
2.      Se efectuează deplasarea logică la stînga – (1), astfel dacă bitul 7 era setat în „1” bitul din registrul de stare SREG – C (carry) se va seta în „1”, ceea ce indică că a avut loc transportul;
3.      Se verifică starea bitului C, dacă este setat în „1” bitul T se va seta în „1”, astfel vom folosi bitul T din SREG ca un buffer, dacă C – „0” bitul T se va seta şi el în „0” – (2);
4.      Se verifică bitul 7 al PORTA, pentru al trece în locul bitului 0 din R16, deplasarea se efectuează prin setarea directă a valoriil, adică dacă PORTA.7 – „0” nu se efectuează nici o operaţie, iar dacă PORTA.7 – „1” vom seta bitul R16.0 – „1” –(3);
5.      Se transferă datele evaluate din registrul de uz general în PORTD - ;
6.      Datele din PORTC se încarcă într-un registru de uz general ;
7.      Se repetă punctul 2 - (4);
8.      Valoarea bitului T, în care a fost salvată informaţia din bitul PORTD.7, se încarcă în bitul 0 din registrul de uz general R16 – (5);
9.      Se repetă punctul 3 - (6);
10.  Se transferă datele evaluate din registrul de uz general în PORTC - ;
11.  Datele din PORTB se încarcă într-un registru de uz general ;
12.  Se repetă punctul 2 - (7);
13.  Valoarea bitului T, în care a fost salvată informaţia din bitul PORTC.7, se încarcă în bitul 0 din registrul de uz general R16 – (8);
14.  Se repetă punctul 3 - (9);
15.  Se transferă datele evaluate din registrul de uz general în PORTB - ;
16.  Datele din PORTA se încarcă într-un registru de uz general ;
17.  Se repetă punctul 2 - (10);
18.  Valoarea bitului T, în care a fost salvată informaţia din bitul PORTB.7, se încarcă în bitul 0 din registrul de uz general R16 – (11);
19.  Se transferă datele evaluate din registrul de uz general în PORTA.

Schema bloc a subrtinei:
Exemplu:
Sa se realizeze un program, care ar realiza calculul unei expresii simple: a * b + 22 cu ajutorul unei subroutine cu parametri. Sa se realizeze protectia starii globale a registrilor. Expresia: a*b+22

Schema bloc: