- Preparare l'hardware
- Comprensione dei pin GPIO su STM8S103F
- Pinout Descrizione e suggerimenti per la selezione GPIO STM8S103F
- Programmazione di STM8S per input e output GPIO utilizzando SPL
- Caricamento e test del programma
Per i microcontrollori, un programma di lampeggiamento LED è equivalente al programma "ciao mondo". Nel nostro tutorial precedente, abbiamo imparato come iniziare con la scheda di sviluppo STM8S103F3 e come configurare l'IDE e il compilatore per programmare i nostri controller STM8S. Abbiamo anche imparato come utilizzare le librerie periferiche standard e come compilare e caricare il codice nel nostro microcontrollore. Con tutte le basi coperte, iniziamo effettivamente a scrivere codice. In questo tutorial, impareremo come eseguire le funzioni GPIO generali sui controller STM8S. La scheda ha già un LED integrato collegato al pin 5 della porta B, impareremo come lampeggiare questo LED e aggiungeremo anche un LED esterno e controllarlo con un pulsante. Se sei completamente nuovo, ti consigliamo vivamente di leggere il tutorial precedente prima di procedere ulteriormente.
Preparare l'hardware
Prima di immergerci nel programma, prepariamo le connessioni hardware. Come accennato in precedenza, utilizzeremo due LED qui, uno è un LED integrato che lampeggerà continuamente e l'altro è un LED esterno che verrà attivato con un pulsante. L'idea è di apprendere tutte le funzionalità GPIO in una semplice configurazione. Il Led di bordo è già collegato a PB5 (pin5 di PORTB), quindi ho appena collegato un LED a PA3 e un pulsante a PA2, come puoi vedere nello schema sotto.
Ma, di tutti i pin di uscita disponibili sul nostro controllo, perché ho selezionato PA3 per l'uscita e PA2 per l'ingresso? Le domande sono valide e lo spiegherò più avanti in questo articolo. La configurazione hardware per questo tutorial è mostrata di seguito. Come puoi vedere, ho anche collegato il mio programmatore ST-link ai pin di programmazione che non solo programmeranno la nostra scheda ma fungeranno anche da fonte di alimentazione.
Comprensione dei pin GPIO su STM8S103F
Ora tornando alla domanda, perché PA2 per l'input e perché PA3 per l'output? Per capirlo, diamo uno sguardo più da vicino al pinout del microcontrollore mostrato di seguito.
Secondo il diagramma di pinout, abbiamo quattro porte sul nostro microcontrollore, vale a dire, PORT A, B, C e D denotate rispettivamente da PA, PB, PC e PD. Ogni pin GPIO è anche bastonato con alcune altre funzionalità speciali. Ad esempio, il PB5 (pin 5 della PORTA B) non può funzionare solo come pin GPIO ma anche come pin SDA per la comunicazione I2C e come pin di uscita Timer 1. Quindi, se usiamo questo pin per semplici scopi GPIO come il collegamento di un LED, non saremo in grado di utilizzare I2C e il LED contemporaneamente. Purtroppo, il LED di bordo è collegato a questo pin, quindi non abbiamo molta scelta qui e in questo programma non useremo I2C, quindi non è un grosso problema.
Pinout Descrizione e suggerimenti per la selezione GPIO STM8S103F
In verità, non sarebbe male usare PA1 un pin di ingresso e funzionerebbe solo pin. Ma l'ho sollevato deliberatamente per offrirmi l'opportunità di mostrarti alcune trappole comuni in cui potresti cadere quando selezioni i pin GPIO su un nuovo microcontrollore. La cosa migliore per evitare le trappole è leggere i dettagli dei pin e la descrizione dei pin forniti nella scheda tecnica STM8S103F3P6. Per i dettagli della descrizione dei pin del microcontrollore STM8S103F3P6 menzionati nella scheda tecnica sono mostrati sotto le immagini.
I pin di ingresso sul nostro microcontrollore possono essere flottanti o pull-up deboli e i pin di uscita possono essere Open Drain o Push-pull. La differenza tra i pin Open Drain e Push-Pull Output è già stata discussa, quindi non entreremo nei dettagli. Per dirla in modo semplice, un pin di uscita Open Drain può rendere l'uscita più bassa non così alta, mentre un pin di uscita push-pull può rendere l'uscita sia alta che alta.
A parte quello dalla tabella sopra, puoi anche notare che un pin di uscita può essere Fast output (10 Mhz) o Slow Output (2 MHz). Questo determina la velocità GPIO, se vuoi cambiare i tuoi pin GPIO tra alto e basso molto velocemente, allora possiamo scegliere Uscita veloce.
Alcuni pin GPIO sul nostro controller supportano True Open Drain (T) e High Sink Current (HS) come menzionato nell'immagine sopra. Una notevole differenza tra Open Drain e True Open Drain è che l'uscita collegata allo scarico aperto non può essere tirata più in alto della tensione operativa del microcontrollore (Vdd) mentre un vero pin di uscita open-drain può essere tirato più in alto di Vdd. Pin con capacità di dissipazione elevata significa che può assorbire più corrente. La corrente di source e sink di qualsiasi pin GPIO HS è di 20 mA, mentre la linea di alimentazione può consumare fino a 100 mA.
Dando uno sguardo più da vicino all'immagine sopra, noterai che quasi tutti i pin GPIO sono di tipo High Sink Current (HS) ad eccezione di PB4 e PB5 che sono True Open Drain Type (T). Ciò significa che questi pin non possono essere alti, non saranno in grado di fornire 3,3 V anche quando il pin è alto. Questo è il motivo per cui il led integrato è collegato a un 3.3V e messo a terra tramite PB5 invece di alimentarlo direttamente dal pin GPIO.
Fare riferimento alla pagina 28 della scheda tecnica per la descrizione dettagliata dei pin. Come menzionato nell'immagine sopra, PA1 viene automaticamente configurato come pull-up debole e non è consigliabile utilizzarlo come pin di uscita. Ad ogni modo può essere usato come pin di ingresso insieme a un pulsante, ma ho deciso di usare PA2 solo per provare ad abilitare il pull up dal programma. Queste sono solo alcune cose di base che saranno utili quando scriveremo programmi molto più complicati. Per ora, va bene se molte cose rimbalzano sulla tua testa, ci occuperemo di questo strato in altri tutorial.
Programmazione di STM8S per input e output GPIO utilizzando SPL
Crea uno spazio di lavoro e un nuovo progetto come abbiamo discusso nel nostro primo tutorial. Puoi aggiungere tutti i file di intestazione e di origine o aggiungere solo i file gpio, config e stm8s. Apri il file main.c e inizia a scrivere il tuo programma.
Assicurati di aver incluso i file di intestazione come mostrato nell'immagine sopra. Apri il file main.c e avvia il codice. Il codice main.c completo si trova in fondo a questa pagina e da lì potrai anche scaricare il file di progetto. La spiegazione del codice è la seguente, puoi anche fare riferimento al manuale utente SPL o al video collegato in fondo a questa pagina se sei confuso sulla parte di codifica.
Disinizializzazione della porta richiesta
Iniziamo il nostro programma de-inizializzando le porte richieste. Come abbiamo discusso in precedenza, ogni pin GPIO avrà molte altre funzioni associate ad esso oltre a funzionare come un normale input e output. Se questi pin sono stati utilizzati in precedenza per altre applicazioni, dovrebbe essere deinizializzato prima di usarli. Non è obbligatorio, tuttavia, è una buona pratica. Le seguenti due righe di codice vengono utilizzate per de-inizializzare la porta A e la porta B. Utilizzare semplicemente la sintassi GPIO_DeInit (GPIOx); e menziona il nome della porta al posto di x.
GPIO_DeInit (GPIOA); // prepara la porta A per lavorare con GPIO_DeInit (GPIOB); // prepara la porta B per lavorare
Dichiarazione GPIO di input e output
Successivamente, dobbiamo dichiarare quali pin verranno utilizzati come input e quali come output. Nel nostro caso verrà utilizzato come input il pin PA2, dichiareremo anche questo pin con pull-up interno in modo da non doverne utilizzare uno esternamente. La sintassi è GPIO_Init (GPIOx, GPIO_PIN_y, GPIO_PIN_MODE_z); . Dove x è il nome della porta, y è il numero di pin e z è la modalità GPIO Pin.
// Dichiara PA2 come input pull up pin GPIO_Init (GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_IT);
Successivamente, dobbiamo dichiarare i pin PA3 e PB5 come output. Anche in questo caso sono possibili molti tipi di dichiarazione di output ma useremo "GPIO_MODE_OUT_PP_LOW_SLOW", il che significa che lo dichiareremo come un pin di output di tipo push-pull a bassa velocità. E per impostazione predefinita, il valore sarà basso. La sintassi sarà la stessa.
GPIO_Init (GPIOA, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_SLOW); // Dichiara PB5 come pin di uscita push pull GPIO_Init (GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_SLOW);
L'istantanea di seguito dal manuale utente SPL menziona tutte le possibili modalità GPIO (z).
Ciclo while infinito
Dopo la dichiarazione del pin, dobbiamo creare un loop infinito all'interno del quale continueremo a far lampeggiare il LED per sempre e monitoreremo lo stato del pulsante per attivare il LED. Il ciclo infinito può essere creato con un while (1) o con un for (;;) . Qui ho usato while (1).
while (1) {}
Verifica dello stato del pin di ingresso
Dobbiamo controllare lo stato del pin di input, la sintassi per farlo è GPIO_ReadInputPin (GPIOx, GPIO_PIN_y); dove x è il nome della porta ey è il numero del pin. Se il pin è alto, otterremo "1" e se il pin è basso, otterremo uno "0". Abbiamo usato per dentro un ciclo if per controllare se il pin è alto o basso.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // se il pulsante viene premuto
Creazione di un pin GPIO alto o basso
Per rendere un pin GPIO alto o basso, possiamo usare GPIO_WriteHigh (GPIOx, GPIO_PIN_y); e GPIO_WriteLow (GPIOx, GPIO_PIN_y); rispettivamente. Qui abbiamo fatto in modo che il LED si accenda se il pulsante viene premuto e si spenga se il pulsante non viene premuto.
if (GPIO_ReadInputPin (GPIOA, GPIO_PIN_2)) // se il pulsante è stato premuto GPIO_WriteLow (GPIOA, GPIO_PIN_3); // LED ACCESO altrimenti GPIO_WriteHigh (GPIOA, GPIO_PIN_3); // LED SPENTO
Commutazione di un pin GPIO
Per attivare o disattivare un pin GPIO, abbiamo GPIO_WriteReverse (GPIOx, GPIO_PIN_y); chiamando questa funzione cambierà lo stato del pin di uscita. Se il pin è alto, verrà cambiato in basso, e se è basso, sarà cambiato in alto. Stiamo usando questa funzione per far lampeggiare il LED integrato su PB5.
GPIO_WriteReverse (GPIOB, GPIO_PIN_5);
Funzione di ritardo
A differenza di Arduino, il compilatore cosmico non ha una funzione di ritardo predefinita. Quindi dobbiamo crearne uno da soli. La mia funzione di ritardo è indicata di seguito. Il valore doe il ritardo verrà ricevuto nella variabile ms e ne useremo due per il ciclo per mantenere o per l'esecuzione del programma. Come _asm ("nop") è un'istruzione di assemblaggio che sta per nessuna operazione. Ciò significa che il controller eseguirà il looping nel ciclo for senza eseguire alcuna operazione, creando così un ritardo.
void delay (int ms) // Definizione della funzione {int i = 0; int j = 0; for (i = 0; i <= ms; i ++) {for (j = 0; j <120; j ++) // Nop = Fosc / 4 _asm ("nop"); // Non eseguire alcuna operazione // codice assembly}}
Caricamento e test del programma
Ora che il nostro programma è pronto, possiamo caricarlo e testarlo. Una volta caricato, il mio hardware funzionava come previsto. Il LED rosso a bordo lampeggiava ogni 500 millisecondi e il LED verde esterno si accendeva ogni volta che premevo l'interruttore.
La lavorazione completa la trovate nel video linkato di seguito. Una volta raggiunto questo punto, puoi provare a collegare l'interruttore e il LED a pin diversi e riscrivere il codice per capire il concetto. Puoi anche giocare con il tempo di ritardo per verificare se hai capito chiaramente i concetti.
Se hai domande, ti preghiamo di lasciarle nella sezione commenti qui sotto e per altre domande tecniche, puoi usare i nostri forum. Grazie per averci seguito, ci vediamo nel prossimo tutorial.