Subroutine Una subroutine è un insieme di istruzioni che si adoperano più volte insieme e nella stessa sequenza. Se usiamo l espressione RJMP per chiamare una subroutine all uscita di essa non ho un ritorno specificato.(non sappiamo all uscita dove torna il programma ) RCALL XXXXXX Etichetta che indica di quanto ci si deve muovere
RJMP vs RCALL Supponiamo che l etichetta asterix indichi il numero 37 Confrontiamo RJMP asterix con RCALL asterix Con RJMP asterix leggo l istruzione nella memoria programma incremento il PC di uno e poi lo incremento di 37 per un totale di k+1 (vedere istruction set), senza influenzare lo stack pointer Con RCALL asterix il PC viene incrementato di 1 ed il suo contenuto viene salvato nello stack pointer, successivamente SP viene aggiornato come nella istruzione di RJMP Con l istruzione RET il contenuto del PC viene aggiornato prendendo il dato salvato precedentemente nello Stack, va messa quindi alla fine della subroutine
RJMP vs RCALL L istruzione RET funziona con un pre-incremento quindi lo stack pointer deve essere alla locazione immediatamente prima a dove è stato salvato il PCL e PCH del PC Program Memory RCALL Prima della chiamata a RET, SP deve essere qui Stack PCL PCH
Subroutine Una subroutine può a sua volta chiamare un altra subroutine che a sua volta ne può chiamare un altra. 0x100 RCALL PIPPO 0x174 PIPPO: CLR 0x182 RCALL PLUTO RET 0x200 PLUTO: SER R16 RET
CLR R18 LDI R16, 5 RCALL CONTA Esempio di subroutine CONTA: FINE: PUSH R17 TST R16 BREQ FINE DEC R16 PUSH R16 POP R17 ADD R18, R17 RJUMP CONTA RET
Interrupt Abbiamo visto negli esempi precedenti che si possono controllare deterministicamente tutte le istruzioni e che cambiamenti portano in tutti i registri anche in presenza di condizioni previste (salti condizionati) Diverso e più complicato è invece controllare eventi provenienti dal mondo esterno. (Es. apertura di porte, di valvole, monitoraggio e controllo della temperatura) Si dovrebbe interrogare periodicamente le periferiche di interfacciamento e controllare lo stato di un byte. Cosa molto dispendiosa.
Interrupt Sistemi Elettronici #6 L interrupt è un meccanismo hardware mediante il quale è la stessa periferica che avverte il verificarsi di un particolare evento. La CPU deve essere quindi in grado di percepire se vi è una periferica che richiede il suo intervento mediante una routine di servizio Alla fine di ogni istruzione la CPU verifica se ci sono periferiche che vogliono essere servite tramite il bit di interrupt Non si può sapere a priori a quale istruzione del codice siamo quando avviene un interrupt Se il registro I=0 anche se una periferica avanza una richiesta di interrupt la CPU non se ne accorge
.CSEG.ORG RJMP RJMP RJMP RETI RETI RETI RESET: 0X00 RESET INT_1 INT_2 Interrupt Bisogna lasciare 17 posti liberi per le Interrupt Si parte quindi da 0x11 SI ESEGUONO DIVERSE ISTRUZIONI RETI Sistemi Elettronici #6 In presenza di una interrupt il processore mette automaticamente il bit I dello SREG a 0 in modo che altre eventuali richieste di interrupt non vengano sentite. RETI ha la stessa funzione di RET con in più la possibilità di settare il bit I a 1
Gestione delle Interrupt Non si può sapere a priori quando avviene una richiesta di interrupt La CPU non prende alcuna precauzione su registri che vengono modificati Per mantenere il registro di stato e gli altri registri che si devono adoperare bisogna quindi prevedere delle procedure di salvataggio Le operazioni di push e pop non alterano il registro di stato, quindi possono essere utilizzate senza alcun problema
INT_1: PUSH R16 IN R16, SREG PUSH R16 PUSH R17 PUSH R18.. POP R18 POP R17 POP R16 OUT SREG, R16 POP R16 RETI Esempio Esempio di procedura di salvataggio Riprendo il contenuto di SREG Riprendo il contenuto R16
PORTE DI I/O Le periferiche più semplici da usar sono le porte di ingresso/uscita: A, B, C, D Ognuna è composta da 8 bit e ad ognuna corrispondono 8 pin esterni Con opportune operazioni di IN e OUT si può quindi agire su queste porte Bisogna specificare se ogni piedino viene visto come uscita o come ingresso DDR X PORT X PIN X Con X= A, B, C, D Esempio: Se si vuole leggere dall esterno si deve leggere in PIN DDR A PORT A PIN A Per vedere cosa portare in uscita bisogna usare PORT
Pin di ingresso/uscita Ad ogni pin corrisponde un bit Se il tasto è chiuso il PIN è di uscita se è aperto il PIN è di ingresso
ESEMPIO di PIN di INGRESSO Inverter a rapporto Se il PIN è di ingresso possiamo pensare di fare questo collegamento Se nell istante in cui vado a leggere il valore è 1, il tasto è aperto; se è 0 il tasto è chiuso
Esempio di PIN di USCITA LED Se il pin è di uscita posso collegare un LED Se bisogna leggere cosa c è dall esterno devo leggere in PIN (A, B, C, D) Se invece bisogna leggere cosa portare in uscita devo leggere in PORT (A, B, C, D)
Configurazione delle porte La tabella seguente schematizza le possibili configurazioni pin per pin DDRA Y PORTA Y PA Y 1 0 0 X può essere un valore qualunque X 0 1 Uscita con valore X Ingresso no int pull up Ingresso pull up interno
IN IN carica dati dallo spazio di I/O (Porte, Timers, Registri di Configurazione) Rd I/O(A) IN Rd,A Con 0<d<31 0<A<63 IN R25, $16 CPI R25, 4 BREQ exit. Exit:NOP ESEMPIO PC PC+1
OUT OUT salva dati dai registri nello spazio di I/O (Porte, Timers, Registri di Configurazione) I/O(A) Rr OUT A,Rr Con 0<d<31 0<A<63 PC PC+1 ESEMPIO CLR R16 SER R17 OUT $18,R16 NOP OUT $18,R17