Programarea MK de la zero. Programare AVR.

Nu am o dată și nu doi spun că studiul MK ar trebui să fie început cu asamblorul. Acest lucru a fost dedicat unui întreg curs pe site (deși nu este foarte consistent, dar treptat le-am combinat la un tip adecvat). Da, este dificil, rezultatul nu va fi în prima zi, dar veți învăța să înțelegeți ce se întâmplă în controlerul dvs. Veți ști cum funcționează și nu pe maimuță să copieze sursele altor persoane și să încerce să înțeleagă de ce a încetat brusc să lucreze. În plus, SI este mult mai ușor de depășit de mijlocul de mijloc, care va ieși cu furci la momentul cel mai inoportun.

Din păcate, toată lumea dorește imediat rezultatul. Prin urmare, am decis să merg pe de altă parte - să fac formare pe Si, dar cu spectacolul lenjeriei sale. Un bun programator-ambalator îi ține întotdeauna bucata de fier pentru o squală, fără să-i dea un pas pentru a trece fără permisiune. Așa că va fi la începutul codului așa, atunci ce sa născut compilatorul și cum funcționează cu adevărat :)

Pe de altă parte, Si o parte puternică Acesta este codul portabilității. Dacă, desigur, scrieți totul corect. Separarea algoritmilor de lucru și a implementărilor lor de fier în diferite părți ale proiectului. Apoi, pentru a transfera algoritmul la un alt MK, este suficient să rescrieți numai stratul de interfață, unde este scrisă totul la glandă și lăsați întregul cod de lucru așa cum este. Și, desigur, lizibilitatea. Sursa sursei Sash este mai ușor de înțeles la prima vedere (deși ... eu, de exemplu, nu-mi pasă de ce să flirtezi este cel puțin Si, cel puțin AFM :)), dar, din nou, dacă scrie totul corect. Cu aceste momente, voi acorda, de asemenea, atenție.

Ca o bucată de hardware efectuată pe care cota leului din toate exemplele va fi a mea deplasați taxa.

Primul program pe C pentru AVR

Alegerea unui compilator și a instalării mediului
Pentru AVR, există multe compilatoare diferite C:
În primul rând IAR AVR C. - aproape unic recunoscut ca cel mai bun compilator pentru AVR, pentru că Controlorul în sine a fost creat de colaboratorul apropiat al ATMEL și specialiștii din IAR. Dar pentru tot ceea ce trebuie să plătiți. Iar acest compilator nu este suficient pentru ceea ce este un software comercial scump, de asemenea, posedă un astfel de setări de mic dejun care le ia și îl compilează în ea ar trebui să fie gratat. Chiar nu am avut o prietenie cu el, proiectul a fost beat pe greșeli ciudate la etapa de legare (mai târziu a aflat că a fost o curbă de crack).

Al doilea vine Winavr GCC. - Compilator puternic de optimizare. Întreprinderile complete, platforme încrucișate, în general, toate bucuriile vieții. De asemenea, el se integrează perfect în AVR Studio, permițându-vă să depanați chiar acolo că Iadul este confortabil. În general, am ales-o.

De asemenea, există Codevision AVR C.- Compilator foarte popular. El a devenit popular în legătură cu simplitatea sa. Program de lucru Puteți intra în ea în câteva minute - Maestrul codului de plecare este promovat foarte mult, ștampila inițializării tuturor tipurilor de urechi. Sincer, îmi pare rău cu suspiciunea lui - cumva trebuia să dezasamblați un prog scris de acest compilator, un fel de sens, dar nu codul a fost obținut. O cantitate teribilă de televițiuni și operațiuni inutile, care a fost turnată într-un cod ușor și viteză lentă. Cu toate acestea, poate că a existat o greșeală în ADN a scris firmware-ul original. În plus, dorește bani. Nu la fel ca IAR, dar vizibil. Și în Demozhim nu oferă codul de mai mult de 2KB.
Sparge, desigur, există, dar dacă fură, deci un milion, în sensul lui IAR :)

Există deasemenea Image Craft AVR C și Microc. de la microelectronică. Nici să folosească alte utilizări, ci aici SWG. Foarte arat Micropascal.Topirea este un mediu și o bibliotecă de programare extrem de convenabilă. Cred că microc nu va fi mai rău, dar plătit și plătit.

Așa cum am spus, aleg Winavr. Din trei motive: Free, este integrat în AVR Studio și este scrisă pur și simplu o defalcare a codului finit pentru toate ocaziile.

Deci, descărcați-vă pentru a instala Studio Winavr C și AVR. Apoi, studioul este pus în primul rând, de sus, Winavr se rostogolește și se agață de studio sub forma unui plugin. Îți recomand cu insistență instalarea lui Winvr pe scurt, ceva de genul C: \\ Winavr, astfel, evitați grămezi de probleme cu căile.

Crearea unui proiect
Deci, studioul este livrat, Si este fixat, este timpul să încercați ceva de programat. Să începem cu un simplu, mai simplu. Lansați studioul, alegeți acolo proiect nou, ca un compilator AVR GCC și introduceți numele proiectului.

Deschide câmpul de lucru cu un fișier gol *.

Acum nu împiedică configurarea afișajului căilor în filele studioului. Pentru aceasta, înclinarea la:
Meniul Instrumente - Opțiuni - General - Filetabs și selectați "Numai fișier Numai" în lista derulantă. În caz contrar, va fi imposibil să lucrați - în fila va fi o cale completă a fișierului și nu va mai fi mai mult de două file pe ecran.

Configurarea proiectului
În general, crearea fișierului de realizare în care ar fi descrise toate dependențele. Și probabil este corect. Dar am crescut pe site-ul complet integrat ca uvision. sau AVR Studio. Această abordare este profund străină. Prin urmare, voi face în felul meu, toate studiourile.

Strângeți în buton cu o unelte.


Acestea sunt setările proiectului dvs. sau mai degrabă setarea generării automate a fișierului. Pe prima pagină trebuie doar să introduceți frecvența pe care va funcționa MK. Depinde de siguranțele biților, deci credem că frecvența este de 8000000gz.
De asemenea, acordați atenție șirului de optimizare. Acum există o optimizare în dimensiune. În timp ce pleacă așa cum este, atunci puteți încerca să jucați cu acest parametru. -O0 este optimizarea detașabilă deloc.

Următorul pas este de a configura căi. Primul lucru de adăugare a directorului proiectului dvs. există - veți pune o bibliotecă terță parte acolo. Lista va apărea "."

Realizați fișierul generat, îl puteți vedea în dosarul implicit din proiectul dvs., purtați prin ochi, vedeți ce este acolo.


Asta e tot. Jim Oriunde ok și du-te la sursă.

Formularea problemei
Fișa goală este atât de fluturată pentru a încorpora o idee dificilă, deoarece clipirea banală a diodei nu se inserează. Să luăm imediat un taur pentru coarne și să implementăm o legătură cu computerul - acesta este primul lucru pe care îl fac.

Va funcționa așa:
Sub sosirea portului COM, unitatea (codul 0x31) va lumina diodionul și când sosirea zero (cod 0x30) este stinsă. Mai mult, totul se va face pe întreruperi, iar sarcina de fundal va clipi o altă diodă. Pur și simplu și cu semnificație.

Colectați schema
Trebuie să conectăm modulul convertor USB-USART cu convertoarele Microcontroller USART. Pentru a face acest lucru, luați un jumper de două cabluri și puneți crucea în știfturile crucii. Adică, controlerul RX se conectează cu convertorul TX și convertorul TX cu controlerul RX.

Se pare că, ca rezultat, acesta este un astfel de schemă:


Conectarea altor concluzii, nutriție, descărcare, este standard

Noi scriem cod

Faceți imediat o rezervare pe care nu o voi aprofunda în mod specific în descrierea limbii Si în sine. Pentru aceasta, există pur și simplu o cantitate extraordinară de material, variind de la limba clasică "SI de programare" de la K & R și terminând cu diferite tehnici.

O astfel de metodă a fost găsită în mine în fagure, am studiat odată această limbă pe ea. Acolo totul este scurt, de înțeles și în caz. Mă descurc treptat și rearanjat pe site-ul meu.

Nu există cu adevărat capitolul amânat, dar cred că nu este mult timp.

Este puțin probabil ca voi descrie mai bine, deci de la cursul de formare, în loc de o expunere detaliată a subtilităților albastre, voi da pur și simplu legături directe către anumite pagini ale acestei tehnici.

Adăugați biblioteci.
În primul rând, adăugăm bibliotecile și titlurile necesare cu definiții. La urma urmei, Si este un limbaj universal și trebuie să explice că lucrăm cu AVR, deci intrați în linia sursă:

1 #Include.

#Include.

Acest fișier este în dosar Winavr. Și conține o descriere a tuturor registrelor și a porturilor controlerului. Și există toate viclenile, cu referire la un controler specific, care este transmis de compilator prin face Fișier în parametru MCU. Și pe baza acestei variabile în proiectul dvs., un fișier antet cu o descriere a adreselor tuturor porturilor și registrelor este pe acest controler. Cum! Fără, de asemenea, este posibil, dar atunci nu veți putea utiliza numele simbolic al registrelor ca un SREG sau UDR și trebuie să vă amintiți adresa fiecăruia dintre "0xc1", și acesta este un cap.

Aceeași echipă în sine #Include.<имя файла> Vă permite să adăugați la proiectul dvs. Conținutul oricărui fișier text, de exemplu, un fișier care descrie funcțiile sau o bucată de alt cod. Și astfel încât directiva ar putea găsi acest dosar, am indicat căi de a proiecta proiectul nostru (directorul WINAVR este deja scris acolo).

Functie principala.
Programul din limba SI constă în funcții. Ele pot fi încorporate și aduse unul de celălalt în orice ordine și în moduri diferite. Fiecare funcție are trei parametri necesari:

  • Valoarea returnată, de exemplu, păcat (x) Returnează valoarea sinusului x. Ca și în matematică, pe scurt.
  • Parametrii transmis, același X.
  • Funcția corpului.

Toate valorile transmise și returnate trebuie să fie orice tip, în funcție de date.

Orice program pe C trebuie să conțină o funcție principal. Ca punct de intrare la programul principal, altfel este nifiga nu si :). În funcție de prezența principală în sursa altcuiva de la un milion de fișiere, se poate înțelege că acesta este capul programului în care totul începe. Deci, să ne întrebăm:

1 2 3 4 5 Int principal (void) (retur 0;)

int principal (void) (retur 0;)

Totul, primul program cel mai simplu este scris, nu contează că nu face nimic, tocmai am început.

Vom analiza ceea ce am făcut.
int. Acest tip de date pe care se întoarce funcția principală.

Desigur, într-un microcontroler principal. Nu pot returna nimic în principiu și în teorie ar trebui să fie void principal (void)Dar GCC este inițial ascuțit pe PC și există programul poate returna valoarea sistemului de operare la finalizare. Prin urmare, GCC ON. void principal (void) avertizare.

Aceasta nu este o greșeală, va funcționa, dar nu-mi plac varningurile.

nulă. Acest tip de date pe care le transmitem funcției în acest caz principal. De asemenea, nu pot lua nimic din afară, poetul nulă. - Dummy. Plugul este aplicat când nu este necesar să transmiteți nimic sau să reveniți.

Acestea sunt { } Figura brațe sunt un bloc software, în acest caz funcția corpului principal., va fi codul.

Întoarcere. - Aceasta este valoarea de returnare pe care o va oferi funcția principală la finalizare, deoarece suntem INT, adică numărul pe care trebuie să-l întoarcem numărul. Deși încă nu are sens, pentru că Pe microcontrolerul de la Main, noi, cu excepția nicăieri. Întoarce zero. Pentru nonfig. Iar compilatorul este de obicei inteligent și codul nu generează codul.
Deși, dacă pervertiți, apoi de la principal. Puteți merge la MC - de exemplu, cădeți în secțiunea Bootloader și îndepliniți-o, dar există deja o selecție de firmware la nivel scăzut, pentru a regla adresele de tranziție. Mai jos veți vedea și înțelegeți cum să faceți acest lucru. Pentru ce? Aceasta este o altă întrebare, în 99.999% din cazuri Acest Nafig nu este necesar :)

Făcut, a mers mai departe. Adăugați o variabilă, nu este necesară în special pentru noi și nu este necesar să introducem variabile, dar învățăm. Dacă variabilele sunt adăugate în corpul funcției - atunci sunt locale și există numai în această funcție. Când părăsiți funcția, aceste variabile sunt îndepărtate, iar memoria RAM este dată nevoilor mai importante. .

1 2 3 4 5 6 Int principal (void) (nesemnat char i; retur 0;)

int principal (void) (nesemnat char i; retur 0;)

nesemnat Atât de nesalabile. Faptul este că, în reprezentarea binară, avem un bit de vârf pentru semnul, ceea ce înseamnă într-un byte (caractere) numărul + 127 / -128, dar dacă semnul aruncați deja de la 0 la 255. De obicei, semnul este nu e necesar. Astfel încât nesemnat.
i. - Acesta este doar numele variabilei. Nu mai.

Acum trebuie să inițializați porturile și UART.. Desigur, puteți să luați și să conectați biblioteca și să apelați un fel de uartinit (9600); Dar atunci nu veți ști ce sa întâmplat de fapt.

Facem acest lucru:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Int principal (nul) (caractere nesemnate i; #define xtal 8000000L #define baudrate 9600L #Define baudidivid (Xtal / (16 * baudrate) -1) #Define hi (x) ((x) \u003e\u003e 8) #define lo (x) ((x) & 0xFF) ubrl \u003d lo (bauddivid); Ubrh \u003d hi (bauddividorul); UCSRA \u003d 0; UCSRB \u003d 1.<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int principal (nuld) (nesemnat char i; #define xtal 8000000L #define baudrate 9600L #define bauddividiv (xtal / (16 * baudrate) -1) #define hi (x) ((x) \u003e\u003e 8) #define lo ( x) ((x) & 0xFF) Ubrl \u003d lo (bauddividor); Ubrh \u003d hi (bauddividiv); UCSRA \u003d 0; UCSRB \u003d 1<

Infricosator? De fapt, codul real aici este doar cinci linii de ultimă oră. Tot ce #Defini Acesta este un preprocesor macro-limbă. Aproape aceleași vârfuri ca și în asamblare, dar sintaxa este oarecum diferită.

Acestea vă vor facilita operațiunile de rutină pentru a calcula coeficienții necesari. În prima linie spunem acest lucru Xtal. Puteți înlocui în siguranță 80.000.000 și L.- Specificație tip, Mall lung sunt o frecvență a ceasului procesorului. La fel baudrate. - frecvența datelor de către UART.

bauddividorul. Deja mai complicată, expresia calculată prin formula a două dintre cele anterioare va fi înlocuită în schimb.
Bine si Lo. și SALUT Din acest rezultat va lua octeții mai tineri și seniori, pentru că Într-un byte, este clar să nu se potrivească. ÎN SALUT Schimbarea ICSE se face (parametrul de intrare al macro-ului) de opt ori în dreapta, ca rezultat, numai cel mai vechi octet va rămâne. A B. Lo. Facem un lot și cu un număr de 00ff, ca rezultat, numai cel mai tânăr octet va rămâne.

Deci, tot ceea ce se face ca #Defini Puteți arunca în siguranță, iar numerele dorite se numără pe calculator și le introduce imediat în UbbrL \u003d linii .... și Ubbrh \u003d ... ..

Poate sa. Dar! Fa asta Este categoric imposibil!

De asemenea, va lucra pentru a lucra, dar veți avea așa-numita numere magice - Valorile luate de neînțeles de unde nu este clar de ce și dacă dați un astfel de proiect în câțiva ani, atunci este greu de înțeles că va fi naibii. Da, și acum, doriți să schimbați viteza sau să schimbați frecvența cuarțului și totul va trebui să recalculați, așa că a schimbat un cuplu de Tsiferok în cod și totul în sine. În general, dacă nu doriți să vă bucurați de BydLokoder, faceți codul astfel încât să fie ușor de citit, a fost ușor de înțeles și ușor de modificat.

Apoi totul este simplu:
Toate aceste "Ubrl și Co" sunt registrele configurației transmițătorului cu care vom comunica cu lumea. Și acum am atribuit valorile necesare prin configurarea vitezei dorite și a modului potrivit.

Vizualizare de înregistrare 1< Înseamnă următoarele: Luați 1 și puneți-l în poziție Rxen. În zbor. Rxen. Aceasta este a patra parte a registrului UCSRB., astfel încât 1< formează un număr binar 00010000, Txen. - Acesta este un al treilea bit, și 1< DAST 00001000. Single "| Este stricat SAUastfel 00010000 |. 00001000 \u003d 00011000. Bițele de configurare necesare rămase sunt expuse în același mod și adăugate la Generalul General. Ca rezultat, numărul de asamblare este scris în UCSRB. Detaliile sunt scrise în Datashet pe MC în secțiunea USART. Deci, nu vă distrați de detalii tehnice.

Gata, este timpul să vedeți ce sa întâmplat. PIP-uri pe compilarea și lansarea emulării (Ctrl + F7).

Debugging.
Toate tipurile de bare de progres au fugit, studioul sa schimbat și o săgeată galbenă a apărut în apropierea funcției principale. Acesta este locul în care procesorul este în prezent curent și simularea pe pauză.

Faptul este că inițial, de fapt, ea stătea pe rândul Ubrl \u003d Lo (Bauddividorul); La urma urmei, faptul că avem în definit nu este cod, ci pur și simplu calcule preliminare, atunci simulatorul a fixat puțin. Dar acum își dădu seama că prima instrucțiune este finalizată și dacă urci într-un copac Vizualizare I / O, În secțiunea USART și câștigați acolo pe Byte Ubbrl, veți vedea că există deja acolo deja! 0x33.

Face încă un pas. Privind cum se schimbă conținutul unui alt registru. Deci, fuzionați pe toți, acordați atenție faptului că toți biții indicați sunt expuși așa cum am spus și este setat la un moment dat pentru întregul octet. Următoarea întoarcere nu funcționează, programul sa terminat.

Deschidere
Acum resetați simularea în zero. Faceți clic acolo Resetare (Shift + F5). Deschideți lista de dezasamblare, acum veți vedea ce se întâmplă în controlor de fapt. Vizualizare -\u003e dezasamblare. Și nu Yyaaaa !!! Asambl !!! Uzhos !!! DAR TU TREBUIE. Deci, mai târziu, când ceva nu merge bine, nu a îndrăznit la codul și nu a cerut problemelor nenorocite pe forumuri și a urcat imediat în pierdere și a urmărit unde aveți un stand. Nu este nimic teribil acolo.

În primul rând, va fi un top al seriei:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 +00000000: 940C002A JMP 0x0000002A Jump 00000002: 940C0034 JMP 0x00000034 Jump 00000004: 940C0034 JMP 0x00000034 Jump 00000006: 940C0034 JMP 0x00000034 Jump 00000008: 940C0034 JMP 0x00000034 Jump + 0000000A: 940C0034 JMP 0x00000034 Jump + 0000000C: 940C0034 JMP 0x00000034 Jump + 0000000E: 940C0034 JMP 0x00000034 Jump 00000010: 940C0034 JMP 0x00000034 Jump 00000012: 940C0034 JMP 0x00000034 Jump 00000014: 940C0034 JMP 0x00000034 Jump 00000016: 940C0034 JMP 0x00000034 Jump 00000018: 940C0034 JMP 0x00000034 Jump + 0000001A: 940C0034 JMP 0x00000034 Jump + 0000001C : 940C0034 JMP 0x00000034 Jump + 0000001E: 940C0034 JMP 0x00000034 Jump 00000020: 940C0034 JMP 0x00000034 Jump 00000022: 940C0034 JMP 0x00000034 Jump 00000024: 940C0034 JMP 0x00000034 Jump 00000026: 940C0034 JMP 0x00000034 Jump 00000028: 940C0034 JMP 0x00000034 Jump

00000000: 940C002A JMP 0x0000002A Jump 00000002: 940C0034 JMP 0x00000034 Jump 00000004: 940C0034 JMP 0x00000034 Jump 00000006: 940C0034 JMP 0x00000034 Jump 00000008: 940C0034 JMP 0x00000034 Jump + 0000000A: 940C0034 JMP 0x00000034 Jump + 0000000C: 940C0034 JMP 0x00000034 Jump + 0000000E : 940C0034 JMP 0x00000034 Jump 00000010: 940C0034 JMP 0x00000034 Jump 00000012: 940C0034 JMP 0x00000034 Jump 00000014: 940C0034 JMP 0x00000034 Jump 00000016: 940C0034 JMP 0x00000034 Jump 00000018: 940C0034 JMP 0x00000034 Jump + 0000001A: 940C0034 JMP 0x00000034 Jump + 0000001C: 940C0034 JMP 0x00000034 Jump + 0000001E: 940C0034 JMP 0x00000034 Jump 00000020: 940C0034 JMP 0x00000034 Jump 00000022: 940C0034 JMP 0x00000034 Jump 00000024: 940C0034 JMP 0x00000034 Jump 00000026: 940C0034 JMP 0x00000034 Jump 00000028: 940C0034 JMP 0x00000034 Jump

Acesta este tabelul vectorilor de întrerupere. Vom reveni la ea, în timp ce vă vedem și amintiți-vă că este. Prima coloană este adresa flash a blițului în care comanda minciună, al doilea cod de comandă al celei de-a treia echipă mnemonice, aceeași instrucțiune de asamblare, al treilea operand al echipei. Ei bine, un comentariu automat.
Deci, dacă arăți, atunci există tranziții solide. Și codul de comandă JMP este de patru octeți, conține adresa de tranziție înregistrată de Backward - octetul mai tânăr pentru adresa mai mică și codul comenzii de tranziție 940C

0000002B: BE1F Out 0x3F, R1 Out la locația I / O

Înregistrarea acestei adrese zero la 0x3F Dacă vedeți coloana I / O, atunci veți vedea că adresa 0x3F este adresa Registrului Registrului Registrului Sreg - Flag. Acestea. Resetăm SREG pentru a rula programul la condiții zero.

1 2 3 4 + 0000002C: E5CF LDI R28.0x5F Încărcarea imediată + 0000002D: E0D4 LDI R29.0x04 Încărcare imediată + 0000002E: BFDE Out 0x3e, R29 Out to I / O Localizare + 0000002F: BFCD Out 0x3d, R28 Out to I / O Localizare

0000002C: E5CF LDI R28.0x5F Încărcarea imediată + 0000002D: E0D4 LDI R29.0x04 Încărcare imediată + 0000002E: BFDE Out 0x3e, R29 Out to I / O Locul de amplasare + 0000002F: BFCD Out 0x3d, R28 Out to I / O Localizare

Aceasta este încărcarea indicatorului de stivă. Directorul direct în registrele I / O nu pot, numai prin registrul intermediar. Prin urmare, primul LDI în intermediar, și apoi de acolo în I / O. De asemenea, vă voi spune mai multe despre stivă. Între timp, se știe că aceasta este o zonă atât de dinamică de memorie, atârnând la capătul memoriei RAM și păstrează adresele și variabilele intermediare. Acum am arătat unde vom avea un stivă.

00000032: 940C0041 JMP 0x00000041 Salt

Salt la capătul Saaaeaee al programului și acolo avem o intervilă și înclinare strâns de sine:

1 2 +00000041: 94F8 CLI Global Inverrubire Dezactivare +00000042: CFF RJMP PC-0x0000 salt relativ

00000041: 94F8 CLI Global Inverrubire Dezactivare +00000042: CFFF RJMP PC-0x0000 salt relativ

Acest lucru este în cazul unor circumstanțe neprevăzute, cum ar fi ieșirea din funcția principală. De la o astfel de buclă, controlerul poate fi afișat fie cu o resetare hardware, fie este probabil, descărcarea de la câinele de supraveghere - Watchdog. Ei bine, sau, după cum am spus mai sus, corectați aceste locuri în editorul hexagonal și rutarea unde avem un suflet. De asemenea, acordați atenție faptului că există două tipuri de tranziții JMP și RJMP Primul este o tranziție directă la adresa. Este nevoie de patru octeți și poate face o tranziție directă în întreaga zonă de memorie. Al doilea tip de tranziție - RJMP - rudă. Echipa lui are doi octeți, dar tranziția pe care o face din poziția curentă (adrese) cu 1024 pași înainte sau înapoi. Și în parametrii săi, este indicat offset de la punctul curent. Folosit mai des, pentru că Este nevoie de două ori mai puțin spațiu în același timp, iar factorii lungi sunt rareori necesari.

1 +000034: 940C0000 JMP 0x00000000 salt

00000034: 940C0000 JMP 0x00000000 salt

Și acesta este un salt la începutul codului. Reporniți un fel. Puteți verifica, toți vectorii sari aici. Din această ieșire - dacă vă permiteți să permiteți întreruperile (ele sunt interzise în mod implicit) și veți fi întrerupte, dar nu există un handler, atunci va fi o resetare a programului - programul va arunca programul la început.

Functie principala. Totul este similar, chiar nu puteți descrie. Privind doar la registrele deja calculate numărul. Preprocessor compilator taxi !!! Deci, nu numere "magice"!

1 2 3 4 5 6 7 8 9 10 11 12 <

00000036: E383 LDI R24.0x33 Încărcare imediată +000037: B989 out 0x09, R24 Out la I / O Locul 15: Ubrh \u003d Hi (Bauddividiv); +000038: BC10 out 0x20, R1 Out to I / O Locul 16: UCSRA \u003d 0; +000039: B81B Out 0x0b, R1 Out to I / O Locul 17: UCSRB \u003d 1<

Și aici este JAMB:

1 2 3 + 0000003E: E080 LDI R24.0x00 Încărcare imediată + 0000003F: E090 LDI R25.0x00 Încărcare imediată +00000040: 9508 RET Subrutine Return

0000003E: E080 LDI R24.0x00 Încărcare imediată + 0000003F: E090 LDI R25.0x00 Încărcare imediată +00000040: 9508 RET SUBROUTINE RETURN

Se întreabă de ce acest compilator adaugă un astfel de topmaster? Și acest lucru nu este altceva decât întoarce 0, apoi am identificat ca int principal (void). Așa că am câștigat mai mult de patru octeți nu înțeleg ce :) și dacă faceți un vid principal (void), acesta va fi doar RET, dar Varning va fi. Ce spun ei că nu întoarcem nimic la funcția principală. În general, faceți-l ca tine :)

Complicat? Pare să fie nu. Măriți performanța pas cu pas în modul de dezasamblare și în Pokery, deoarece procesorul efectuează instrucțiuni individuale, care se întâmplă cu registrele. Cum să treceți la comenzi și looping final.

Continuarea urmează în câteva zile ...

Offtop:
Alexei78. Gang un plugger de fixare pentru Firefox facilitarea navigării pe site-ul meu și forum.
Discuție și descărcare

Pentru programarea microcontrolere AVR, există o mulțime de instrumente de dezvoltare, cu toate acestea, cele mai populare, fără îndoială, trebuie recunoscut un pachet AVR Studio. . Există o serie de motive pentru o astfel de popularitate - acesta este un pachet gratuit dezvoltat de companie Atml. , Combină editorul de text, asamblarea și simulatorul. Pachetul AVR Studio este, de asemenea, utilizat împreună cu fixarea hardware-ului. În articolul propus, exemplele consideră că tehnicile de lucru cu un pachet, care va ajuta pe programatorii începători să înțeleagă interacțiunea componentelor individuale ale studioului AVR.

În următoarea parte a articolului va fi descrisă despre depanarea în mediul studio AVR al programelor scrise în SI.

Pachetul AVR Studio are o istorie solidă de dezvoltare, care se reflectă în numărul de versiuni existente. La sfârșitul anului 2003, versiunea 4.08 a fost lansată, care are o serie de adăugări utile, iar la începutul anului 2004 a fost lansată o actualizare (Service Pack 1), adăugând suport pentru controlerele AVR ale celei de-a treia generații a ATMEGA48 familie. Producția de jetoane din această familie este programată pentru a doua jumătate a anului 2004.

Pachetul de distribuție și service pack poate fi descărcat de pe www.atmel.com sau obțineți un CD cu această distribuție de la distribuitorul rus al ATMEL.

Activitatea pachetului AVR Studio este revizuită convenabil pe orice program specific. Ca o opinie, vom lua în considerare crearea unui proiect pentru cel mai simplu program, care va fi la rândul său, la lumina a două LED-uri. Pentru claritate, luați un microcircuit ATMEGA128. și conectați cele două LED-uri în concluziile 31 și 32 (acestea sunt biți 6 și 7 din Port D Chip ATMEGA128). Controlere AVR Aveți cascade puternice de ieșire, curentul tipic al fiecărei ieșiri este de 20 mA, curentul maxim de ieșire este de 40 mA, iar acest lucru se referă la ambele curgere și la curentul curgător. În exemplul nostru, LED-urile sunt conectate la anoduri la concluziile controlorului, iar catodele prin rezistențele de stingere sunt conectate la sol. Aceasta înseamnă că LED-ul este aprins prin hrănirea "1" la ieșirea portuară corespunzătoare. Diagrama schematică este prezentată în figură. Diagrama prezintă, de asemenea, cele două butoane care trebuie utilizate într-unul din programe.

Aici este potrivit să faceți o mică digresiune despre alegerea unui tip de cip pentru cel mai simplu exemplu. Într-adevăr, la prima vedere, poate părea ciudat, de ce aveți nevoie de un astfel de cristal puternic într-un caz de 64 de pini, unde există suficient cip cu 8 pini Atiny12. ? Cu toate acestea, în această abordare există logică. Se știe că în inima aproape orice controler AVR se află același kernel. De și mare, controlorii diferă în memorie, numărul de porturi I / O și un set de module periferice. Caracteristicile fiecărui control al controlerului specific / registrele logice obligatorii la adresele fizice, adresele de vectori de întrerupere, identificarea biților portuare etc. Descrie în fișiere cu extensie.inc, care sunt incluse în pachetul AVR Studio. În consecință, folosind un tip specific de cristal, puteți depana programul ca el și pentru orice cristal mai tânăr. Mai mult, dacă utilizați cel mai înalt cristal ca un depanare, astăzi este ATMEGA128, puteți depana un program pentru aproape orice controler AVR, trebuie doar să utilizați resurse hardware care lipsesc din microcontrolerul țintă. Astfel, de exemplu, puteți depana programul care urmează să fie efectuat pe ATMEGA128 Atiny13. . În acest caz, codul sursă va rămâne practic același, numai numele fișierului conectat cu 128def.inc pe tn13def.inc se va schimba. Această abordare are, de asemenea, avantajele sale. De exemplu, pot fi utilizate porturi de I / O suplimentare pentru conectare. Indicatorul LCD. pe care le puteți retrage informații de depanare. Sau, utilizați emulatorul intraemum care se conectează la portul JTAG al cipului ATMEGA128 (controlerul Atticiny13 nu are acest port). Astfel, este posibil să se utilizeze o singură placă de depanare pe care este instalată controlerul AVR "senior", pentru a depana orice sisteme nou dezvoltate, bazate în mod natural pe microcontrolere AVR. Una dintre aceste panouri este numită as-megam. Acesta a fost folosit pentru a crea exemple de programe date în articol. Acesta este un controler universal cu un singur bord bazat pe cipul ATMEGA128, care conține RAM extern, două porturi RS-232. , port pentru conectarea indicatorului LCD, programator intrahemnoe și emulator La gheața JTAG. . Consiliul are, de asemenea, un loc pentru a împărți chipul seriei Flash-ROM AT45. În carcasele TSOP32 / 40/48 și un DAC din două canale AD5302 / AD5312 / AD5322 . Acum, după ce ați explicat cauzele utilizării Monsterului AVR pentru a aprinde o pereche de swattide, puteți merge mai departe.

La programarea în mediul studio AVR, trebuie să efectuați o secvență standard de acțiuni:

  • compilare
  • Crearea de proiect începe cu selecția proiectului \\ noul meniu proiect. În fereastra "Creați nou proiect" care se deschide, trebuie să specificați numele proiectului (în cazul nostru - eșantionul1) și numele fișierului de inițializare. După apăsarea butonului "Următorul", se deschide fereastra Selectați platforma de depanare și dispozitivul, unde este selectată platforma de depanare (simulator sau emulator) și tipul de microcontroler.

    Puteți alege unul dintre emulatorii Intrahehemny oferit, observăm că fiecare emulator are propria listă de microcircuități susținute. Pentru exemplul examinat, alegem ca un simulator AVR platformă Debug și cipul Atmega128. După apăsarea butonului "Finish", ieșirea noastră apare ferestrele de lucru ale pachetului AVR Studio, în timp ce este goală. Urmează fereastra dreaptă pentru a plasa textul sursă al programului. Acest lucru se poate face în două moduri sau se poate apela direct textul direct în fereastra Editor sau să descărcați un fișier existent. Mai jos este textul integral al celui mai simplu program cu comentarii.

    ; Exemplu "Controlul LED"; scrise pentru consiliul de depanare as-megam; Frecvența generatorului de parametri este de 7,37 MHz; LED-urile sunt conectate la concluzii PD6 și PD7 și prin rezistențe - pe un fir comun. ; Conectarea datelor ATMEGA128 Circuit I / O Fișier "M128DEF.INC"; Începutul programului de început :; Prima operație - inițializarea stivei; Dacă acest lucru nu este făcut, adresați-vă o subrutină sau întrerupeți; nu va reveni la controlul înapoi; Pointerul de la capătul stack-ului este setat la ultima adresă a RAM-ului intern - RAMEND LDI R16, scăzut (ramend) out SPL, R16 LDI R16, ridicat (ramend) out SPH, R16; Pentru a controla LED-urile conectate la concluziile PD6 și PD7; Este necesar să se declare aceste concluzii. ; Pentru a face acest lucru, scrieți "1" la biții corespunzători ai Registrului DDRD (DataDirection) LDI R16, (1<<6) | (1<<7) out DDRD,r16 ; основной цикл программы loop: ldi r16,(1<<6) ; светится один светодиод out PORTD,r16 rcall delay ; задержка ldi r16,(1<<7) ; светится второй светодиод out PORTD,r16 rcall delay ; задержка rjmp loop ; повторение цикла; процедура задержки; примерно полсекунды при частоте 7,37 МГц; три пустых вложенных цикла соответственно delay: ldi r16,30 ; 30 delay1: ldi r17,200 ; 200 delay2: ldi r18,200 ; и еще 200 итераций delay3: dec r18 brne delay3 dec r17 brne delay2 dec r16 brne delay1 ret ; возврат в главную программу

    Proiectul poate consta din mai multe fișiere, în timp ce un fișier i se atribuie cea principală. Toate operațiile sunt convenabile pentru a produce folosind butonul de context al mouse-ului. După conectarea fișierului sursă, ferestrele au formularul următor.

    Compilarea proiectului se face prin comanda \\ Project \\ Build sau prin apăsarea butonului F7. Procesul de compilare este afișat în fereastra "Ieșire". Această fereastră poate fi "trage" comanda \\ Vizualizare \\ Ieșire.

    În principiu, am primit deja un fișier de ieșire în format.hex, care poate fi deja încărcat în microcircuit și observați administratorii LED-urilor. Cu toate acestea, scopul articolului este de a arăta întregul ciclu de lucru în mediul studio AVR, astfel încât să mergem la etapa de depanare. Acest lucru este realizat de echipa de depanare \\ Debug \\ Start.

    Acum, setați frecvența frecvenței de cuarț 7,3728 MHz în fereastra "Opțiuni simulator" pentru a măsura cu exactitate timpul de execuție al programului.

    Opțiunile rămase trebuie lăsate neschimbate. Acum puteți efectua un program în modul pas cu pas utilizând mouse-ul sau butonul F11.

    Pachetul AVR Studio conține instrumente puternice pentru vizualizarea și editarea stării registrelor interne și a porturilor I / O ale microcontrolerului de depanare, precum și timpul de execuție a programului. Accesul la ele este realizat prin fereastra "I / O".

    De fapt, cantitatea de informații disponibile prin intermediul pachetului AVR Studio Vizualizarea ferestrelor este atât de mare încât este necesar să utilizați un computer într-o configurație cu două monitoruri pentru a obține un confort maxim.

    Pentru a depana exemplul nostru, pentru a accesa porturile D Bits, trebuie să dezvăluiți șirul ATMEGA228 I / O și apoi linia PORTD. Acum toate cele trei registre ale acestui port, portd, ddrd și pind sunt vizibile. Pentru a vedea câmpurile de valoare, biți și adresă, va trebui să extindeți marginea dreaptă a ferestrei, transpirând fereastra cu textul sursă al programului.

    Acum, trecerea programului în modul pas cu pas, puteți vedea schimbarea stărilor actuale ale acestor registre în câmpul BITS. Este posibil să schimbați rapid starea oricărui bit al registrelor portuare și acest lucru se poate face fie prin scrierea unui nou cod în câmpul Value sau direct făcând clic pe bitul dorit al registrului.

    Pentru exerciții independente, se propune următorul program, care diferă de cea precedentă că contactul LED-urilor este controlat de două butoane.

    ; Exemplu "Controlul LED-urilor din butoane"; scrise pentru consiliul de depanare as-megam; LED-urile sunt conectate la concluzii PD6 și PD7 și prin rezistențe - pe un fir comun. ; Butoane - pe PE4 și PE5. Include "M128DEF.INC"; Începeți programul principal:; Inițializarea stivei LDI R16, scăzută (ramend) out SPL, R16 LDI R16, ridicat (ramend) out SPH, R16; Inițializarea LED-urilor R16, (1<<6) | (1<<7) out DDRD,r16 ; инициализация выводов, к которым подключены кнопки (на вход) ; внутренние подтягивающие резисторы подключены; для этого в PORTE нужно установить соответствующие биты в единицы ldi r16,(1<<4) | (1<<5) out PORTE,r16 ; а в DDRE - в нули ldi r16,0 out DDRE,r16 ; бесконечный цикл forever: in r16,PINE ; теперь в r16 находится текущее "состояние" кнопок com r16 ; кнопка "нажимается" нулем, поэтому инвертируем регистр lsl r16 ; переносим биты 4,5 в позиции 6,7 lsl r16 ; и обновляем "показания" светодиодов andi r16,(1<<6) | (1<<7) out PORTD,r16 rjmp forever ; цикл выполняется бесконечно

    Astfel, pe exemplul celor mai simple programe, sunt prezentate unele caracteristici ale pachetului AVR studio. Este necesar să înțelegem că aceasta este doar prima cunoaștere care vă permite să vă utilizați rapid cu comenzile pachetului de bază. Între timp, capabilitățile pachetului luate în considerare sunt mult mai largi. De exemplu, aici puteți depana programe scrise în limbi de nivel înalt. În special, compilatorul C-Compircraft al companiei utilizează Debuggerul AVR Studio "ca nativ". Pentru a face acest lucru, atunci când compilați codul sursă, trebuie să setați opțiunea de generare a fișierelor de ieșire într-un format compatibil cu AVR Studio. În același timp, este posibilă depanarea în codurile sursă.

    Un alt dintre numeroasele caracteristici ale pachetului AVR Studio este abilitatea de a conecta programele externe. De exemplu, pentru a vă asigura că programul de inspecție AS2 este necesar pentru a efectua mai multe operații simple.

    În meniul Instrumente al ferestrei principale AVR Studio, trebuie să selectați Personalizare;

    În fereastra Personalizare, selectați elementul Instrumente;

    Dublu clic pe butonul mouse-ului sau apăsând Inserare pe tastatură, adăugați o nouă comandă în listă și o apelați "AS2 programator";

    Specificați calea către fișierul executabil programator introducând direct în câmpul de introducere "Command" sau făcând clic pe butonul "..." din partea dreaptă a acestui câmp;

    Acum apare meniul Instrumente "programator as2".

    AVR STUDIO 4.08 Pachetul înseamnă să conectați programe auxiliare - pluginuri. Primul plugin pentru AVR Studio este un program de editor grafic care simplifică procesul de inițializare a indicatorului LCD, care poate gestiona direct controlerul AVR ATMEGA169. Dimensiunea logică maximă a indicatorului LCD este de 100 de segmente, fiecare element al indicatorului este realizat în conformitate cu bitul în registrul special al controlerului. Pentru a simplifica procedura de legare de rutină pentru anumiți biți la fiecare segment, puteți utiliza programul menționat mai sus.

    În timp ce vizitează "patria AVR" - biroul norvegian al Atmel, unul dintre autorii articolului a vorbit cu Lars Quener, șeful Grupului Programmer, care a creat și suportă pachetul AVR Studio. Această persoană, un programator clasic, cu o barbă, într-un pulover și țesute în sandalele de șosete, a vorbit despre perspectivele dezvoltării pachetului. În următoarea versiune (4.09), interfața va fi activată pentru un nou emulator intrahemnoe - JTAGICE MKII (este numit și la JTagice2), care în a doua jumătate a anului va înlocui la JTAGICE. Acest emulator are două diferențe esențiale. Pe de o parte, suportul susținut pentru o nouă interfață de depanare cu un singur fir pentru controlorii tineri AVR, Debugwire. Această interfață este interesantă deoarece nu ocupă o concluzie suplimentară a microcontrolerului pentru munca sa, deoarece utilizează pentru a schimba ieșirea microcontrolerului de resetare! Pe de altă parte (puteți înțelege această expresie literalmente), la AT JTAGICE2 va apărea, în cele din urmă, interfața USB pentru a comunica cu computerul.

    Literatură

    1. AVR Formarea tehnică Materiale tehnice. Atmel. Norvegia. Deceptber 2003.
    2. Nikolay Korolev, Dmitry Korolev AVR-microcontrolere ale celei de-a doua generații: Mediul dezvoltatorului. // componente și tehnologii, 2003 nr. 7
    3. AVR-microcontrolere din a doua generație: noi capabilități hardware // componente și tehnologii. 2003. Nr. 4.
    4. Nikolay Korolev, Dmitri Korolev. Microcontrolere AVR: Mare în mici. // schemă ", 2001, №5
    5. Nikolay Korolev, Dmitri Korolev. Microcontrolere AVR: Software // Componente și tehnologii, 2000. Nr. 4.
    6. Nikolay Korolev. AVR: Dezvoltator Hardware // Componente și tehnologii, 1999 № 1
    7. Nikolay Korolev. ATMEL RISC-Microcontrolere // Chip-News 1998, №2
    8. Nikolay Korolev, Dmitry Korolev AVR: RISC-microcontrolere noi pe 8 biți ale companiei ATMEL // Microprocessor Review, 1998, №1

    Cumva a tras imediat pentru a oferi sfaturi cu privire la alegerea mediului de programare pentru controlorii AVR. Doar nu aruncați pe adidași. Sunt destul de puțin

    Programarea limbii pentru microcontrolere foarte mult. Mass-media de programare nu este, de asemenea, suficient și în comparație cu acestea incorect. Nu există limbi mai bune de programare. Deci, trebuie să alegeți limba cea mai potrivită pentru dvs. și mediul de programare.

    Dacă vă aflați în prezent, stați în fața selecției, despre ce să începeți să lucrați, iată câteva recomandări.

    Fosta experiență de programare. Nu neglija fosta experiență în programare. Chiar dacă era un Baisik. Chiar dacă a fost o lungă perioadă de timp în școală. Programarea ca o plimbare cu bicicleta - trebuie doar sa incepeti si amintiti rapid totul uitat. Începeți cu Beysika - neplăcut - mai târziu va fi mai ușor să alegeți ceva mai potrivit pentru scopurile dvs.

    Ajutați mediul.Prietenii tăi scriu pe Pascal? Pentru dvs., o întrebare este rezolvată - scrieți pe Pascal! Veți ajuta întotdeauna la Consiliu, bibliotecile vor fi aruncate în biblioteci, vor oferi proiecte gata făcute. În general, fericit va fi dus în comunitatea lor. Dacă faceți dimpotrivă, obțineți rezultatul opus. Surchii de prieteni vă vor distra pe voi, care au decis să studieze asamblorul. Nu așteptați ajutor.

    Bună carte de programare AVR Va ajuta foarte bine. Din păcate, există foarte puține dintre ele. Dacă tu în mâinile tale au primit o carte și crezi că totul este foarte disponibil în ea. - Încearcă. Nu sfătuiesc să înveți prin e-cărți, ca o ultimă soluție, tipăriți. Foarte incomod pentru a comuta între mediul înconjurător și textul fișierului de fișier. Mult mai plăcut Citește cartea imediat încercați fără a fi distrasă prin comutare, în plus, puteți face o marcă pe câmpuri, scrieți ideile care au apărut.

    Programarea mediului mai simplu. Dacă există o gamă de programe de programare a limbii dvs. - nu vă îndoiesc, alegeți cea mai ușoară. Lăsați-o să fie mai puțin funcțională. Lăsați-o să compileze codul înfricoșător. Principalul lucru este să începeți să lucrați. După ce sunteți înclinat într-un mediu simplu, veți merge cu ușurință la un mediu mai avansat și mai drept ". Și nu ascultați pe cei care spun că veți pierde mai mult timp - ei sunt în neregulă. Elevii claselor junior nu sunt rugate să citească "războiul și pacea" pe care le dau cărți mai ușor - cu imagini.

    Biblioteci. Prezența bibliotecilor este controversată pentru a învăța limba. Desigur, mai târziu, ei vor facilita foarte mult viața, dar la început "cutii negre" sunt de neînțeles și nu ajută foarte mult de înțelegerea limbii. Pe de altă parte, aceasta facilitează citirea programului și permiteți unui nou venit, nu deosebit de întins, să construiască programe complexe. Deci, prezența lor nu este în mod deosebit plictisită. Cel puțin la început.

    Cod eficient. Selectarea mediului de programare pentru a studia programarea numai de cât de eficientă a codului compilării este o idee proastă. În principal, începeți confortabil învățarea - că cel de-al zecelea lucru este "la ieșire". Desigur, puteți lucra mai târziu la el.

    Vizard.Orice dispozitiv la bord a cristalului trebuie să fie configurat utilizând porturile. Procedura este destul de viguroasă și sunt necesare foi de date. În plus, există nuanțe în care noul venit nu este doar de oferit. Prin urmare, în mediul este foarte de dorit pentru prezența unor vizoane. Comunicatele sunt automate SPI, I2C, USART etc. Ajustări automate. Cele mai multe dispozitive sunt acceptate, cu atât mai bine. Expuneți parametrii periferici necesari, iar Visard-ul în sine generează un cod care va furniza parametrii specificați. Foarte simplifică viața.


    Recomandări generale O astfel de programare la etapa inițială ar trebui să fie cât mai simplă (chiar dacă primitiv). Mediul de programare ar trebui să fie ușor de învățat (după cum aveți nevoie, să învățați programarea și să nu pierdeți timpul pe alegerea în setări). Este recomandabil ca rusificarea. De asemenea, nu împiedică manualul rus și exemple de programe. Este de dorit posibilitatea firmware-ului cristalului din mediu. Apoi, atunci când părăsiți elementele de bază ale programului, puteți să vă deplasați pe scoici mai complexe.


    O altă recomandare, în cele din urmă, lucrați cu un adevărat cristal. Nu vă fie frică să o ardeți. Îmbunătățiți experiența practică. Lucrul cu emulatori (de exemplu, Proteus), deși va elibera de fierul de lipit, dar nu va putea niciodată să dea satisfacția că veți primi de la programul câștigat, primele cani de LED! Înțelegerea a ceea ce ați făcut cu propriile mâini Circuitul real de lucru va instija încrederea și stimularea continuă!

    (A vizitat 7 377 de ori, 1 vizite astăzi)

    Conceptul programatorului de pe portul LPT este prezentat în figură. Ca anvelopă anvelopă, utilizați chipul 74AC 244 sau 74HC244 (K1564AP5), 74LS244 (K5555AP5) sau 74als244 (K1533AP5).

    LED-ul VD1 indică un mod de înregistrare a microcontrolerului,

    vD2 LED - Citirea,

    vD3 LED - prezența unei diagrame.

    Tensiunea necesară pentru alimentarea schemei ia de la conectorul ISP, adică. de la dispozitivul programabil. Această schemă este un programator reciclat STK200 / 300 (LED-uri adăugate pentru o operare ușoară), deci este compatibil cu toate programele de programare PC care operează cu schema STK200 / 300. Pentru a lucra cu acest programator, utilizați un program Cvavr.

    Programatorul poate fi efectuat pe placa de circuit imprimat și plasați-o în carcasa conectorului LPT, așa cum se arată în imagini:




    Pentru a lucra cu programatorul, este convenabil să utilizați extensia LPT a portului, care este ușor de făcut (de exemplu, de la cablul Cableronix pentru imprimantă), principalul lucru este "să nu regretați" conductorii pentru Pământ (18-25 picioare ale conectorului) sau cumpărați. Cablul dintre programator și microcircuitul programabil nu trebuie să depășească 20-30 cm.

    Bună ziua, dragi hrabeți!

    În acest articol, vreau să spun despre modul în care într-o zi am decis să încep să programez microcontrolerele, ceea ce a fost necesar pentru acest lucru și că în cele din urmă sa dovedit.

    Subiectul microcontrolerelor mi-a interesat de mult timp, anul în 2001. Dar apoi pentru a obține programatorul la locul de reședință a fost problematic și nu a existat nicio achiziție pe Internet și vorbire. A trebuit să amâne acest caz până la cele mai bune momente. Și așa, într-o zi am descoperit că cele mai bune momente au venit fără a părăsi casa, puteți cumpăra tot ce aveam nevoie. Am decis să încerc. Deci, ce avem nevoie:

    1. Programator
    Există multe opțiuni pe piață - de la cele mai ieftine programatori ISP (programare în sistem) pentru mai mulți dolari, pentru programatori puternici de depanare pentru câteva sute. Fără o experiență mai mare în această chestiune, mai întâi am decis să încerc una dintre cele mai ușoare și mai ieftine - USBASP. Am cumpărat la un moment dat pe eBay pentru 12 dolari, acum puteți găsi chiar și pentru $ 3-4. De fapt, aceasta este versiunea chineză a programatorului de la Thomas Fischl. Ce pot să spun despre el? Doar un singur lucru - funcționează. În plus, există o mulțime de controlori AVR ai seriei Atmega și Atusiny. Sub Linux nu necesită un driver.

    Pentru firmware, trebuie să conectați ieșirile VCC, GND, RESET, SCK, MOSI, MISO, cu ieșirile de microcontroler corespunzătoare. Pentru simplitate, am colectat schema auxiliară chiar pe bărbat:

    Stânga pe tablă - același microcontroler, pe care îl vom aprinde.

    2. Microcontroler
    Odată cu alegerea unui microcontroler, nu m-am deranjat în mod deosebit și am luat atmega8 de la ATMEL - 23 I / O Pin, două cronometre pe 8 biți, o frecvență pe 16 biți, o frecvență de până la 16 MHz, consum mic (1-3,6 mA) , ieftin ($ 2). În general, pentru un început - mai mult decât suficient.

    Sub Linux Pentru a compila și descărca firmware-ul de pe controler, pachetul AVR-GCC + AVRDEDE funcționează perfect. Instalare trivial. Urmând instrucțiunile, puteți instala tot ce aveți nevoie în câteva minute. Singurele Neans, care trebuie plătite - AvDude (software pentru înregistrare pe controler) pot necesita un drept de utilizator super de accesul programatorului. Ieșiți - treceți prin sudo (nu o idee foarte bună) sau înregistrați drepturi speciale UDEV. Sintaxa poate fi diferită în diferite versiuni ale sistemului de operare, dar în cazul meu (Linux Monet 15) a fost realizată prin adăugarea următoarei reguli către fișierul /etc/udev/rules.d/41-ATMEGA.RLEES:

    # Subsistemul programatorului USBASP \u003d\u003d "USB", Attr (Idvendor) \u003d\u003d "16c0", Attr (IDPRODUCT) \u003d\u003d "05DC", grup \u003d "Plugdev", Mod \u003d "0666"

    După aceea, în mod natural, este nevoie de o repornire a serviciului.
    Service Udev Repornește
    Puteți compila și clipește fără probleme direct de la linia de comandă (care se va îndoi), dar dacă există multe proiecte, este mai convenabil să puneți pluginul și să faceți totul direct din mediul eclipse.

    Sub Windows va trebui să livreze șoferul. Nu există probleme în restul. Pentru interes științific, am încercat pachetul AVR Studio + Extreme Burner în Windows. Din nou, totul funcționează cu un bang.

    Începem programarea

    Programarea controlorilor AVR poate fi atât pe asamblator (AVR Assembler), cât și pe C. Aici, cred că toată lumea trebuie să-și facă alegerea, în funcție de sarcina specifică și de preferințele sale. Personal, am început să colecteze asamblarea. La programarea pe asamblare, arhitectura dispozitivului devine mai clară și aparent că se sapa direct în interiorul controlerului. În plus, cred că, în programe deosebit de critice, cunoașterea asamblorului poate fi foarte utilă. După familiarizarea cu AVR Assembler, voi schimba pe Si.

    După cunoștință cu arhitectura și principiile de bază, am decis să colectez ceva util și interesant. Fiica mea ma ajutat, făcea șah și o seară frumoasă a declarat că vrea să aibă un ceas de cronometru pentru loturi pentru o vreme. Batz! Aici este - ideea primului proiect! A fost posibil să le ordonați pe același eBay, dar am vrut să vă fac propriul ceas, cu negru ... cu indicatori și butoane. Făcut repede și foarte bine!

    Ca afișaj, sa decis utilizarea a două indicatoare diode cu 7 segmente. Pentru a controla a fost suficientă 5 butoane - "Player 1", "Player 2", "Resetare", "Setare" și "Pauză". Ei bine, nu uitați de indicarea sunetului jocului. Arata ca asta e. Figura de mai jos prezintă diagrama generală de conectare a microcontrolerului la indicatoare și butoane. Ea va avea nevoie când parsarea codului sursă al programului:

    Colorarea zborului.

    Să începem, așa cum ar trebui să fie, din punctul de intrare al programului - principalele funcții. De fapt, nimic remarcabil în el nu este - configurarea de porturi, inițializarea datelor și un buton infinit de apăsare a butoanelor. Ei bine, apelul SEI () este rezolvarea prelucrării întreruperilor, despre ele puțin mai târziu.

    Int principal (void) (init_io (); init_data (); sunet_off (); Sei (); în timp ce (1) (gâscă_buttons ();) retur 0;)
    Luați în considerare fiecare funcție separat.

    VOID INIT_IO () (// setare de ieșire ddrb \u003d 0xff; ddrd \u003d 0xff; // setare intrare ddrc \u003d 0B11100000; // rezistențe de pull-up PORTC | \u003d 0B00011111; // Timer întrerupe Timsk \u003d (1<

    Setarea porturilor I / O este foarte simplă - în registrul DDRX (unde X este litera, denotând portul) numărul, fiecare dintre acestea înseamnă dacă PIN-ul corespunzător va fi dispozitivul de intrare (corespunde la 0) sau ieșirea (corespunde la 1). Astfel, seasushal în DDRB și DDRD numărul 0xff, am făcut porturile de ieșire B și D. În consecință, comanda DDRC \u003d 0B11100000; transformă primele 5 porturi ale portului C în știfturile de intrare și rămânând în weekend. Echipa PORTC | \u003d 0B00011111; Include rezistoare interne de strângere pe 5 intrări ale controlerului. Conform schemei, butoanele sunt conectate la aceste intrări, care, atunci când sunt presate sunt închise pe pământ. Astfel, controlerul înțelege că butonul este apăsat.

    Apoi, urmați setarea a două cronometre, Timer0 și Timer1. Folosim primul care să actualizeze indicatorii, iar al doilea - pentru numărătoarea inversă a timpului, după ce a stabilit-o la declanșarea în fiecare secundă. O descriere detaliată a tuturor constantelor și a metodei de setare a temporizatorului la un anumit interval poate fi găsită în documentația pentru ATMEGA8.

    Întreruperea procesului

    ISR (afișaj (); dacă (_buzzer\u003e 0) (_buzer--; dacă (_buzger \u003d\u003d 0) sunet_off ();)) ISR (timer1_compa_vect) (dacă (ActiveTimer \u003d\u003d 1 && Timer1\u003e 0) (Timer1--- ; dacă (Timer1 \u003d\u003d 0) proces_timeoff ();) dacă (ActiveTimer \u003d\u003d 2 && timer2\u003e 0) (Timer2--; dacă (Timer2 \u003d\u003d 0) Process_TimeOff ();))

    Când cronometrul este declanșat, controlul este transmis la manipulatorul de întrerupere corespunzător. În cazul nostru, acesta este procesorul Timer0_OVF_VECT, care determină procedura de ieșire a timpului la indicatoare și Timer1_compa_vect, care procesează numărătoarea inversă.

    Concluzie la indicatori

    VOID Afișaj () (Display_number ((Timer1 / 60) / 10, 0B00001000); _delay_ms (0,25); Display_number ((Timer1 / 60)% 10, 0B00000100); _delay_ms (0,25); Display_number (((Timer1 60) / 10, 0B00000010); _delay_ms (0,25); display_number ((Timer1% 60)% 10, 0B00000001); _delay_ms (0,25); display_number ((Timer2 / 60) / 10, 0B10000000); _delay_ms (0,25); Display_number ((Timer2 / 60)% 10, 0B01000000); _delay_ms (0,25); display_number ((Timer2% 60) / 10, 0B00100000); _delay_ms (0,25); display_number (((Timer2% 60)% 10, 0B00010000); _delay_ms (0.25) ; PORTD \u003d 0;) VOID Display_Number (int Număr, INT Mask) (PORTB \u003d număr_mask (număr); portdd \u003d mască;)

    Funcția de afișare utilizează o metodă de indicare dinamică. Faptul este că fiecare indicator individual are 9 contacte (7 pentru controlul segmentelor, 1 pentru punctul și 1 pentru sursa de alimentare). Pentru a controla 4 cifre, ar lua 36 de contacte. Prea risipitor. Prin urmare, rezultatul de evacuări la un indicator multi-cifre este organizat în conformitate cu următorul principiu:

    Tensiunea este alimentată alternativ la fiecare dintre contactele partajate, care vă permite să evidențiați figura dorită în indicatorul corespunzător utilizând aceleași contacte de control. Cu o frecvență de ieșire suficient de mare, arată ca o imagine statică. Acesta este motivul pentru care toate cele 8 contacte de alimentare ale ambelor indicatori de pe diagramă sunt conectate la 8 porturi de port d și 16 segmente de comandă de contact sunt conectate în perechi și conectate la 8 porturi de port B. Astfel, funcția de afișare cu o întârziere de 0,25 MS Afișează alternativ numărul dorit pentru fiecare dintre indicatori. Sub final, toate ieșirile care alimentează tensiunea pe indicatoare sunt oprite (comanda PORTDD \u003d 0;). Dacă acest lucru nu este făcut, ultima cifră de afișare va continua să ardă până când următorul apel este numit funcția de afișare, ceea ce va duce la luminescența mai luminoasă în comparație cu restul.

    Tratamentul preselor

    VIOD GALER_BUTTONS () (HEALT_BUTTON (KEY_SETUP); GALE_BUTTON (KEY_RESET); GALE_BUTTON (KEY_PAUSE); GALE_BUTTON (Key_Player1); Gale_button (key_player2); \u003d Setup_bit; pauză; caz cheie_reset: bit \u003d reset_bit; pauză; caz cheie_pause: bit \u003d pause_bit; break; caz cheie_player1: bit \u003d player1_bit2: bit \u003d player2_bit; Break; Implicit: Returnar (Bit_is_Clear Button_pin, biți) (dacă (_presed \u003d\u003d 0) (_delay_ms (debounce_time); dacă (bit_is_clear (button_pin, bit)) (_presed | \u003d tasta; // cheie comutator de acțiune (key_setup: proces_setup (); rupere; caz) : PROCES_RESET (); pauză; pauză cheie: PROCESS_PAUSE (); pauză; caz cheie key_player1: proces_player1 (); pauză; caz cheie key_player2: proces_player2 (); pauză;))) altceva (15);))) ;))

    Această caracteristică la rândul său, toate cele 5 butoane și procese presă, dacă sa întâmplat așa. Apăsarea este înregistrată de bifarea Bit_is_Clear (button_pin, biți), adică Butonul este apăsat dacă intrarea corespunzătoare acestuia este conectată la sol, care se va întâmpla în conformitate cu schema, când apăsați butonul. Întârzierea întârziată Duratația_time și re-verificarea este necesară pentru a evita mai multe răspunsuri inutile datorită zgomotului de contacte. Salvarea starea de presă în biții variabili corespunzători este utilizată pentru a elimina re-declanșarea cu un buton de presare lungă.
    Funcțiile de presare sunt destul de triviale și cred că în comentariile suplimentare nu au nevoie.

    Programul de text complet

    #Define f_cpu 4000000L #include #Include. #Include. #define debunce_time 20 #define button_pin Pinc #define setup_bit PC0 #define pause_bit PC2 #define player1_bit PC3 #Define player2_setup 0B00000001 #define key_pasase 0B00000100 #define key_player1 0B00001000 #define key_player2 0B00010000 Volatile Int ActiveTimer \u003d 0; Volatile Int Timer1 \u003d 0; Volatile INT TIMER2 \u003d 0; volatile int _buzzer \u003d 0; Volatile int _presed \u003d 0; // declarații de funcționare VOID INIT_IO (); Void init_data (); Int numere_mask (int num); vid haller_buttons (); vid gale_button (int cheie); VOID PROCESS_SETUP (); VOID PROCESS_RESET (); vid proces_pause (); vid proces_timeoff (); VOID PROCESS_PLAYER1 (); VOID PROCESS_PLAYER2 (); afișaj vid (); VOID Display_Number (int masca, int Numar); Void Sound_on (intervalul INT); VOID SOUND_OFF (); // întrerupe ISR (afișaj (); dacă (_buzger\u003e 0) (_buzzer--; dacă (_buzger \u003d\u003d 0) sunet_off ();)) ISR (Timer1_compa_vect) (dacă (ActiveTimer \u003d\u003d 1 && timer1\u003e 0) ( Timer1 - dacă (Timer1 \u003d\u003d 0) Process_TimeOff ();) dacă (ActiveTimer \u003d\u003d 2 && Timer2\u003e 0) (Timer2--; dacă (Timer2 \u003d\u003d 0) Process_TimeOff ();)) int Main (VOD) (init_io (); init_data (); sunet_off (); SEI (); în timp ce (1) (mâner_buttons ();) retur 0;) vid_io (// set ddrb \u003d 0xff; ddrd \u003d 0xFF; // Intrare DDRC \u003d 0B11100000; // Rezistori de ridicare PORTC | \u003d 0B00011111; // Timer întrerupe Timsk \u003d (1< 5940 ||. Timer2\u003e 5940) (Timer1 \u003d 0; Timer2 \u003d 0)) VOID PROCESS_RESET (INIT_DATA ();) VOID PROCESS_TIMEOFF () (INIT_DATA (); Sound_on (30);) VOID PROCESS_PAUSE (ActiveTimer \u003d 0;) VOID PROCESS_PLAYER1 () (ActiveTimer \u003d 2;) () (Active) (ActiveTimer \u003d 1;) (ActiveTimer \u003d 1;) (ActiveTimer \u003d 1;) (ActiveTimer \u003d 1;) (Tasta KeyStUp_Bit; Bird; CASE KEY_RESET: Bit \u003d resetare_bit; Break; CASE KEY_PAUSE: bit \u003d pause_bit; Break; CASE KEY_PLAYER1: Bit \u003d Player1_Bit; Break; Case Key_Player2: Bit \u003d Player2_bit; Break; Implicit: Return;) Dacă (But_pin, Bit)) (dacă (_Presed \u003d\u003d 0) (dacă (_Presed \u003d\u003d 0) _delay_ms (debunce_time); dacă (bit_is_clear (buton_pin, bit)) (_presed | \u003d tasta; // key_setup: proces_setup (); pauză; caz cheie_reset: proces_reset (); pauză; caz cheie_pause (); pauză; caz cheie_player1 : proces_player1 (); pauză; caz cheie key_player2: proces_player2 (); rupt;) SOUND_ON (15);))) altceva (_pre SSD & ~ cheie; ))) Vid haller_buttons () (gheață_button (key_setup); gheață_button (key_reset); gheață_button (key_pauze); gheață_button (key_player1); gheață_button (key_player2); () (afișaj_number ((Timer1 / 60) / 10, 0B00001000) ; _delay_ms (0,25); display_number ((Timer1 / 60)% 10, 0B00000100); _delay_ms (0,25); display_number ((Timer1% 60) / 10, 0B00000010); _delay_ms (0.25); Display_number (((Timer1% 60) % 10, 0B00000001); _delay_ms (0,25); display_number ((Timer2 / 60) / 10, 0B10000000); _delay_ms (0,25); Display_number ((Timer2 / 60)% 10, 0B01000000); _delay_ms (0.25); display_number (( Timer2% 60) / 10, 0B00100000); _delay_ms (0,25); display_number (((Timer2% 60)% 10, 0B00010000); _delay_ms (0,25); PORTDD \u003d 0;) VOID Display_number (int numere_mask) (PORTB \u003d Number_Mask ( Număr); portd \u003d mască;) vid sold_on (int interval) (_buzzer \u003d interval; // pus buzzer pin high portc | \u003d 0b00100000;) vid sold_off (// pune buzzer pin low PORTC & ~ 0B00100000;)

    Prototipul a fost asamblat pe o placă de dumping.