Skip to the content.

Torna all’indice generale >versione in C++

Fasi di una applicazione

accensioneled

Un microcontrollore possiede la specificità di avere integrate nello stesso chip un gran numero di periferiche con le quali una generica applicazione in qualche modo deve colloquiare.

il colloquio si può realizzare sostanzialmente usando due tecniche di gestione:

Il polling degli ingressi è una attività che, insieme al codice del programma, si effettua all’interno del loop().

Una ISR() è una funzione a parte, esterna al loop() che viene richiamata in risposta ad un evento di interrupt.

Sia che venga notificato con un interrupt, sia che venga rilevato dall’appplicazione, in qualche modo si genera un evento di input che deve essere gestito.

Eventi di input possono essere di varia natura: l’input di un pulsante, l’input da una seriale, l’input da una porta digitale in genere. Qualunque sia il tipo di dispositivo, nello sviluppo del ragionamento che faremo adesso, lo possiamo assimilare ad un generico sensore.

In definitiva, se il nostro “sensore” è un pulsante, dovremmo vedere la pressione del pulsante come un generico evento di input al quale il microcontrollore risponde generando un output dopo avere elaborato una logica di comando. Possiamo interpretare la logica di comando come l’algoritmo che genera la risposta all’evento.

Il discorso è del tutto generale e non vale solo per i pulsanti ma per qualunque ingresso e per qualunque applicazione eseguita da un microcontrollore, che, non a caso, in ambito industriale è spesso indicato come Logic Solver.

micro

Quindi le fasi di una generica applicazione dovrebbero essere nell’ordine:

  1. Lettura ingressi

  2. Elaborazione logica di comando

  3. Scrittura uscite

Ad es.:

val = digitalRead(pulsante)   # lettura ingressi
stato = not(stato)              # calcolo logica di comando
digitalWrite(led,stato)      # scrittura uscite

In un microcontrollore le tre fasi sono eseguite in quell’ordine ma, se inserite dentro la funzione loop(), sono eseguite periodicamente, all’infinito, fino allo spegnimento della macchina.

Questo fatto impone alcune riflessioni:

Quanto spesso (azioni periodiche).

Azioni eseguite non sempre (azioni aperiodiche).

Le azioni da eseguire in base al verificarsi di certe condizioni non periodiche. Se il loro accadere non è il frutto di nessun algoritmo in esecuzione nel sistema perchè sostanzialmente dipende da fattori esterni al sistema e quindi non prevedibili, quali valori degli ingressi o segnali di interrupt, allora si possono definire come eventi asincroni.

Gli eventi aperiodici possono essere gestiti:

Di seguito la fase di scrittura delle uscite non viene eseguita ad ogni loop ma solo se un certo ingresso ha un determinato valore:

if in == HIGH:
	digitalWrite(led,closed)	  #scrittura uscita

Azioni con memoria (persistenza di una variabile).

Le variabili in un microcontrollore possono essere dichiarate:

La persistenza di una variabile globale nel loop() potrebbe servire a:

Ad esempio se deduco il nuovo stato da quello precedente:

stato = not stato 

oppure, se deduco il nuovo stato da un ingresso e dallo stato precedente:

if in == HIGH and stato == 0: 	
	stato = 1 

In entrambi i casi precedenti le informazioni devono “sopravvivere” tra un loop e l’altro, cioè il loro valore non deve essere cancellato al termine dell’esecuzione della funzione loop() e ciò può essere ottenuto dichiarando le variabili di memoria globali, cioè dichiarandole all’esterno di tutte le funzioni del sistema, compresa la funzione loop().

Torna all’indice generale >versione in C++