Dopo aver visto come accendere un LED, continuiamo in questa pagina ad esaminare l'uso di PORTx, per generare segnali digitali.
A volte vogliamo accendere o spegnere un solo LED, non otto come nel precedente esempio. Analogamente non sempre è opportuno configurare tutti gli otto pin di PORTx come uscita: è infatti assolutamente legittimo avere alcun pin come ingresso ed altri come uscita. Osservazione 1
La seconda versione del precedente codice, che utilizza lo stesso hardware già presentato, mostra come fare, utilizzando la sintassi dei bit fileld che permette di modificare un solo bit, lasciando gli altri invariati
TRISCbits.RC0 = 0; // Set RC0 pin as Output
LATCbits.LATC0 = 1; // Turn on RC0 pin
In questo caso viene configurato come uscita solo pin RC0 e su di esso viene impostato un valore alto.
Analogamente, per spegnere il LED:
LATCbits.LATC0 = 0; // Turn off RC0 pin
La modalità appena descritta è tipica di XC8 ed utilizzata con praticamente tutti gli SFR associati alle periferiche definiti negli header file distribuiti insieme al compilatore.
In alternativa è ovviamente sempre possibile modificare tutti i pin di una porta con un solo assegnamento. Per esempio per configurare quattro bit come ingresso e quattro come uscita:
TRISC = 0b11110000; // Set R0 -> R3 as output; R4 -> R7 as input
Se, per qualche ragione, non si vuole o non si può utilizzare la sintassi appena mostrata, è possibile utilizzare i normali operatori bitwise per settare o resettare un singolo bit senza modificare gli altri. Per esempio:
LATC = LATC | 0b00000001; // Turn on RC0 pin (or
LATC |= 0b11111110)
LATC = LATC & 0b11111110; // Turn off RC0 pin (or LATC &= 0b11111110)
Da notare che questa seconda modalità NON è utilizzabile con PORTx anche se a volte, apparentemente, funziona. Perché?
L'uso della direttiva #define e delle macro in molti casi rende spesso il codice più leggibile e facile da manutenere. Si veda il secondo codice di esempio, funzionalmente uguale al precedente, ma più semplice da comprendere.
Una volta acceso un LED, vogliamo anche spegnerlo. Magari facendolo lampeggiare. E' quello che fa il codice in blink.c, che utilizza lo stesso hardware già presentato. Per accendere e spegnere un LED è sufficiente un ciclo infinito simile al seguente:
while (1) { // Forever
LATCbits.LATC0 = 1; // Turn on RC0 pin
LATCbits.LATC0 = 0; // Turn off RC0 pin
}
In alternativa è possibile usare la negazione bitwise per invertire lo stato dell'uscita ad ogni ripetizione del ciclo.
while (1) { // Forever
LATCbits.LATC0 = ~LATCbits.LATC0; // Reverse led status
}
Eseguendo entrambi i codici mostrati si scopre però che il LED appare sempre acceso... In realtà lampeggia in modo talmente rapido che il nostro occhio non riesce assolutamente a percepire variazioni. Per verificare ciò è possibile, in alternativa:
Per "rallentare" il ciclo occorre, per esempio, inserire la macro __delay_ms(250) che, come dice il nome, inserisce un ritardo di 250 ms. Per funzionare tale macro richiede la inizializzazione della costante _XTAL_FREQ con l'effettiva frequenza di clock del processore. Osservazione 3.
Un approfondimento sull'argomento.
Il programma presentato è un classicissimo: un LED acceso su otto che scorre continuamente da destra a sinistra e viceversa. Lo trovate a fondo pagina, in due versioni. Il cuore del circuito è costituito da 8 LED collegati a PORTC: potete utilizzare come riferimento questo circuito (lo stesso della fotografia di apertura di questa pagina), PICdemo oppure ancora PICdemo R2. Osservazione 2
La prima versione, piuttosto banale, non fa altro che mandare a PORTC otto bit che indicano quali LED vogliamo accesi e quali spenti. Di positivo ha il fatto che è semplice cambiare la sequenza di accensione dei LED.
Il secondo codice si basa sull'uso di una coppia di operazioni di scorrimento dei bit:
In pratica i bit in uscita, memorizzati nei latch di PORTC, vengono fatti scorrere di una posizione nel verso indicato dalla "freccia". Inizialmente occorre scrivere, per esempio 0b00000001.
Per approfondire trovate anche gli esercizi.
Il passo successivo: Leggere un ingresso digitale
Data di creazione di questa pagina: settembre 2014
Ultima modifica: 20 maggio 2016
PIC18 in C - Versione 0.991 - luglio 2019
Copyright 2014-2019, Vincenzo Villa (https://www.vincenzov.net)
PIC18 in C di Vincenzo Villa è distribuito con Licenza Creative Commons Attribuzione 4.0 Internazionale