Quali sono i vantaggi delle periferiche indipendenti dal core (CIP) per un'applicazione? Oltre a consentire agli utenti di automatizzare determinate attività che normalmente vengono eseguite dall'unità di elaborazione centrale sulla base di istruzioni scritte nel software, riducono la quantità di codice da scrivere per lo sviluppatore e creano un sistema più reattivo e a bassa potenza. Questo video realizzato da Microchip spiega nel dettaglio cosa sono le periferiche indipendenti dal core, come vengono utilizzate e perché rappresentano un vantaggio per il tuo progetto.
Salve a tutti, sono Marc McComb e questa volta desidero dare un'occhiata più da vicino alle periferiche indipendenti dal core.
Forse sapete già che le architetture dei microcontroller sono ricche di periferiche. In molti casi, si tratta di periferiche indipendenti dal core, spesso indicate dalla sigla CIP. Queste periferiche sono state create al fine di automatizzare determinate attività che venivano tradizionalmente eseguite dall'unità di elaborazione centrale sulla base di istruzioni scritte nel software.
Le periferiche indipendenti dal core offrono vantaggi quali la riduzione della quantità di codice da scrivere per lo sviluppatore e la creazione un sistema più reattivo e a bassa potenza. In questo video, vorrei presentarvi una panoramica generale dei vantaggi che queste periferiche apportano a un'applicazione.
A tale scopo, utilizzerò un semplice esempio in cui alternerò lo stato del pin di una porta I/O tra alto e basso creando un output a onda quadra chiamato segnale heartbeat. Per ottenere il segnale heartbeat, ho scritto un codice che cambierà lo stato dell'uscita da alto a basso o viceversa, attraverso un loop che ho mostrato qui utilizzando questo diagramma di flusso.
Ora aggiungiamo un'altra attività all'applicazione. Diciamo che ogni volta che premiamo un pulsante a pressione collegato a un altro pin del microcontroller vogliamo generare un impulso in uscita su un ulteriore pin che avrà un'ampiezza di circa due millisecondi, quindi come un multivibratore monostabile o "one-shot".
Ora, in un microcontroller con periferiche rudimentali, dovremmo implementare questa attività aggiuntiva utilizzando interruzioni che potrebbero avere più o meno questo aspetto. Qui ho utilizzato una periferica timer di base e una porta I/O per usi generici collegata al pulsante a pressione. La maggior parte di queste periferiche è in grado di generare interruzioni comuni presenti nella maggior parte dei moderni microcontroller.
La prima interruzione che utilizzerò è quella che la periferica I/O può generare quando si verifica una modifica di tensione su un pin associato. In questo modo, premendo il pulsante a pressione, la tensione del pin scende a zero volt perché il pulsante qui è a livello alto e viene attivata un'interruzione. Quando il core riceve la notifica dell'attivazione dell'interruzione di una porta I/O, sarà eseguita una verifica della priorità dell'interruzione del software, o dell'hardware se presente.
Questo ci consente di garantire che non siano in corso eventi di interruzione simultanei che abbiano la priorità sull'interruzione in questione. In caso negativo, il core attiva l'Interrupt service routine (ISR) della porta I/O, in base alla quale il core riceve l'istruzione di reimpostare il timer e di caricarlo a un valore specifico in modo da ottenere un overflow a due millisecondi esatti. A questo punto il timer inizia il conteggio.
Il core riceve anche l'istruzione di impostare il nostro pin di uscita su alto, generando il fronte di salita del nostro segnale one-shot. Una volta terminata la routine, il core può tornare alla sua attività precedente, nel nostro caso, alternare il segnale heartbeat. Il core continua quindi ad alternare il segnale fino all'overflow del timer ai due millisecondi preimpostati e all'attivazione di un'interruzione proprio come nel caso della priorità dell'interruzione della porta I/O per software o hardware e, salvo altre interruzioni di maggiore priorità, viene attivata l'ISR per il timer.
Seguendo le istruzioni del codice, il core azzera e ferma il timer, impostando il nostro segnale one-shot sul livello basso. Come potete vedere, non vi è nulla di eccessivamente complicato in questo codice, ma non dobbiamo dimenticare che tutti questi passaggi, l'attivazione dell'intervento di interruzione, il riconoscimento, la prioritizzazione e infine l'esecuzione dell'ISR dell'hardware associato, richiedono tempo qualora il core non sia in grado di alternare il nostro segnale heartbeat.
Cerchiamo di dimostrarlo. Dopo aver scritto il codice per questa applicazione, l'ho scaricato su un microcontroller. Ho un oscilloscopio collegato ai due pin di uscita. Questo segnale in blu è il nostro segnale heartbeat generato dal core, che attiva il pin attraverso il loop. Date un'occhiata a cosa succede quando premo il pulsante a pressione e attivo l'interruzione della porta. Qui potete vedere che ora il segnale heartbeat ha alcuni impulsi mancanti immediatamente prima e dopo il fronte di salita dell'impulso one-shot e per un breve intervallo di tempo prima e dopo il fronte di rilascio dell'impulso one-shot.
Il pulsante a pressione viene premuto proprio qui. E questo ritardo prima del primo fronte dell'impulso one-shot è frutto di diversi fattori, tra cui la latenza dell'interruzione, ovvero il tempo che intercorre tra l'istante in cui viene generata l'interruzione e l'istante in cui il core la rileva. Gran parte di questo ritardo dipende tuttavia dalla prioritizzazione dell'interruzione e dal codice di esecuzione all'interno delle routine secondarie.
Potete anche notare un ritardo dopo che l'impulso one-shot va su alto e prima che il core torni ad alternare il nostro segnale heartbeat. Quindi qui otteniamo qualche impulso in più e in seguito il timer si ferma dopo due millisecondi. Ancora una volta, dopo aver rilevato l'interruzione in breve tempo, il core smette di generare il segnale heartbeat, esegue la prioritizzazione e quindi attiva l'ISR del timer dove imposta il nostro segnale one-shot sul livello basso.
In realtà questa è solo un'applicazione di base in cui abbiamo alternato un I/O in un software. Ma immaginiamo per un istante che invece di alternare un segnale heartbeat questo sia una specie di segnale di ingresso che deve essere rilevato dal core. Ad esempio un input dell'utente, come un sensore touch capacitivo, o persino un segnale più importante come quello che rileva il surriscaldamento del sistema o un potenziale pericolo per l'utente.
In sintesi, il core potrebbe essere impegnato a eseguire un'interruzione e non rilevare il segnale in questione, causando per l'utente conseguenze che vanno da un piccolo fastidio a effetti catastrofici sul sistema. In questo caso, potremmo minimizzare il rischio aumentando la velocità d'esercizio in modo che le interruzioni siano gestite più rapidamente dal core, ma non dimenticate che in questo modo aumentiamo anche il consumo di potenza. Inoltre, una maggiore velocità d'esercizio si limiterà a minimizzare questa interruzione del segnale heartbeat, senza eliminarla completamente.
Potremmo chiedere allo sviluppatore della nostra applicazione di perdere più tempo per il collaudo scrivendo diverse routine software o di configurare gli altri componenti del sistema per migliorare la situazione. Ma come tutti sappiamo, il tempo è denaro. Impiegare più tempo per scrivere il codice o testare diverse configurazioni di sistemi secondari collegati al nostro microcontroller potrebbe quindi rivelarsi piuttosto costoso.
Diamo quindi un'occhiata a una soluzione alternativa che prevede l'uso di periferiche indipendenti dal core. Questo è ATTINY817, un dispositivo AVR che, oltre ad altre periferiche, è dotato di una periferica basata su timer chiamata Timer/Counter Type B o semplicemente TCB e di un'altra periferica chiamata Event System. La periferica Event System è in grado di utilizzare un evento generato in un'altra parte del microcontroller per attivare un altro evento sullo stesso microcontroller.
Quindi, se ad esempio la tensione collegata a uno dei pin di ingresso del nostro comparatore supera la soglia prestabilita, l'uscita del comparatore può essere configurata per andare a livello basso. Grazie all'Event System, potremmo quindi utilizzare questa uscita del comparatore per attivare una conversione da analogica a digitale della tensione su un altro pin.
Oppure una modifica del segnale esterno, ad esempio un pulsante a pressione che, se premuto, attiva un contatore. Un contatore come Timer/Counter Type B o periferica TCB a 16 bit sul microcontroller ATTINY817 è dotato di una modalità di generazione monostabile che, se attivata, genera un impulso di durata definita dall'utente.
Quindi la utilizzerò per generare il nostro segnale one-shot. Mediante la periferica Event System, la porta I/O collegata al pulsante a pressione nel nostro schema sarà instradata al Timer/Counter Type B in modo che una modifica dell'input su quel pin attivi questo segnale one-shot. Una volta implementate queste funzionalità, la nostra applicazione avrà questo aspetto.
Quindi, ancora una volta, il core del microcontroller viene utilizzato per alternare quel segnale heartbeat sul pin I/O. Questa volta tuttavia, invece di affidarci alle interruzioni nel core per generare l'impulso one-shot, instraderemo l'evento sul pin della porta collegato al pulsante a pressione tramite la periferica Event System e lo collegheremo al nostro Timer/Counter Type B in modo che attivi l'impulso di uscita per due millisecondi.
Come potete vedere in questo diagramma a blocchi, il core viene sollevato da qualsiasi attività associata al rilevamento del pulsante a pressione o all'esecuzione del segnale one-shot dal momento che tutto ciò avviene all'interno dell'hardware mediante le funzionalità delle periferiche. Sono andato avanti e ho programmato l'ATTINY817 con questa applicazione, quindi adesso diamo un'occhiata alle nostre forme d'onda.
Ancora una volta, questo è il nostro pin I/O controllato dal core. Questa volta la differenza è che quando premo il pulsante a pressione collegato all'ingresso, l'impulso di due millisecondi gestito nell'hardware dalle periferiche non ha alcun effetto sul segnale heartbeat dal momento che il core non subisce alcuna interruzione. Gestire le attività nell'hardware mediante periferiche invece che nel software significa che il core può svolgere simultaneamente altre attività, come eseguire il codice per il nostro heartbeat o persino entrare in modalità di basso consumo.
Tuttavia, la cosa più importante è che, oltre ad aver migliorato la reattività del sistema eliminando software e interruzioni che tengono occupato il core, siamo stati in gradi di mantenere una bassa velocità d'esercizio senza aumentare il consumo di potenza. Ora vorrei mostrarvi un'ultima cosa. Se ricordate, volevamo che l'impulso di uscita fosse esattamente di due millisecondi.
Tuttavia, date un'occhiata alla versione di questa applicazione basata sull'interruzione del software. Configuriamo il timer in modo da generare un'interruzione a due millisecondi esatti, tuttavia, con le latenze dell'interruzione e il tempo necessario per generare il codice associato alle ISR e così via, il nostro impulso è di circa 300 microsecondi più lungo del previsto.
Date un'occhiata alla nostra forma d'onda quando utilizziamo le periferiche ATTINY817. Come potete vedere, l'impulso è di due millisecondi, proprio dove volevamo, poiché questa attività è gestita nell'hardware, senza le complessità associate all'uso di software e interruzioni. Questa versione con periferiche hardware è stata sviluppata piuttosto rapidamente utilizzando alcuni degli strumenti di programmazione grafica di Microchip Technology che consentono di utilizzare le periferiche per facilitare notevolmente lo sviluppo di applicazioni con microcontroller PIC e AVR.
Parlerò di questi strumenti e molto altro nei prossimi video. Nel frattempo, per maggiori informazioni sull'argomento, visitate la pagina www.microchip.com/8bit. Sono Marc McComb e vi ringrazio per l'attenzione.