Conectarea cardului SD la avr

Apoi, hai să mergem direct pe hartă.
Cardul de memorie Secure Digital (SD) este un format de card de memorie conceput pentru a fi utilizat în principal în dispozitivele portabile. Pentru a înțelege activitatea sa, vom folosi specificația care descrie acest standard și se numește Specificații SD ver3.01.






Primul lucru de care avem nevoie este să ne dăm seama cum să lucrăm cu această carte, cum să ne conectăm și să facem lucruri. În primul rând, vom selecta o carte. Pentru experimente, am luat un microSD cu o capacitate de 2GB, o capacitate standard SDSC. Busul de card poate funcționa pe două protocoale SD și SPI. Vreau să observ că această carte este un fel de modificare a cardului MMC, unde (în cardul SD) sa acordat atenția principală sistemului de securitate. Prin urmare, algoritmul de lucru pe SPI al protocolului este același, și, desigur, acestea sunt unilateral compatibile. De exemplu, putem introduce MMC în slotul pentru card SD, dar nu invers.

Figura de mai jos arată conexiunea unei cartele SD utilizând protocolul SPI.
Această interfață vă permite să faceți schimb de date la viteză mare, utilizând numărul minim de pinii microcontrolerului echipat cu

Conectarea cardului SD la avr
modulul SPI. De acum încolo, vom începe să folosim specificația. Primul lucru care ne interesează este alegerea regimului. Să ne uităm la complicațiile din Fig. Sub 6.4.1.1, este prezentată o diagramă a tensiunii de alimentare și secvența de trimitere a comenzii. Se vede clar că, după este necesar cardul să aștepte câteva milisecunde (1 ms + 0,1 până la 35 ms (creștere)) să se stabilizeze. În acest timp linia CS, MOSI trebuie depuse 1. Inițializarea suplimentară are loc un maxim de 1 ms întârziere, atunci când sunt aplicate la intrare impulsuri 74 (cicluri CLK) și apoi trebuie să meargă comanda CMD0. Ne întoarcem la capitolul 7, în care secvența acțiunilor este descrisă în mod clar.

Alimentare Diagrama
Conectarea cardului SD la avr

În timpul resetării, cardul trebuie să răspundă 0 × 01, care corespunde primului bit.

Specificația are o secvență de inițializare clară pentru SPI. În acest scop, comanda CMD8 este utilizată pentru a verifica starea de lucru a cardului, unde apare un algoritm de verificare destul de simplu. Apoi, comanda CMD58 pentru a determina tipul de card SDSD sau SDHC și SDXC. Și, de asemenea, comanda CMD41 pentru a porni și verifica inițializarea. Un proces destul de simplu de inițializare cu verificări, dar cred că pentru scrierea mai simplă a datelor, puteți utiliza un proces mai simplu. În secțiunea 7.2.7. afirmă că în modul de așteptare singurele comenzi valide pentru card sunt CMD41, CMD8, CMD58, CMD59. și de asemenea pentru cartelele (memorie groasă de 2,1 mm) CMD1, care este identică cu comanda CMD41. În standard, această comandă este considerată a fi interzisă pentru inițializare și este utilizată exclusiv pentru diferența dintre cardurile de 1.4mm și 2.1mm.
Să mergem mai ușor și să folosim comanda CMD1. Toate cele descrise mai sus vor fi afișate în codul din funcția de inițializare, dar înainte de aceasta vom examina formatul comenzii. Fiecare comandă sau bloc de date constă din octeți de 8 biți, care sunt aliniate la semnalul CLK. Ie fiecare echipă este aliniată de-a lungul limitei de 8 metri. Mesajele SPI constau dintr-o comandă, un răspuns și date. Toată comunicarea este controlată de un microcontroler. Toate comenzile au lungimea de 6 octeți. Transmisia începe cu primul bit stâng.

Figura de mai jos arată formatul comenzii.
Bit inițial - de la 0 pornește orice comandă. Bitul transmis este, de asemenea, întotdeauna 1.
Indicele este o comandă transmisă direct.
Argument - pentru fiecare comandă, argumentul este specificat în tabelul cu specificații.
Verificarea redundanței codului CRC. În mod implicit, este dezactivat în modul SPI. Prin urmare, îl folosim doar pentru comanda CMD0, care este trimisă înainte de a intra în modul și are o valoare de 0 × 95 CRC.
Bit stop - sfârșitul comenzii transmise.
Să începem să scriem codul.
Să începem cu cele 2 funcții necesare: trimiterea și primirea unui octet.
1. Treceți harta byte.
void trans_byte_sd (date despre caractere nesemnate) // matrice de biți trece
pentru (nesemnate char i = 0; i<8;i++) //Перебираем байт
dacă ((date0 × 80) == 0 × 00) // Dacă cel mai semnificativ bit este 0
returnează datele; // Întoarceți răspunsul
3. Transmiterea echipei.
lung int i = 0; // variabila pentru contor
nesignificat char r1; // răspunsul hărții
trans_byte_sd (CMD); // comandă
trans_byte_sd (0 × 00);
trans_byte_sd (0 × 00);
trans_byte_sd (0 × 00);
trans_byte_sd (0 × 95); // Transferați CRC
/ * Dupa trimiterea comenzii, asteptam un raspuns format R1. Fiecare echipa are raspuns propriu * /
/ * Buclă pentru așteptarea unui răspuns pentru o anumită perioadă de timp * /
r1 = receive_byte_sd ();
> în timp ce (((r10 × 80)! = 0 × 00) (i<0xffff)); /* Как только старший бит байта не равен 0 и i не превышает 65 535 тактов*/
întoarcere r1; // Întoarceți răspunsul
4. Și harta este bătută.

Acum putem înregistra inițierea cardului. Pe scurt programul este descris după cum urmează: primul lucru de care aveți nevoie este să puneți cardul în modul SPI. Atunci când alimentarea este pornită, cardul este setat la modul SD. Pentru a selecta modul SPI, o intrare logică 0 este alimentată la intrarea CS, în același timp, comanda de resetare CMD0 și inițializarea CMD1 sunt introduse la intrarea cardului MOSI. Rețineți că comanda începe cu un hexazecimal 0 × 40, la care trebuie adăugat numărul de comandă CMD în hexazecimal.

caracterele nesemnate char spi_card_init (void) // funcția returnează un răspuns
nesignificat char r1; // variabila pentru a primi răspunsul
lung int i = 0; // variabila pentru contor
_delay_ms (10); // o întârziere mică pentru stabilizarea tensiunii.
PORTB | = _BV (PB1); // CS, setat la 1, când dai bare
PORTB | = _BV (PB3); // linie de comandă - 1 MOSI (DI)
pentru (nesemnate char i = 0; i<80;i++) // посылаем более 74 импульса
PORTB | = _BV (PB5); // CLK-1






asm ("nop"); // întârziere cu un ciclu
PORTB =

_BV (PB5); // CLK - 0

PORTB =

_BV (PB1); / * condiția pentru intrarea în linia CS a modului SPI trebuie să fie 0 * /

dacă (r1! = 0 × 01) retur 4; // codurile de eroare pot pune orice
trans_byte_sd (0xff); / * trimite un strobe, un fel de pauză înainte de a primi un răspuns * /
face / / primi un răspuns de pe card
r1 = comand_sd (0 × 41,0 × 00); / * trimite comanda de inițializare * /
trans_byte_sd (0xff); // pauză
i ++; // contra
> în timp ce ((r1! = 0) (i<65535)); /*пока не получен ответ 0 и количество циклов не превышает 0xffff */
dacă (i> = 0xffff) retur 5; / * returnați o eroare dacă depășește timpul de sosire * /
retur 0; // Return 0 în cazul inițializării cu succes

Un alt punct important este scris în caietul de sarcini că informațiile sunt transmise blocuri de 512 biți, în care în cazul în care cartela SDSC ca și în cazul nostru, blocul de lungime mozhn0 set 1-512 biți de comandă CMD16. Valoarea prestabilită este de 512 biți. Apoi, vom descrie două funcții pentru recepționarea și transmiterea blocurilor. În specificație, se dau diagrame bloc, pe baza cărora vom scrie codul.

Transferați blocul de informații pe card.

Pentru transferul unității SINGLE, comanda CMD24 răspunde. După emiterea comenzii, așteptați un răspuns după ceea ce ar trebui să fie octetul de pornire, care pregătește cardul controler pentru a primi informațiile de la sfârșitul starea transmisiei răspunsurilor carte de octet, așa cum este descris în secțiunea 7.3.3.1. Ie răspunsul corect ar trebui să fie = 5. De asemenea, așteptăm eliberarea anvelopei pentru transferul ulterior.

Conectarea cardului SD la avr

O octet de feedback pentru starea transmisiei.

Secțiunea 7.3.3.2 descrie formatul blocului transmis

Conectarea cardului SD la avr

5. Transmiterea blocului de informații.
lung int i; // contra
nesignificat char r1; // răspuns
r1 = comand_sd (0 × 58, arg); // CMD24
dacă (r1! = 0 × 00) retur 6; // ieșire dacă răspunsul nu este 0
trans_byte_sd (0xff); // o pauză scurtă
trans_byte_sd (0xf); // introduceți octetul de început
pentru (int i = 0; i<512;i++) //передаем данные
trans_byte_sd (bloc [i]);
trans_byte_sd (0xff); // octet CRC
trans_byte_sd (0xff); // octet CRC
r1 = receive_byte_sd (); // obține octetul de confirmare
dacă ((r10 × 05)! = 0 × 05) retur 7; // verificați transferul corect
așteptați să eliberați autobuzul
r1 = receive_byte_sd ();
> în timp ce ((r1! = 0xff) (i<65535));
dacă (i> = 0xffff) return 8;
retur 0; // returnați 0 dacă ați reușit

6. Și ultima funcție este citirea blocului. Procedura este în principiu aceeași ca și cu transferul, numai pentru recepție: mai întâi octetul de început, apoi 512 biți și 2 octeți pentru verificarea codului. Rețineți că, chiar dacă CRC este dezactivat, trebuie să trimitem și să primim 2 octeți. Un astfel de format de bloc.

Conectarea cardului SD la avr

lung int i = 0;
nesignificat char r1;
r1 = comand_sd (0X51, arg); // CMD17
dacă (r1! = 0 × 00) retur 5; // Ieșiți dacă răspunsul nu este 0 × 00
trans_byte_sd (0xff);
// Așteptăm începutul unui pachet de date
r1 = receive_byte_sd ();
> în timp ce ((r1! = 0xfe) (i<65535));
dacă (i> = 0xffff) retur 5;
pentru (int i = 0; i<512;i=i+1) //прием данных
bloc [i] = receive_byte_sd ();
receive_byte_sd (); // octet CRC
receive_byte_sd (); // octet CRC
retur 0;

Înainte de a utiliza programul, să examinăm partea hardware. Așa cum am spus mai sus, cardul este compatibil cu microcontrolerul în modul SPI. Rețineți următoarele nuanțe de lucru cu cardul:
1. Conjuncția nivelurilor logice este necesară la tensiunea de alimentare diferită a cardului SD și a microcontrolerului AVR. Este posibil să se utilizeze un separator de tensiune rezistiv, care este liniar, adică Tensiunea de ieșire depinde de tensiunea de intrare. O paralelă poate fi parametric regulator de tensiune Zener, și, de asemenea, că primul exemplu de realizare numai în brațul inferior al diodei Zener este utilizat, care este un divizor neliniar și monitorizează tensiunea de referință datorită proprietăților lor atunci când creșterea tensiunii de intrare pentru a reduce rezistența internă și invers.
Am folosit a doua opțiune. În diagrama de mai jos pe liniile de semnal sunt rezistență de balast (limitatoare de curent), este introdus la tensiunea divizor de 4,5 - 5 V, iar ieșirea este îndepărtată dintr-un divizor umăr inferior. Limitatoarele de curent sunt necesare pentru a proteja cardul și alte periferice atunci când microcontrolerul funcționează defectuos. Cu un dispozitiv bine reglat, acestea nu sunt necesare.
Rețineți că linia MISO nu are nevoie de coordonare; Funcționează doar într-o singură direcție de la card la microcontroler.
2. Al doilea punct, nu folosesc protecția de verificare și scriere a cardului. Cineva are aceste contacte în sloturi, cineva nu.
3. Ultimul moment - mâncare. Fie că alimentați 3.3 volți întregul circuit, inclusiv cu microcontrolerul, fie puneți separatorul pe intrarea circuitului, nu foarte fiabil. Sau stabilizatorul este de 3.3 volti, asa cum am facut si pe cipul LP2980. Un punct important aici este un condensator electrolitic (tantal), care protejează microcontrolerul împotriva dumpingului când scade tensiunea.
Mai jos este programul și rezultatul. Ca întotdeauna, încerc să folosesc un program care îl schimbă în mod constant. Acest cod este preluat din articolul # 5 (indicator de șapte segmente).

#include
#include
#include
#include
// macro-uri pentru a lucra cu indicatorul
#definiti un 128
#define b 32
#define c 8
#define d 2
#define e 1
#define f 64
#define g 16
#define dp 4
blocul de caractere [512] =<>; // scrie / citește tampon pentru a hărți
int j nesemnificat, k = 0; // în macro-ul de întrerupere
caracterele caractere nesemnate [11]; // Array de numere care se afișează pe indicator
void trans_byte_sd (date despre caractere nesemnate); // funcția de transfer byte
nesemnate char receive_byte_sd (void); // Funcția Byte
semnul nesignificat comand_sd (char, char); // funcția de a transmite comanda
caracterele nesemnate char spi_card_init (void); // Funcția de inițializare a cartelei de memorie
caracterele nesemnate char_block_sd (char * bloc, char arg); // Funcția de primire a blocului
semnul nesignificat trans_block_sd (char * bloc, char arg); // Funcția de blocare a transferului
// Inițializați indicatorul
void Slot_init ()
// Ieșire la indicator
ISR (TIMER0_OVF_vect)

Un punct important este timpul de expirare. Este important să monitorizați timpul de citire a înregistrării și ștergerea cardului, deoarece microcontrolerul poate rămâne în modul de așteptare a răspunsului cardului. Specificația descrie în mod clar perioadele de expirare ale cardului. Un card simplu durează 5 ms, după care trece într-un mod de economisire a energiei, în care sunt valabile următoarele comenzi CMD0, CMD1, CMD41 și CMD58. Prin urmare, dacă limita de inactivitate este depășită, transferăm CMD1, răspunsul este procesat ulterior cu cardul.
Mai jos sunt două capturi de ecran din programul WinHex. cu ajutorul căruia putem examina conținutul celulelor de memorie. Programul funcționează după cum urmează: Se scriu date la tampon, se trimite cardul, se șteapă tamponul, se citesc datele de pe card în tampon și se afișează, asigurându-se că datele sunt transferate pe card. Ne uităm la conținutul hărții, resetați tamponul, scrieți 0 pe hartă și deschideți din nou conținutul hărții, asigurându-vă astfel că programul și circuitul funcționează. Ca întotdeauna, suntem de neuitat pentru fleacuri, cum ar fi nu dopajka, nu crosete mari în căi, etc, care poate lua departe partea de leu de timp. Prin urmare, dacă există un osciloscop la îndemână, atunci cu siguranță îl folosiți pentru configurare. În articolul 24, am dat un mic exemplu de diagnosticare a hărții în toate etapele lucrării.

Conectarea cardului SD la avr

Conectarea cardului SD la avr

Conectarea cardului SD la avr
În principiu, asta e tot. În următorul articol, înainte de a descrie sistemul de fișiere și de a crea un logger, ne vom familiariza cu senzorul de umiditate și temperatură DHT11. Apoi începem să scriem datele (temperatura și umiditatea) într-un fișier text, un fel de bază de date. Asta e tot pentru moment. Toate pentru moment.







Articole similare

Trimiteți-le prietenilor: