
La microelettronica è diventata una moda negli ultimi anni grazie al magico Arduino. Ma c'è un problema: con un po' di interesse, è facile superare il DigitalWrite(), ma cosa fare dopo non è molto chiaro. Gli sviluppatori di Arduino hanno fatto un grande sforzo per abbassare la soglia d'ingresso nel loro ecosistema, ma al di fuori di esso c'è ancora una fitta foresta di difficile elettronica, poco accessibile agli appassionati.
Ad esempio, i datasheet. Sembra che contengano tutto, basta prenderli e utilizzarli. Ma gli autori non sembrano avere l'obiettivo di rendere popolari i microcontrollori; a volte sembra, che abusano di termini e abbreviazioni incomprensibili per descrivere cose semplici, per confondere al massimo i neofiti. Ma non è tutto così negativo, se si ha voglia il mistero si svela.
In questo articolo condividerò l'esperienza di un umanista che interagisce con i datasheet per scopi hobbistici. Il testo è destinato a coloro che sono cresciuti con Arduino e presuppone una certa conoscenza dei principi di funzionamento dei microcontrollori.
Inizio con il tradizionale
Flickering LED su Arduino
E subito il codice:
void setup() {
DDRB |= (1<<5);
}
void loop() {
PINB = (1<<5);
for (volatile uint32_t k=0; k<100000; k++);
}«Cosa significa? – chiederà il lettore esperto. – Perché scrivi qualcosa nel registro di ingresso PINB? È solo in lettura!» In effetti, , come la maggior parte degli articoli didattici su Internet, afferma che questo registro è di sola lettura. Anche io lo pensavo, finché non ho riletto il datasheet dell'Atmega328p, mentre preparavo questo articolo. E lì:

Questa è una funzionalità relativamente nuova, non era presente nell'Atmega8, e non tutti lo sanno o lo menzionano per motivi di retrocompatibilità. Ma è molto utile per dimostrare che i datasheet vanno letti, per sfruttare tutte le potenzialità del chip, comprese quelle poco conosciute. E questa non è l'unica ragione.
Perché leggere i datasheet
Di solito, gli appassionati di Arduino, dopo aver giocato con i LED e gli AnalogWrite, iniziano a collegare vari moduli e chip alla scheda, per i quali ci sono già librerie scritte. Prima o poi appare una libreria che non funziona come dovrebbe. Allora l'amatore inizia a modificarla per correggerla, e lì…
E lì succede qualcosa di categoricamente incomprensibile, quindi si finisce per cercare su Google, leggere innumerevoli tutorial, prendere in prestito pezzi di codice da qualcuno e infine ottenere quello che si vuole. Questo dà una potente sensazione di realizzazione, ma in realtà il processo somiglia all'invenzione della bicicletta tramite il reverse engineering di una motocicletta. Inoltre, non si acquisisce comprensione su come funziona questa bicicletta. Lo so, perché ci ho passato abbastanza tempo.
Se invece di quest'attività affascinante avessi dedicato un paio di giorni allo studio della documentazione dell'Atmega328, avrei risparmiato un'enorme quantità di tempo. Dopotutto, si tratta di un microcontrollore piuttosto semplice.
Pertanto, è necessario leggere i datasheet almeno per avere un'idea di come sia strutturato un microcontrollore e cosa possa fare. E ancora:
per controllare e ottimizzare le librerie di altri. Spesso sono scritte da appassionati che inventano la bicicletta; oppure, al contrario, gli autori includono intenzionalmente una protezione eccessiva contro l'errore. Tanto varrà essere tre volte più grandi e lenti, purché funzioni correttamente.
per poter utilizzare nel progetto chip di cui nessuno ha scritto la libreria;
per semplificare il compito di migrazione da una serie di MCU a un'altra;
per ottimizzare finalmente il mio vecchio codice che non riusciva ad adattarsi ad Arduino;
per imparare a gestire qualsiasi chip direttamente attraverso i suoi registri, senza dover approfondire lo studio del funzionamento delle sue librerie, se esistono.
Perché scrivere direttamente nei registri, quando esistono HAL e LL?
Glossario
HAL, High Abstraction Layer – una libreria per la gestione del microcontrollore con un alto livello di astrazione. Se è necessario utilizzare l'interfaccia SPI1, basta configurare e abilitare SPI1, senza preoccuparsi di quali registri siano responsabili di cosa.
LL, Low Level API – una libreria che contiene macro o strutture con indirizzi di registri, consentendo di accedervi per nome. DDRx, PORTx, PINx su Atmega – questi sono LL.
Le discussioni sul tema 'HAL, LL o registri' si verificano regolarmente nei commenti su Habr. Senza pretendere di avere accesso a conoscenze astrali, condividerò semplicemente la mia esperienza e le mie riflessioni da dilettante.
Dopo aver capito a grandi linee l'Atmega e aver letto articoli sulle meraviglie dello STM32, ho acquistato mezza dozzina di schede - sia Discovery, che le 'Blue Pill', e persino semplici chip per i miei progetti fai da te. Tutti loro sono rimasti per due anni a prendere polvere in una scatola. A volte mi ripetevo: «da questo fine settimana inizio a imparare STM», aprivo CubeMX, generavo una configurazione per SPI, guardavo quella parete di testo, arricchita da copyright STM, e decidevo che era davvero troppo.

Certo, è possibile capire cosa ha scritto CubeMX. Ma è chiaro che memorizzare tutte queste formule per poi scriverle a mano è irreale. E debuggarle, se per caso dimentico di mettere un flag in Cube, è davvero un bel guaio.
Sono passati due anni, e ancora guardo con desiderio vari chip interessanti, ma incomprensibili per me, e ho casualmente trovato , anche se su STM8. E improvvisamente ho capito che per tutto questo tempo stavo bussando a una porta aperta: i registri dello STM sono strutturati come quelli di qualsiasi altro microcontrollore, e per lavorarci non hai bisogno di Cube. Davvero, si poteva fare così?..
HAL e in particolare STM32CubeMX sono strumenti per ingegneri professionisti che lavorano intensamente con i chip STM32. La caratteristica principale è l'alto livello di astrazione, che consente di migrare rapidamente da un microcontrollore a un altro e persino da un nucleo all'altro, rimanendo all'interno della famiglia STM32. Gli appassionati si trovano raramente di fronte a questo tipo di problemi: la nostra scelta di microcontrollori è generalmente limitata all'assortimento di AliExpress, e più frequentemente migriamo tra chip radicalmente diversi: passiamo da Atmega a STM, da STM a ESP, o a ciò che i nostri amici cinesi ci propongono di nuovo. HAL qui non aiuterà, e il tempo necessario per studiarlo sarà considerevole.
Rimane LL - ma da esso ai registri ci sono solo pochi passi. Personalmente, trovo utile scrivere i miei macro con gli indirizzi dei registri: studio di più il datasheet, riflettendo su ciò che mi servirà in futuro e cosa non sarà necessario, strutturo meglio i miei programmi e, in generale, superare questa fase aiuta la memoria.
Inoltre, c'è una peculiarità con il popolare STM32F103: esistono due versioni LL incompatibili, una ufficiale di STM e l'altra di Leaf Labs, utilizzata nel progetto STM32duino. Se si scrive una libreria open-source (e io avevo proprio ), è necessario creare due versioni o contattare direttamente i registri.
Infine, rinunciare a LL semplifica, a mio avviso, la migrazione, soprattutto se si pianifica fin dall'inizio del progetto. Esempio eccessivo: scriviamo un blink di Arduino in Atmel Studio senza LL:
#include <stdint.h>
#define _REG(addr) (*(volatile uint8_t*)(addr))
#define DDR_B 0x24
#define OUT_B 0x25
int main(void)
{
volatile uint32_t k;
_REG(DDR_B) |= (1<<5);
while(1)
{
_REG(OUT_B) |= (1<<5);
for (k=0; k<50000; k++);
_REG(OUT_B) &= ~(1<<5);
for (k=0; k<50000; k++);
}
}Per far lampeggiare questo codice un LED su un circuito cinese con STM8 (da ST Visual Desktop), è sufficiente cambiare due indirizzi:
#define DDR_B 0x5007
#define OUT_B 0x5005Sì, sto utilizzando una caratteristica specifica per collegare il LED su questa scheda, lampeggerà molto lentamente, ma ci sarà!
Quali sono i datasheet
Negli articoli e nei forum, sia in russo che in inglese, con ‘datasheet’ si intende qualsiasi documentazione tecnica sui chip, e faccio lo stesso in questo testo. Formalmente, sono solo uno dei tipi di tale documentazione:
Datasheet – TTX, specifiche tecniche operative. Deve essere presente per ogni componente elettronico. Informazioni di riferimento, utile averle a portata di mano, ma non c'è molto da leggere attentamente. Tuttavia, i chip più semplici spesso si limitano al datasheet per non creare documenti superflui; in questo caso Manuale di Riferimento si include qui.
Manuale di Riferimento – istruzioni generali, un manuale dettagliato di oltre 1000 pagine. Descrive in dettaglio il funzionamento di tutto ciò che è contenuto nel chip. Il documento principale per apprendere il microcontrollore. A differenza di datasheet, le istruzioni sono scritte per una vasta gamma di MC, contenendo molte informazioni sulle periferiche che potrebbero non essere presenti nel vostro modello specifico.
Manuale di programmazione o Manuale delle istruzioni – istruzioni per comandi unici del microcontrollore. Destinato a chi programma in Assembly. Gli autori dei compilatori lo utilizzano attivamente per ottimizzare il codice, quindi in generale non sarà necessario. Tuttavia, è utile dare un'occhiata qui per una comprensione generale, in particolare per comandi specifici come l'uscita da un'interruzione e durante l'uso attivo del debugger.
Nota applicativa – suggerimenti utili per risolvere compiti specifici, spesso con esempi di codice.
Foglio degli errori – descrizione di casi di comportamento anomalo del chip con opzioni per superare il problema, se disponibili.
Cosa è incluso nei datasheet
Direttamente nel Datasheet potremmo aver bisogno delle seguenti sezioni:
Riepilogo del dispositivo – la prima pagina del datasheet offre una breve panoramica sul dispositivo. È molto utile nelle situazioni in cui si trova un chip (lo si vede in negozio, si dissolda, si incontra una menzione) e si vuole capire di cosa si tratta.
Descrizione Generale – una descrizione più dettagliata delle funzionalità dei chip della serie.
Pinout – schemi di pinout per tutti i possibili package del chip (quale pin è su quale piedino).
Pin Description – descrizione delle funzioni e delle capacità di ogni pin.
Mappa di Memoria – la mappa degli indirizzi in memoria probabilmente non ci servirà, ma a volte include anche una tabella degli indirizzi dei registri.
Mappa dei Registri – la tabella degli indirizzi dei registri è di solito presente proprio nel datasheet, mentre nel Manuale di Riferimento – ci sono solo gli offset (address offsets).
Caratteristiche Elettriche – in questa sezione ci interessa in primo luogo valori massimi assoluti, elencando i carichi massimi sul chip. A differenza dell'infrangibile Atmega328p, la maggior parte dei microcontrollori non permette di collegare carichi significativi ai pin, il che diventa una spiacevole sorpresa per gli appassionati di Arduino.
Informazioni sul Package – disegni dei package disponibili, utili nella progettazione delle proprie schede.
Manuale di Riferimento è strutturato in sezioni dedicate a specifiche periferiche, indicate nei loro titoli. Ogni capitolo può essere suddiviso in tre parti:
Panoramica, Introduzione, Caratteristiche – panoramica delle funzionalità della periferica;
Descrizione funzionale, Guida all'uso o semplicemente il blocco principale della sezione – una descrizione testuale dettagliata dei principi di funzionamento della periferica e dei modi per utilizzarla;
Registri – descrizione dei registri di controllo. In casi semplici come GPIO o SPI, questo può essere sufficiente per iniziare a utilizzare la periferica, ma spesso è necessario leggere anche le parti precedenti.
Come leggere i datasheet
I datasheet possono intimidire per il loro volume e l'abbondanza di termini incomprensibili. In realtà, non è così spaventoso se si conoscono alcuni trucchi.
Installa un buon lettore di PDF. I datasheet sono scritti secondo le antiche tradizioni delle istruzioni cartacee, è utile stamparli, segnarli con segnalibri di plastica e rileggerli. Il hypertext in essi si osserva in quantità trascurabili. Per fortuna, almeno la struttura del documento è organizzata con segnalibri, quindi un buon lettore con una navigazione comoda è molto utile.
Un datasheet non è un manuale di Stroustrup, in esso non bisogna leggere tutto a caso.. Se hai seguito il consiglio precedente, trova semplicemente la sezione desiderata nel pannello dei segnalibri.
I datasheet, in particolare i manuali di riferimento, possono descrivere le capacità non di un singolo chip, ma dell' intera gamma. Questo significa che metà, se non due terzi, delle informazioni non sono pertinenti al tuo chip. Prima di esaminare i registri TIM7, controlla se Descrizione Generaleè disponibile nel tuo modello.
Conoscere l'inglese è sufficiente a un livello base. I datasheet sono composti per metà da termini poco familiari per un parlante medio e per metà da semplici frasi di collegamento. Ci sono anche dati cinesi ben fatti in inglese cinese, dove metà sono termini e l'altra metà è un insieme casuale di parole.
Se incontri una parola sconosciuta, non cercare di tradurla con un dizionario inglese-russo. Se ti confonde hysteresis, la traduzione «histeresi» non ti porterà a nulla di più chiaro. Usa Google, Stack Overflow, Wikipedia e forum dove il concetto che ti serve sarà .
Il modo migliore per capire ciò che hai letto è verificare sul campo.. Pertanto, tieni a disposizione la scheda di debug con cui stai prendendo confidenza, o meglio ancora due, nel caso in cui ci sia qualcosa che hai frainteso e vedi un magico fumo.
È una buona abitudine avere il datasheet a portata di mano quando leggi un tutorial di qualcun altro o studi una libreria altrui. È probabile che in esso tu trovi una soluzione più ottimale per il tuo compito. E viceversa: se dal datasheet non riesci a capire come funziona il registro, fai una ricerca su Google: molto probabilmente qualcuno ha già scritto tutto in parole semplici o ha lasciato un codice comprensibile su GitHub.
Glossario
Alcune parole e simboli utili per aiutarti a prendere confidenza con i datasheet. Ciò che mi è venuto in mente negli ultimi giorni, integrazioni e correzioni sono benvenute.
Elettricità
Vcc, Vdd – «più», alimentazione
Vss, Vee – «meno», terra
current – corrente
voltage – tensione
to sink current – lavorare come «terra» per un carico esterno
to source current – alimentare un carico esterno
high sink/source pin – pin con maggiore «tolleranza» a carico
IO
H, High – sul pin Vcc
L, Low – sul pin Vss
High Impedance, Hi-Z, floating – sul pin non c'è nulla, «alta impedenza», è praticamente invisibile al mondo esterno.
weak pull up, weak pull down – resistore pull-up/pull-down integrato, con un valore di circa 50 kΩ (vedi datasheet). Utilizzato, ad esempio, per evitare che il pin di ingresso fluttui, causando falsi triggering. Debole – perché è facile "saturarlo".
push pull – modalità di uscita del pin, in cui esso commuta tra Alto e Basso – OUTPUT standard con Arduino.
open drain – Designazione della modalità di uscita, in cui il pin può essere sia Basso, oppure Alta Impedenza / Floating. In questo caso, non si tratta mai di un vero drain aperto, ci sono diodi di protezione, resistori, ecc. È semplicemente la designazione della modalità terra/niente.
true open drain – e questo è un vero open drain: il pin conduce direttamente a terra se è attivato, o rimane in uno stato di sospensione se è chiuso. Ciò significa che attraverso di esso è possibile far passare tensioni superiori a Vcc, ma il massimo è comunque specificato nel datasheet nella sezione Valori Massimi Assoluti / Tensione.
Interfacce
in serie – collegati in serie
to chain – collegare i chip in una catena tramite connessione serie, aumentando il numero di uscite.
shift – shift, di solito indica uno spostamento di bit. Pertanto, to shift in e to shift out – ricevere e trasmettere dati bit a bit.
latch – valvola che copre il buffer mentre i bit vengono spostati attraverso di esso. Quando il trasferimento è completato, la valvola si apre e i bit iniziano a funzionare.
per registrare – eseguire un trasferimento bitwise, spostare tutti i bit nei posti giusti.
buffer doppio, registro shadow, registro di pre-caricamento – designazioni della storia, quando il registro deve essere in grado di ricevere nuovi dati, ma trattenerli fino a un certo punto. Ad esempio, per un funzionamento corretto del PWM, i suoi parametri (duty cycle, frequenza) non devono cambiare finché non termina l'attuale ciclo, ma nuovi parametri possono già essere trasmessi. Pertanto, i correnti rimangono in registro shadow, mentre i nuovi vanno in registro di pre-caricamento, essendo scritti nel registro corrispondente del chip.
Ogni tipo di
prescaler – divisore della frequenza
per impostare un bit – impostare il bit a 1
per azzerare/reimpostare un bit – resettare il bit a 0 (reset – nota dei datasheet STM)
Cosa succede dopo
In realtà, era pianificata una parte pratica con la dimostrazione di tre progetti su STM32 e STM8, realizzati appositamente per questo articolo utilizzando i datasheet, con lampadine, SPI, timer, PWM e interrupt:

Ma il testo sta diventando piuttosto lungo, quindi i progetti saranno inviati nella seconda parte.
La capacità di leggere i datasheet può aiutarti nel tuo hobby, ma difficilmente può sostituire la comunicazione dal vivo con colleghi appassionati su forum e chat. Per questo è comunque necessario migliorare prima di tutto l'inglese. Pertanto, per coloro che arrivano fino alla fine, c'è un premio speciale: due lezioni gratuite su Skyeng al primo pagamento con il codice. HABR2.
Fonte: habr.com
