
Microelectronica este o pasiune modernă a ultimilor ani, datorită magiei Arduino. Dar, din păcate, în cazul unui interes suficient, se depășește rapid DigitalWrite(), iar ce trebuie făcut mai departe nu este foarte clar. Dezvoltatorii Arduino au depus mult efort pentru a reduce bariera de intrare în ecosistemul lor, dar dincolo de acesta se află încă o pădure întunecată a circuitelor riguroase, inaccesibilă amatorului.
De exemplu, fișele tehnice. Pare că acestea conțin tot ce ai nevoie, doar să le folosești. Dar autorii lor nu au deloc ca scop popularizarea microcontrolerelor; uneori se pare, că abuzează intenționat de termeni neclari și acronime în descrierea lucrurilor simple, pentru a confuza la maximum neinițiații. Dar nu este totul atât de rău, cu puțină voință, lucrurile devin clare.
În acest articol, voi împărtăși experiența mea de interacțiune a unui umanitar cu fișele tehnice în scopuri hobby. Textul este destinat iubitorilor care au crescut din etapele de bază ale Arduino, presupunând o oarecare familiaritate cu principiile de funcționare ale microcontrolerelor.
Voi începe cu tradiționalul
Clipiți un LED pe Arduino
Și imediat codul:
void setup() {
DDRB |= (1<<5);
}
void loop() {
PINB = (1<<5);
for (volatile uint32_t k=0; k<100000; k++);
}„Ce este asta? – va întreba cititorul experimentat. – De ce scrii ceva în registrul de intrare PINB? Acesta este destinat doar citirii!” Adevărat, , la fel ca majoritatea articolelor didactice de pe internet, susține că acest registru este read-only. Și eu am crezut asta, până nu am recitit despre Atmega328p, pregătind acest articol. Și acolo:

Este o funcționalitate relativ nouă, nu a existat pe Atmega8, nu toată lumea o cunoaște sau nu o menționează din motive de compatibilitate retroactivă. Dar este destul de utilă pentru a demonstra ideea că fișele tehnice ar trebui citite, pentru a folosi toate capabilitățile cipului, inclusiv cele mai puțin cunoscute. Și aceasta nu este singura rațiune.
De ce mai trebuie să citim fișele tehnice
De obicei, utilizatorii de Arduino, după ce s-au jucat cu LED-uri și AnalogWrite-uri, încep să conecteze la placă diverse module și cipuri, pentru care există deja biblioteci scrise. Târziu sau mai devreme, apare o bibliotecă care nu funcționează așa cum ar trebui. Atunci amatorul începe să o modifice pentru a o repara, iar acolo...
Acolo se întâmplă ceva categoric nedeterminat, așa că trebuie să mă duc pe Google, să citesc numeroase tutoriale, să iau pe bucăți coduri potrivite de la alții și, în cele din urmă, să obțin rezultatul dorit. Acest lucru oferă o puternică senzație de realizare, dar, de fapt, procesul amintește de invenția bicicletei prin reverse engineering-ul unei motociclete. Și în plus, nu îmi crește înțelegerea despre cum funcționează această bicicletă. Știu, deoarece am făcut asta timp de destul de mult.
Dacă în locul acestei activități incitante aș fi petrecut câteva zile studiind documentația pentru Atmega328, aș fi economisit o cantitate uimitoare de timp. Până la urmă, este un microcontroler destul de simplu.
Astfel, este necesar să citim fișele tehnice măcar pentru a avea o idee despre cum este construit microcontrolerul și ce poate face. Și încă:
pentru a verifica și a optimiza bibliotecile altora. Acestea sunt adesea scrise de alți pasionați care inventează bicicleta; sau, dimpotrivă, autorii fac intenționat o protecție excesivă împotriva greșelilor. Să fie de trei ori mai mult și mai lent, dar sigur va funcționa;
pentru a avea posibilitatea de a utiliza cipuri în proiect care nu au biblioteci scrise de nimeni;
pentru a-mi ușura sarcina de migrare de la o gamă de microcontrolere la alta;
pentru a optimiza în sfârșit codul meu vechi, care nu se încadra deloc în Arduino;
pentru a învăța să controlez orice cip direct prin registrele sale, fără a mă preocupa să studiez cum funcționează bibliotecile lui, dacă acestea există de fapt.
De ce să scrii direct în registre când există HAL și LL?
Dicționar
HAL, High Abstraction Layer – o bibliotecă pentru controlul microcontrolerului cu un nivel înalt de abstracție. Dacă trebuie să folosim interfața SPI1, pur și simplu o configurăm și o activăm, fără a ne gândi la ce registre răspund la ce.
LL, Low Level API – o bibliotecă care conține macrocomenzi sau structuri cu adresele registrelor, permitând accesul la acestea prin nume. DDRx, PORTx, PINx pe Atmega – acestea sunt LL.
Discuțiile despre „HAL, LL sau registre” apar regulat în comentarii pe Habr. Fără a pretinde acces la cunoștințe astrale, vreau doar să împărtășesc experiența și gândurile mele de amator.
După ce m-am familiarizat mai bine cu Atmega și am citit articole despre minunile STM32, am cumpărat o duzină de plăci diferite – și Discovery, și „Tabletele Albastre”, și chiar cipuri simple pentru proiectele mele personale. Toate acestea au stat timp de doi ani în cutie. La un moment dat, îmi spuneam: „gata, încep să învăț STM de acest weekend”, deschideam CubeMX, generam setarea pentru SPI, observam pereții de text ce erau îmbogățiți de copyright-urile STM și decideam că e chiar prea mult.

Desigur, este posibil să înțelegi ce a scris CubeMX. Dar este clar că să reții toate formulările pentru a le scrie manual ulterior este nerealist. Iar dacă trebuie să depanez, și uit să bifez vreo opțiune în Cube, - e chiar o mare problemă.
Au trecut doi ani, și eu în continuare mă minunez de chipuri tot felul de gustose, dar inaccesibile înțelegerei mele, și din întâmplare am dat peste , chiar dacă este despre STM8. Și brusc am realizat că toată această vreme am bătut la o ușă deschisă: registrele la STM sunt organizate la fel ca la orice alt microcontroler, iar Cube nu este obligatoriu pentru a lucra cu ele. Serios, așa se putea?..
HAL și, în special, STM32CubeMX sunt instrumente pentru inginerii profesioniști care lucrează intens cu cipurile STM32. Principalul avantaj este un nivel înalt de abstractizare, posibilitatea de a migra rapid de la un microcontroler la altul și chiar de la un nucleu la altul, rămânând în cadrul liniei STM32. Amatorii se confruntă rar cu astfel de sarcini – alegerea noastră de microcontrolere este, de obicei, limitată de oferta de pe AliExpress, și migram mai des între cipuri complet diferite – trecem de la Atmega la STM, de la STM la ESP, sau la ceea ce noii prieteni chinezi ne oferă. HAL nu ajută aici, iar timpul petrecut pentru a-l studia este considerabil.
Rămâne LL – dar de la aceasta la registre este un singur pas. Personal, găsesc util să îmi scriu propriile macrocomenzi cu adresele registrelor: studieze mai atent fișa tehnică, mă gândesc la ce îmi va fi necesar în viitor și ce pot omite, îmi structurez mai bine programele, și, în general, depășirea acestora ajută la memorare.
În plus, există o nuanță cu popularul STM32F103 – pentru acesta există două versiuni LL incompatibile, una oficială de la STM, iar cealaltă de la Leaf Labs, folosită în proiectul STM32duino. Dacă scrii o bibliotecă open-source (iar eu am avut exact ), trebuie fie să faci două versiuni, fie să te adresezi direct registrelor.
În final, renunțarea la LL, din punctul meu de vedere, simplifică migrarea, mai ales dacă se planifică încă de la începutul proiectului. Un exemplu exagerat: să scriem un blink Arduino în Atmel Studio fără 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++);
}
}Pentru ca acest cod să facă LED-ul să clipească pe o placă chineză cu STM8 (din ST Visual Desktop), este suficient să schimbăm două adrese:
#define DDR_B 0x5007
#define OUT_B 0x5005Da, eu folosesc o caracteristică de conectare a LED-ului pe placa specifică, va clipi foarte lent, dar tot va clipi!
Ce tipuri de fișe de date există
În articole și pe forumuri, atât în limba rusă, cât și în limba engleză, sub «fișierele de date» se înțelege orice documentație tehnică pentru cipuri, așa procedez și eu în acest text. Formal, ele sunt doar un tip de documentație de acest fel:
Fișă de date – TTH, caracteristici tactico-tehnice. Acestea sunt obligatorii pentru orice componentă electronică. Informație de referință, util de avut la îndemână, dar nu este necesar să o citim cu atenție. Totuși, cipurile mai simple sunt adesea limitate la fișa de date, pentru a nu crea documente suplimentare; în acest caz Manual de Referință se include aici.
Manual de Referință – instrucțiunea propriu-zisă, o carte mare de peste 1000 de pagini. Detaliază funcționarea tuturor componentelor din cip. Documentul principal pentru învățarea microcontrolerului. Spre deosebire de fișa de date, instrucțiunile sunt scrise pentru o gamă largă de MC-uri, conținând multe informații despre perifericele care lipsesc din modelul dvs. specific.
Manualul de programare sau Manualul setului de instrucțiuni – instrucțiunea pentru comenzile unice ale microcontrolerului. Este destinată celor care programează în Assembler. Autorii compilatoarelor o folosesc activ pentru optimizarea codului, așa că, în general, nu ne va fi necesară. Dar este util să ne uităm aici pentru o înțelegere generală, la unele comenzi specifice de tip ieșire din întreruperi, precum și atunci când utilizăm intens debugger-ul.
Notă de aplicație – sfaturi utile pentru rezolvarea unor sarcini specifice, adesea cu exemple de cod.
Fișă de erate – descrierea cazurilor de comportament neobișnuit al cipului cu variante de ocolire, dacă există.
Ce se găsește în fișele de date
Direct în Fișă de date ne pot fi necesare următoarele secțiuni:
Rezumatul dispozitivului – prima pagină a fișei de date vorbește pe scurt despre dispozitiv. Foarte utilă în situațiile când ați găsit undeva un cip (l-ați văzut în magazin, l-ați scos dintr-o placă, ați întâlnit o mențiune) și doriți să înțelegeți ce este.
Descriere generală – o descriere mai detaliată a capabilităților chipset-urilor din gamă.
Pinouts – diagrame de legare pentru toate tipurile posibile de carcase ale chipset-ului (pe ce pin se află fiecare picior).
Descrierea pinilor – descrierea funcției și capabilităților fiecărui pin.
Memory Map – harta adreselor în memorie probabil că nu ne va fi necesară, dar uneori conține și o tabelă a adreselor blocurilor de registre.
Register Map – tabela adreselor blocurilor de registre se află, de obicei, în datasheet, iar în Ref Manual – doar deplasările (address offsets).
Electrical Characteristics – în această secțiune, în primul rând ne interesează specificațiilor maxime absolute, care enumeră sarcinile maxime asupra chipset-ului. Spre deosebire de Atmega328p, care este foarte rezistent, majoritatea microcontrolerelor nu permit conectarea de sarcini mari la pini, ceea ce devine o surpriză neplăcută pentru utilizatorii Arduino.
Package Information – desenuri ale carcaselor disponibile, utile în proiectarea propriilor plăci.
Manual de Referință format structural este compus din secțiuni dedicate perifericilor specifice, menționate în titlurile lor. Fiecare capitol poate fi împărțit în trei părți:
Prezentare generală, Introducere, Features – o prezentare a capacităților periferiei;
Functional Description, Usage Guide sau, pur și simplu, partea principală a secțiunii – o descriere detaliată a principiilor de funcționare ale periferiei și a modurilor de utilizare a acesteia;
Registers – descrierea registrelor de control. În cazuri simple, cum ar fi GPIO sau SPI, aceasta poate fi suficientă pentru a începe utilizarea periferiei, dar adesea este necesar să citim și părțile anterioare.
Cum să citim datasheet-urile
Datasheet-urile pot părea descurajante la început, cu volumul și multitudinea de termeni necunoscuți. De fapt, lucrurile nu sunt atât de sinistre, dacă știi câteva trucuri.
Instalați o aplicație bună pentru PDF. Datasheet-urile sunt scrise în tradițiile glorioase ale manualelor pe hârtie; este ideal să le imprimi, să le pui folii de plastic și să le legi. Hypertextul este prezent în cantități foarte mici. Din fericire, cel puțin structura documentului este decorată cu marcaje, astfel încât o aplicație solidă de citire cu navigare confortabilă este foarte necesară.
Datasheet-ul nu este un manual de C++ de Stroustrup, în el nu trebuie să citești totul. Dacă ai folosit sfatul anterior – găsește clădirea secțiunii necesare în panoul de marcaje.
Datasheet-urile, în special Reference Manuals, pot descrie capacitățile nu ale unui anumit chipset, ci întregii serii. Asta înseamnă că jumătate, dacă nu două treimi din informație, nu este relevantă pentru chipset-ul tău. Înainte de a studia registrele TIM7, verifică în Descriere generală, aveți asta la voi?
A ști engleză suficient la nivel de bază. Fisele tehnice sunt compuse pe jumătate din termeni necunoscuți pentru vorbitorul mediu și pe jumătate din structuri simple de legătură. Există și fișe tehnice excelente în engleză chineză, unde jumătate sunt termeni, iar cealaltă jumătate este un set aleator de cuvinte.
Dacă întâlniți un cuvânt necunoscut, nu încercați să-l traduceți cu un dicționar englez-român. Dacă vă pune în dificultate hysteresis, traducerea „histerezis” nu vă va ajuta deloc. Folosiți Google, Stack Overflow, Wikipedia, forumuri, unde noțiunea de care aveți nevoie va fi .
Cel mai bun mod de a înțelege ceea ce ați citit este să verificați în practică. Așadar, păstrați la îndemână placa de dezvoltare cu care vă familiarizați, sau și mai bine, două – în caz că nu ați înțeles ceva și ați văzut fumul magic.
Este o obișnuință utilă să aveți la îndemână fișa tehnică atunci când citiți un tutorial al altcuiva sau studiați o bibliotecă existentă. Este foarte probabil să găsiți în ea o soluție mai optimă pentru problema dvs. Și invers – dacă nu reușiți să înțelegeți din fișa tehnică cum funcționează registrul, căutați-l: este foarte probabil ca cineva să fi explicat deja în termeni simpli sau să fi lăsat un cod clar pe GitHub.
Dicționar
Câteva cuvinte și denumiri utile, care ajută la familiarizarea mai rapidă cu fișele tehnice. Ceea ce mi-a venit în minte în ultimele zile, completările și corecturile sunt binevenite.
Electricitate
Vcc, Vdd – „plus”, alimentare
Vss, Vee – „minus”, pământ
current – curent
tensiune – voltaj
a scurge curent – a funcționa „pământ” pentru o sarcină externă
a furniza curent – a alimenta o sarcină externă
pin cu toleranță mare la sarcină – pin cu toleranță „ridicată” la sarcină
IO
H, Înalt – pe pinul Vcc
L, Scăzut – pe pinul Vss
Impedanță mare, Hi-Z, floating – pe pin nu este nimic, „împedranță mare”, este de fapt invizibil lumii exterioare.
impuls slab, impuls slab – rezistor intern de tragere sau de întoarcere, un echivalent aproximativ de 50 kOhm (vezi fișa). Folosit, de exemplu, pentru a evita ca pinul de intrare să fluture în aer, provocând declanșări false. Slab – deoarece este ușor „înlocuibil”.
push pull – modul de ieșire al pinului, în care acesta comută între Ridicat și Low – OUTPUT obișnuit cu Arduino.
), dar în fișele tehnice, această denumire pentru pinurile în mod stoc apare adesea. – denumirea modului de ieșire, în care pinul poate fi fie Low, sau Impedanță mare / Floating. De regulă, aceasta nu este un „stoc” deschis adevărat, există diode de protecție, rezistori și altele. Acesta este doar un mod de a desemna funcția de pământ/nimic.
adevărat deschis drain – iar aceasta este un adevărat stoc deschis: pinul este conectat direct la pământ, dacă este deschis, sau rămâne într-o stare suspendată, dacă este închis. Aceasta înseamnă că prin el, dacă este necesar, se poate aplica o tensiune mai mare decât Vcc, dar maximul este totuși specificat în fișa tehnică la secțiunea Clasificări maxime absolute / Tensiune.
Interfețe
în serie – conectate în serie
către lanț – a conecta cipurile într-un lanț prin conectare în serie, crescând numărul de ieșiri.
shift – shift, de obicei denotă deplasarea biților. Prin urmare, pentru a introduce și pentru a extrage – a primi și transmite date bit cu bit.
zăvor – ușa, care acoperă bufferul, în timp ce biții sunt deplasați prin el. Când transferul s-a încheiat, ușa se deschide, biții încep să funcționeze.
pentru a introduce ceas – a efectua transferul bit cu bit, a deplasa toți biții în locurile corecte.
buffer dublu, registru de umbră, registru de preîncărcare – denotația istoriei, când registrul trebuie să fie capabil să primească date noi, dar să le păstreze până într-un anumit moment. De exemplu, pentru a funcționa corect, parametrii PWM (duty cycle, frecvență) nu trebuie să se schimbe până când ciclul curent nu s-a încheiat, dar parametrii noi pot fi deja transmiși. Prin urmare, cele curente sunt păstrate în registru de umbră, iar cele noi ajung în registru de preîncărcare, fiind scrise în registrul corespunzător al cipului.
Tot felul
prescaler – divizor de frecvență
pentru a seta un bit – a seta bitul la 1
pentru a șterge/reset un bit – a reseta bitul la 0 (reset – caracteristică a fișelor tehnice STM)
Ce urmează
În general, ar fi fost planificată o parte practică cu demonstrarea a trei proiecte pe STM32 și STM8, realizate special pentru acest articol folosind fișele tehnice, cu lumini, SPI, temporizatoare, PWM și întreruperi:

Dar textul devine destul de mult, așa că proiectele sunt trimise în partea a doua.
Abilitatea de a citi fișele tehnice te va ajuta cu hobby-ul tău, dar cu greu va înlocui comunicarea reală cu colegii de pasiună pe forumuri și în chat-uri. Totuși, trebuie să înveți în primul rând limba engleză. Așadar, pentru cei care au citit până la capăt – un premiu special: două lecții gratuite la Skyeng la prima plată cu codul HABR2.
Sursa: habr.com
