Redoslijed programiranja mikrokontrolera avr. avr programiranje mikrokontrolera

Dobar dan dragi radio amateri!
Želim vam dobrodošlicu na stranicu ""

Šta je mikrokontroler i zašto je potreban. Pogledajmo njegovu definiciju:

- mikrokolo dizajnirano za upravljanje elektroničkim uređajima, ili na drugi način - jednostavno računalo (mikro-računalo) sposobno za obavljanje jednostavnih zadataka.

Naime, mikrokontroler je uređaj koji nam omogućava da realizujemo svoje ideje (čak i one sulude), ali, naravno, u okviru svojih mogućnosti. I što je najvažnije, realizacija ideje se ne postiže stvaranjem sofisticiranih elektronskih struktura, već samo, u osnovi, snagom naše misli (da li biste željeli postati čarobnjak?).
Najpopularnije među radio-amaterima su dvije vrste mikrokontrolera:
PIC- Microchip Technology
AVR- od Atmela

Želio bih da napravim kratku digresiju i razjasnim jedan od svojih stavova. Neću raspravljati o prednostima ovog ili onog tipa mikrokontrolera, ovog ili onog softvera, i općenito svega što se tiče mikrokontrolera, da bih nešto savjetovao, a još više, nametnuo čitaocima. Sve je stvar ukusa, ličnih preferencija i vaših krajnjih ciljeva u učenju mikrokontrolera. Pa, pošto se „neizmernost ne može obuhvatiti“, sve svoje dalje pripovedanje ću voditi u vezi sa AVR mikrokontrolerima i, ne baš uobičajenim, ali meni omiljenim, programom „Algoritam Builder“. Različiti tipovi mikrokontrolera, programa, naravno, imaju razlike, ali imaju i mnogo zajedničkog. A mi ćemo naučiti svijet mikrokontrolera na način da se kasnije stečeno znanje može bez problema primijeniti na PIC-ove i bilo koji softver. I da vas još jednom podsjetim da je ova serija članaka moj pokušaj da pomognem onima koji su prvi čuli za postojanje mikrokontrolera i žele razumjeti kako s njima raditi.

Šta vam je potrebno da naučite kako raditi s mikrokontrolerima? Izdvojio bih nekoliko, po mom mišljenju, glavnih uslova:
1. Želja i upornost .
Ovdje je sve vrlo jednostavno: postoji želja - sve će uspjeti. A želja sa istrajnošću je, generalno, super stvar.
2. Poznavanje uređaja mikrokontrolera.
Duboko poznavanje ovde nije važno (a možda i nije potrebno), ali je neophodno znati šta je „na ploči“ mikrokontrolera. Samo znajući od čega se sastoji mikrokontroler, koje uređaje ima, njihove mogućnosti, kako funkcionišu - tek tada ćemo moći da iskoristimo mogućnosti mikrokontrolera u potpunosti.
3. Poznavanje programskog jezika i upravljačkih komandi mikrokontrolera.
Kako će mikrokontroler raditi, koje zadatke mu dodjeljujete i kako će ih obavljati, određuje program koji je u njega ugrađen - program koji sami sastavite za mikrokontroler. I mi ćemo se zadržati na ovoj tački detaljnije kako bismo razmotrili pitanja koja se mogu pojaviti u budućnosti.

Program(u prijevodu ova riječ znači "recept") - preliminarni opis nadolazećih događaja ili radnji.

Na primjer, želimo da mikrokontroler treperi LED diodom. Jednostavan zadatak, ali ipak, da bi mikrokontroler izvršio ovaj zadatak, prvo moramo, korak po korak, opisati sve radnje mikrokontrolera, napisati program koji mora izvršiti da bi dobio rezultat koji nam je potreban - trepćuće LED . Ovako nešto:
♦ Upalite LED:
- konfigurirati izlaz na koji je LED spojena da radi na izlazu informacija
- primenite logički nivo na ovaj pin, koji će vam omogućiti da upalite LED
♦ Pričekajte malo:
- idite na potprogram koji formira pauzu (koju takođe treba "prožvakati")
- po završetku potprograma pauze, vratite se na glavni program
♦ Isključite LED:
- primijeniti logičku razinu na izlaz, gaseći LED
itd.
sa terminom Program drugi pojam je neraskidivo vezan - Algoritam(kao Vuk i Zec, Tom i Džeri).

Algoritam- set uputstava koja opisuju postupak za postizanje željenog rezultata.

Ako smo u programu na najdetaljniji način propisati radnje mikrokontroler, zatim u algoritmu we odrediti tok akcije mikrokontroler, na osnovu kojeg ćemo kreirati program. Slično kao u gornjem primjeru:
♦ Upalite LED
♦ Pričekajte malo
♦ Isključite LED
itd.
dakle, algoritam je preteča programa. I što se pažljivije i promišljenije kreira algoritam, lakše će biti kreirati program.

Sveukupno, program za mikrokontroler je niz radnji mikrokontrolera u obliku skupa naredbi i instrukcija koje mora izvršiti da bi postigao naše ciljeve.

Komande za mikrokontroler izgledaju kao skup jedinica i nula:
00110101 011000100
takozvani - komandni kodovi, a komandni kodovi su jezik koji mikrokontroler razumije. A da bismo preveli naš algoritam sa ruskog na jezik mikrokontrolera - u ove skupove nula i jedinica, postoje posebni programi.
Ovi programi nam omogućavaju da opišemo redosled rada mikrokontrolera na jeziku koji nam je manje-više razumljiv, a zatim taj redosled prevedemo na jezik razumljiv mikrokontroleru, što rezultira tzv. mašinski kod- niz naredbi i instrukcija (samih nula i jedinica) koje samo mikrokontroler razumije. Poziva se tekst programa koji je napisao programer izvorni kod. Program je preveden iz programskog jezika (izvorni kod) u jezik mikrokontrolera (mašinski kod) prevodioci. Prevoditelj pretvara tekst programa u mašinske kodove, koji se zatim upisuju u memoriju mikrokontrolera.
U takvim programima redoslijed rada mikrokontrolera opisuje se posebnim jezikom - programskim jezikom. Programski jezik se razlikuje od našeg ljudskog jezika. Ako je naš jezik komunikacije prvenstveno za razmjenu informacija, onda:

Programski jezik - ovo je način prenošenja komandi, instrukcija, jasan vodič za akciju za mikrokontroler.

Postoji mnogo programskih jezika i mogu se podijeliti u dvije vrste:
programski jezici niskog nivoa
programski jezici visokog nivoa
Koja je razlika. I razlikuju se po njihovoj blizini mikrokontrolera.
U zoru nastanka mikroprocesorske tehnologije, programi su pisani u mašinskim kodovima, odnosno čitav algoritam rada je sekvencijalno pisan u obliku nula i jedinica. Ovako je izgledao program:

01000110
10010011
01010010

Malo je vjerovatno da će itko moći shvatiti takav skup kombinacija dva broja, a rad prvih programera bio je vrlo naporan. Kako bi sebi olakšali život, programeri su počeli stvarati prve programske jezike. Dakle, što je programski jezik bliži takvom skupu nula i jedinica, to je više „niskog nivoa“, a što je dalje od njih, to je „visoki nivo“.
Najčešći programski jezici za mikrokontrolere:
- jezik niskog nivoa - asembler
– jezik visokog nivoa – C (Ci)
Pogledajmo primjer njihove razlike (ovi primjeri su apstraktni).
Recimo da treba da saberemo dva broja: 25 i 35.
U izvornom kodu, ova naredba može izgledati ovako:
00000101 1101001
Na jeziku niskog nivoa:
DODAJTE Rd, Rr
Na jeziku visokog nivoa:
25+35
Razlika između jezika niskog i visokog nivoa vidljiva je golim okom, komentari su, kako kažu, suvišni.
Ali hajdemo dublje u ove primjere. Nećemo analizirati primjer strojnog koda, jer je identičan primjeru u asembleru. U svojoj srži, instrukcije za sklapanje su isti mašinski kodovi (komande) kojima se jednostavno dodeljuju slovne skraćenice kako se ne bi izgubile u nulama i jedinicama. Koristeći naredbu ADD Rd, Rr asembler, postavili smo mikrokontroler da sabere dva pronađena broja (a za to ih prvo moramo upisati tamo) - prvi u Rd, drugi u Rr, a rezultat sabiranja stavimo u Rd. Kao što vidite, postavili smo vrlo specifičan zadatak za mikrokontroler: gdje ga nabaviti, šta učiniti s njim i gdje staviti rezultat. U ovom slučaju radimo direktno sa mikrokontrolerom.
Naredba na jeziku visokog nivoa: 25+35, nama poznata matematička notacija, ugodna našim očima. Ali u ovom slučaju ne radimo direktno sa mikrokontrolerom, već mu jednostavno postavljamo zadatak da sabere dva broja. Rezultat i redoslijed radnji u ovom slučaju bit će isti kao kod izvršavanja asemblerske komande: prvo će se ova dva broja negdje napisati, zatim zbrojiti i rezultat će negdje biti postavljen.
I tu leži glavna razlika između jezika visokog i niskog nivoa. Ako u Assembleru kontrolišemo ceo proces (hteli mi to ili ne): znamo gde su napisana ova dva broja i znamo gde će biti rezultat, onda u jeziku visokog nivoa ne kontrolišemo proces. Program sam odlučuje gdje će unaprijed upisati brojeve i gdje postaviti rezultat. U većini slučajeva to ne moramo znati, jer je za nas glavni rezultat broj 60 u izlazu. Kao rezultat toga, programi na jezicima visokog nivoa su čitljiviji, ugodniji za oko i manji po veličini - na kraju krajeva, ne moramo se "penjati u sve rupe" i slikati svaki korak mikrokontrolera, programa radi to kasnije za nas kada ga kompajlira - prevodi ga u mašinske kodove. Ali postoji i loša strana. Dva identična algoritma napisana u asembleru i u C-u, nakon što ih konvertuju u mašinske kodove, imaće različitu veličinu: program napisan na asembleru biće 20-40% kraći od programa napisanog u C-u - đavo zna kojim putem C ide postići rezultat koji nam je potreban. I postoje slučajevi kada nema poverenja u jezik visokog nivoa i u C program ubacuju kod napisan u Assembleru.
Profesionalni programeri, u pravilu, znaju nekoliko programskih jezika (ili rade u timu koji uključuje stručnjake za različite jezike), kreativno kombinujući svoje karakteristike i prednosti u jednom programu. Pa, mi, amateri, moramo da znamo bar jedan jezik (za početak), i moramo da počnemo (a ja sam u to čvrsto uveren, i niko me neće ubediti) od jezika niskog nivoa - asemblera.

Pa mislim, i tu nam je sve jasno - treba učiti programski jezik, na drugačiji način - nikako.

Naredbe i upute za upravljanje mikrokontrolerom.
AVR mikrokontroleri imaju više od 130 različitih komandi koje im omogućavaju da realizuju sve mogućnosti koje su im svojstvene. Ali odmah ću reći da ih malo koji amater zna sve, a kamoli da ih sve koristi. Obično u amaterskoj praksi ima dovoljno znanja i polovina ekipa, pa čak i manje. Ali morate naučiti komande. Što više komandi znate, to će programi biti sofisticiraniji (u dobrom smislu te riječi) i elegantniji.

Aritmetičko-logička jedinica i organizacija memorije - programska memorija, memorija podataka, nepromjenjiva memorija



U ovom tutorijalu o AVR-u pokušao sam opisati sve najosnovnije stvari za početnike u programiranju mikrokontrolera. avr. Svi primjeri su izgrađeni na mikrokontroleru atmega8. To znači da će vam za ponavljanje svih lekcija biti potreban samo jedan MK. Kao emulator elektronskog kola koristi se Proteus - po mom mišljenju, najbolja opcija za početnike. Programi u svim primjerima su napisani na C kompajleru za avr CodeVision AVR. Zašto ne u nekom asembleru? Zato što je početnik već opterećen informacijama, a program koji množi dva broja traje oko stotinu linija u asembleru, a koriste C u složenim podebljanim projektima. CodeVision AVR kompajler je izoštren za atmel mikrokontrolere, ima zgodan generator koda, a dobar interfejs i direktno iz njega se može flešovati mikrokontrolerom.

Ovaj vodič će pokazati i objasniti jednostavnim primjerima kako:

  • Počnite sa programiranjem mikrokontrolera, odakle početi, šta vam je potrebno za ovo.
  • Koje programe koristiti za pisanje firmvera za avr, za simulaciju i otklanjanje grešaka koda na računaru,
  • Koji se periferni uređaji nalaze unutar MK-a, kako ih kontrolirati pomoću vašeg programa
  • Kako napisati gotov firmver u mikrokontroler i kako ga otkloniti
  • Kako napraviti PCB za svoj uređaj
Da biste napravili prve korake ka MK programiranju, potrebna su vam samo dva programa:
  • Proteus je program za emulator (možete razviti kolo u njemu bez pribjegavanja stvarnom lemljenju, a zatim testirati naš program na ovom kolu). Prvo ćemo pokrenuti sve projekte u Proteusu, a onda već možemo lemiti pravi uređaj.
  • CodeVisionAVR je kompajler C programskog jezika za AVR. U njemu ćemo razviti programe za mikrokontroler, a iz njega će biti moguće flešovati pravi MK.
Nakon što instalirate Proteus, pokrenite ga
Nudi nam da vidimo projekte koji idu uz njega, mi ljubazno odbijamo. Sada napravimo najjednostavniji krug u njemu. Da biste to učinili, kliknite na ikonu vizualno se ništa ne događa. Sada morate kliknuti na malo slovo R (odaberite iz biblioteke) u panelu liste komponenti, otvoriće se prozor za odabir komponente
u polje maske unesite naziv komponente koju želimo pronaći u biblioteci. Na primjer, trebamo dodati mega8 mikrokontroler
u listi rezultata gurnite na mega8 i pritisnite dugme uredu. Na listi komponenti imamo mega8 mikrokontroler
Stoga dodajemo još jedan otpornik na listu komponenti unosom riječi u polje maske res i LED LED

Da biste postavili dijelove na dijagram, kliknite na dio, zatim kliknite na polje dijagrama, odaberite lokaciju komponente i kliknite ponovo. Da dodate uzemljenje ili zajednički minus krugu na lijevoj strani, kliknite na "Terminal" i odaberite Ground. Tako, zbrajanjem svih komponenti i njihovim povezivanjem, dobijamo tako jednostavan sklop
Sve, sada je naša prva šema spremna! Ali možda se pitate šta ona može učiniti? Ali ništa. Ništa, jer da bi mikrokontroler radio, potrebno je napisati program za njega. Program je lista instrukcija koje će mikrokontroler izvršiti. Potreban nam je mikrokontroler za instalaciju na nogu PC0 logička 0 (0 volti) i logička 1 (5 volti).

Pisanje programa za mikrokontroler

Program ćemo napisati u jeziku C koristeći CodeVisionAVR kompajler. Nakon pokretanja CV-a, pita nas šta želimo da kreiramo: izvor ili projekat Odaberemo ovo drugo i pritisnemo dugme OK. Zatim ćemo biti zamoljeni da pokrenemo CVAVR CodeWizard (ovo je neprocjenjiv alat za početnike, jer može generirati glavni kostur programa) izabrati Da
Čarobnjak počinje sa aktivnom karticom Chip, ovdje možemo odabrati model našeg MK-a - ovo je mega8, i frekvenciju na kojoj će MK raditi (mega8 je po defaultu postavljen na 1 megaherc), tako da sve postavljamo kako je prikazano na snimak ekrana iznad. Idite na karticu Ports
Atmega8 mikrokontroler ima 3 porta: Port C, Port D, Port B. Svaki port ima 8 pinova. Pinovi porta mogu biti u dva stanja:
  • Izlaz
Uz pomoć registra DDRx.y možemo postaviti pin kao ulaz ili izlaz. Ako u
  • DDRx.y = 0 - izlaz radi kao ULAZ
  • DDRx.y = 1 pin radi IZLAZ
Kada je pin konfiguriran kao izlaz, možemo ga postaviti na logičku 1 (+5 volti) i logičku 0 (0 volti). Ovo se radi upisivanjem u registar PORTx.y. Dalje će se detaljno raspravljati o ulazno-izlaznim portovima. I sada sve postavljamo kao što je prikazano na snimku ekrana i kliknemo File->Generate, Save and Exit. Zatim, CodeWizard će nam ponuditi da sačuvamo projekat, mi ga sačuvamo i pogledamo kod:

#include //biblioteka za kreiranje vremenskih kašnjenja void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // napravi PC0 izlaz nogu PORTD=0x00; DDRD=0x00; // Tajmer/brojač 0 inicijalizacija TCCR0=0x00; TCNT0=0x00; // Inicijalizacija tajmera/brojala 1 TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; ICR1L=0x000; OCR1AH0x0; ; OCR1BL=0x00; // Inicijalizacija tajmera/brojača 2 ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // Inicijalizacija eksternog prekida MCUCR=0x00; // Tajmer(i)/brojači ) Inicijalizacija prekida TIMSK=0x00; // Inicijalizacija analognog komparatora ACSR=0x80; SFIOR=0x00; dok (1) ( ); )


Ovdje vam sve može izgledati zastrašujuće i nepoznato, ali u stvarnosti sve nije tako. Kod se može pojednostaviti izbacivanjem inicijalizacije MK perifernih uređaja koje ne koristimo. Nakon pojednostavljenja to izgleda ovako:

#include //biblioteka za rad sa mikrokontrolerom mega8 #include //biblioteka za kreiranje vremenskih kašnjenja void main(void) ( DDRC=0x01; /* napravi PC0 nogu izlazni unos 0x01 vam može izgledati nepoznato, a ovo je samo broj 1 u heksadecimalnom, ovaj red će biti ekvivalentan 0b00000001 u binarnom, onda ću pisati tačno ovako. */ dok (1) ( ); )


Stvari su dobre. Ali da bi LED dioda treperila, moramo promijeniti logički nivo na PC0 nozi. Da biste to učinili, dodajte nekoliko redaka u glavnu petlju:

#include //biblioteka za rad sa mikrokontrolerom mega8 #include //biblioteka za kreiranje vremenskih kašnjenja void main(void) ( DDRC=0x01; /* napravi PC0 nogu izlazni unos 0x01 vam može izgledati nepoznato, a ovo je samo broj 1 u heksadecimalnom, ovaj red će biti ekvivalentan 0b00000001 u binarnom, onda ću pisati tačno ovako.*/ dok (1)//glavna programska petlja (// operatorski zagrada glavne programske petlje otvara PORTC.0=1; //postavi port C 1 na pin 0 delay_ms(500); //napravi kašnjenje od 500 milisekundi PORTC.0=0; // postavi port C 0 na pin 0 delay_ms(500); // napravi odgodu od 500 milisekundi );// zatvori zagradu operatora glavne programske petlje)


Sve, sada je kod spreman. Kliknemo na ikonu Build all Project files da kompajliramo (prevedemo u uputstva za MK procesor) naš program. U fascikli Exe, koja se nalazi u našem projektu, trebala bi se pojaviti datoteka s hex ekstenzijom, ovo je naša datoteka firmvera za MK. Da bismo naš firmware ubacili u virtuelni mikrokontroler u Proteusu, potrebno je dvaput kliknuti na sliku mikrokontrolera u Proteusu. Pojavit će se ovakav prozor
kliknite na ikonu fascikle u polju Program File, izaberite hex - datoteku našeg firmvera i pritisnite dugme OK. Sada možemo pokrenuti simulaciju našeg kola. Da biste to učinili, kliknite na dugme "Play" u donjem lijevom uglu prozora Proteus.

Rekao sam više od jednom ili dva puta da proučavanje MK treba početi sa asemblerom. Tome je bio posvećen čitav kurs na sajtu (iako nije baš konzistentan, ali postepeno ga češljam do adekvatnog izgleda). Da, teško je, rezultat neće biti prvog dana, ali naučićete da razumete šta se dešava u vašem kontroleru. Znat ćete kako to funkcionira, a ne kao majmun kopirati tuđe izvore i pokušati razumjeti zašto je odjednom prestao da radi. Osim toga, C-u je mnogo lakše da se petlja sa redneck kodom koji će izaći s vilama u najnepovoljnijem trenutku.

Nažalost, svi žele rezultate odmah. Stoga sam odlučio da krenem drugim putem - da napravim tutorijal o C-u, ali sa demonstracijom njegovog donjeg rublja. Dobar programer za embedder uvek čvrsto drži svoj komad gvožđa za čvarak, sprečavajući ga da učini nijedan korak bez dozvole. Pa šta će prvo biti C kod, pa šta je kompajler rodio i kako sve to radi u stvarnosti :)

S druge strane, C-ova jača strana je prenosivost koda. Ako, naravno, da napišem sve kako treba. Razdvajanje radnih algoritama i njihovih gvozdenih implementacija u različite dijelove projekta. Zatim, da bi se algoritam prebacio na drugi MK, biće dovoljno da se prepiše samo sloj interfejsa, gde je upisan sav pristup hardveru, i da se sav radni kod ostavi kakav jeste. I, naravno, čitljivost. Sish izvorni kod je lakši za razumijevanje na prvi pogled (iako .. na primjer, ne zanima me šta da udarim - barem si, barem asm :)), ali, opet, ako je sve ispravno napisano. Takođe ću obratiti pažnju na ove tačke.

Kao eksperimentalni komad željeza na koji će biti postavljen lavovski dio svih primjera, bit će moja ploča za otklanjanje grešaka.

Prvi C program za AVR

Odabir kompajlera i instaliranje okruženja
Postoji mnogo različitih C kompajlera za AVR:
Prije svega, ovo IAR AVR C- gotovo nedvosmisleno prepoznat kao najbolji kompajler za AVR, tk. sam kontroler je kreiran u bliskoj saradnji između Atmela i stručnjaka iz IAR-a. Ali morate platiti za sve. A ovaj kompajler nije samo skup komercijalni softver, već ima i tako mnoštvo postavki da jednostavno morate naporno raditi da biste ga kompajlirali u njemu. Zaista nisam imao prijateljstvo sa njim, projekat je istrunuo zbog čudnih grešaka u fazi povezivanja (kasnije sam saznao da je to bila kriva pukotina).

Drugi ide WinAVR GCC je moćan kompajler za optimizaciju. Puni open source, cross-platform, općenito, sve radosti života. Takođe se savršeno integriše u AVR Studio, omogućavajući vam da otklanjate greške upravo tamo, što je pakleno zgodno. Generalno, izabrao sam ga.

Takođe imaju CodeVision AVR C je veoma popularan kompajler. Postala je popularna zbog svoje jednostavnosti. U njemu možete dobiti radni program za nekoliko minuta - čarobnjak za startni kod uvelike doprinosi tome, postavljajući standarde za inicijalizaciju bilo kojeg uarta. Da budem iskren, nekako se prema njemu odnosim sa sumnjom - jednom sam morao da rastavljam program koji je napisao ovaj kompajler, ispala je neka vrsta kaše, a ne koda. Užasna količina nepotrebnih gestova i operacija, što je rezultiralo prilično velikom količinom koda i sporim performansama. Međutim, možda je došlo do greške u DNK originalnog pisača firmvera. Plus on želi novac. Ne toliko kao IAR, ali primjetno. A u demo modu vam omogućava da napišete ne više od 2 kb koda.
Naravno da postoji crack, ali ako ukradete, onda milion, u smislu IAR :)

Postoji također Image Craft AVR C i MicroC iz mikroelektronike. Nisam ni morao da koristim, ali... SWG veoma hvale micropascal, kažu, užasno zgodno programsko okruženje i biblioteke. Mislim da MicroC neće biti ništa lošiji, ali i plaćen.

Kao što sam rekao, izabrao sam WinAVR iz tri razloga: besplatan, integriše se u AVR Studio i za njega je napisana samo gomila gotovog koda za sve prilike.

Dakle, preuzmite WinAVR sa i AVR Studio. Zatim se prvo instalira studio, a zatim se odozgo WinAVR namota i prilijepi za studio u obliku dodatka. Toplo preporučujem da WinAVR postavite na kratku stazu, nešto poput C:\WinAVR, tako ćete izbjeći mnogo problema sa putanjama.

Kreiranje projekta
Dakle, studio je postavljen, C je sjeban, vrijeme je da probamo nešto programirati. Počnimo s jednostavnim, najjednostavnijim. Pokrenite studio, tamo odaberite novi projekat kao AVR GCC kompajler i unesite naziv projekta.

Radni prostor se otvara s praznom *.c datotekom.

Sada ne škodi da konfigurišete prikaz staza u obeleživačima studija. Da biste to učinili, idite na:
Meni Alati - Opcije - Općenito - Kartice datoteka i odaberite "Samo naziv datoteke" sa padajuće liste. U suprotnom će biti nemoguće raditi - kartica će sadržavati punu putanju datoteke i neće biti više od dvije ili tri kartice na ekranu.

Postavljanje projekta
Uopšteno govoreći, smatra se klasičnim kreiranje make datoteke u kojoj bi bile opisane sve zavisnosti. I ovo je vjerovatno tačno. Ali za mene, koji sam odrastao sa potpuno integrisanim IDE-ovima kao što su uVision ili AVR Studio ovaj pristup je duboko stran. Stoga ću to učiniti na svoj način, svim sredstvima studija.

Kliknite na dugme zupčanika.


Ovo su postavke za vaš projekat, odnosno postavke za automatsko generiranje make datoteke. Na prvoj stranici samo trebate unijeti frekvenciju na kojoj će vaš MK raditi. Zavisi od bita osigurača, pa pretpostavljamo da je frekvencija 8000000Hz.
Također obratite pažnju na liniju optimizacije. Sada postoji -Os je optimizacija veličine. Ostavite kako je za sada, onda možete pokušati da se poigrate sa ovim parametrom. -O0 uopće nije optimizacija.

Sljedeći korak je postavljanje staza. Prije svega, dodajte direktorij svog projekta tamo - tamo ćete staviti biblioteke trećih strana. Putanja ".\" će se pojaviti na listi

Make fajl je generisan, možete ga pogledati u podrazumevanoj fascikli u vašem projektu, samo pogledajte, vidite šta je tamo.


To je sve za sada. Kliknite OK svuda i idite na izvor.

Formulacija problema
Prazan list je primamljiv za utjelovljenje neke lukave ideje, budući da se banalno bljeskanje diode više ne ubacuje. Hajdemo odmah uhvatiti bika za rogove i uspostaviti vezu sa kompjuterom - ovo je prva stvar koju radim.

Radit će ovako:
Kada jedinica stigne na COM port (kod 0x31), upalit ćemo diodu, a kada stigne nula (kod 0x30), ugasit ćemo je. Štaviše, sve će se raditi na prekidima, a pozadinski zadatak će biti treptanje druge diode. Jednostavno i smisleno.

Sastavljanje šeme
Moramo spojiti USB-USART konvertorski modul na USART pinove mikrokontrolera. Da bismo to učinili, uzimamo kratkospojnik od dvije žice i stavljamo ih na igle poprečno. Odnosno, povezujemo Rx kontrolera sa Tx pretvarača, a Tx pretvarača sa Rx regulatorom.

Ispostavilo se, na kraju, ovo je šema:


Ne razmišljam o povezivanju preostalih izlaza, napajanja, resetovanja, to je standardno

Pišemo kod

Odmah ću rezervisati da se neću posebno upuštati u opis samog C jezika. Da biste to učinili, postoji jednostavno kolosalna količina materijala, u rasponu od klasičnog "C programskog jezika" od K&R do raznih priručnika.

Jedna takva metoda je pronađena u mojoj zalihi, jednom sam proučavao ovaj jezik koristeći ga. Sve je kratko, jasno i precizno. Postepeno ga kucam i prevlačim na svoju stranicu.

Tačno je da još nisu sva poglavlja premeštena tamo, ali mislim da nije zadugo.

Malo je vjerovatno da ću bolje opisati, stoga, iz kursa obuke, umjesto detaljnog objašnjenja zamršenosti Cish-a, jednostavno ću dati direktne veze na pojedine stranice ovog priručnika.

Dodavanje biblioteka.
Prije svega, dodajemo potrebne biblioteke i zaglavlja s definicijama. Na kraju krajeva, C je univerzalni jezik i potrebno je objasniti da radimo sa AVR-om, pa unesite red u izvorni kod:

1 #include

#include

Ovaj fajl se nalazi u folderu WinAVR i sadrži opis svih registara i portova kontrolera. I tu je sve zeznuto, s obzirom na određeni kontroler, preko kojeg se prenosi kompajler napraviti fajl u parametru MCU i na osnovu ove varijable, fajl zaglavlja sa opisom adresa svih portova i registara za ovaj određeni kontroler je povezan sa vašim projektom. Kako! Možete to učiniti i bez njega, ali tada nećete moći koristiti simbolička imena registara kao što su SREG ili UDR i morat ćete zapamtiti adresu svakog kao što je "0xC1" i to je glavobolja.

Isti tim #include<имя файла> omogućava vam da svom projektu dodate sadržaj bilo koje tekstualne datoteke, na primjer, datoteku s opisom funkcija ili dio drugog koda. I da bi direktiva mogla pronaći ovu datoteku, naznačili smo putanje do našeg projekta (WinAVR direktorij je tamo već registriran po defaultu).

glavna funkcija.
C program je sve o funkcijama. Mogu biti ugniježđene i pozvane jedna od druge bilo kojim redoslijedom i na mnogo različitih načina. Svaka funkcija ima tri potrebna parametra:

  • Povratna vrijednost, na primjer, sin(x) vraća vrijednost sinusa od x. Kao u matematici, ukratko.
  • Preneseni parametri, isti x.
  • Tijelo funkcije.

Sve proslijeđene i vraćene vrijednosti moraju biti nekog tipa, ovisno o podacima.

Svaki C program mora sadržavati funkciju main kao ulazna tačka u glavni program, inače nije C uopšte :). Po prisustvu main u tuđem izvornom kodu od milion fajlova, možete shvatiti da je ovo glavni deo programa odakle sve počinje. Ovdje ćemo postaviti:

1 2 3 4 5 int main(void) (vrat 0;)

int main(void) (vrat 0;)

To je to, prvi najjednostavniji program je napisan, nema veze što ne radi ništa, tek smo počeli.

Hajde da vidimo šta smo uradili.
int je tip podataka koji vraća glavna funkcija.

Naravno, u mikrokontroleru main u principu se ništa ne može vratiti, a u teoriji bi trebalo void main(void), ali GCC je originalno izoštren na PC-u i tamo program može vratiti vrijednost operativnom sistemu po završetku. Stoga je GCC uključen void main(void) kune se upozorenjem.

Ovo nije greška, radiće, ali ne volim upozorenja.

void ovo je tip podataka koji prosljeđujemo funkciji, u ovom slučaju main takođe ne može prihvatiti ništa izvana, pjesnik void- prazno. Stub se koristi kada ništa ne treba proslijediti ili vratiti.

Evo ovih { } vitičaste zagrade su programski blok, u ovom slučaju tijelo funkcije main, kod će se tamo nalaziti.

povratak- ovo je povratna vrijednost koju će glavna funkcija dati na kraju, pošto imamo int, odnosno broj, onda moramo vratiti broj. Iako i dalje nema smisla, jer. na mikrokontroleru sa glavnog, ne možemo samo nikuda. Vraćam nulu. Za nefig. A kompajler je obično pametan i ne generiše kod za ovaj slučaj.
Iako, ako je izopačeno, onda iz main možete otići na MK - na primjer, upasti u odjeljak pokretačkog programa i izvršiti ga, ali ovdje će vam već trebati odabir firmvera na niskom nivou kako biste ispravili adrese tranzicije. U nastavku ćete vidjeti i razumjeti kako to učiniti. Zašto? E sad ovo je drugo pitanje, u 99.999% slučajeva to nije potrebno :)

Gotovo, idemo dalje. Hajde da dodamo varijablu, nije nam baš potrebna i ne bismo trebali uvoditi varijable bez nje, ali učimo. Ako se varijable dodaju unutar tijela funkcije, one su lokalne i postoje samo u ovoj funkciji. Kada izađete iz funkcije, ove varijable se brišu, a RAM memorija se daje važnijim potrebama. .

1 2 3 4 5 6 int main(void) (nepotpisani char i; povratak 0;)

int main(void) (nepotpisani char i; povratak 0; )

nepotpisan znači nepotpisano. Činjenica je da je u binarnom prikazu znaku dodijeljen visoki bit, što znači da se broj +127/-128 uklapa u jedan bajt (char), ali ako se znak odbaci, on će stati od 0 do 255 Obično znak nije potreban. Tako da nepotpisan.
i je samo ime varijable. Dosta.

Sada moramo inicijalizirati portove i UART. Naravno, možete uzeti i povezati biblioteku i pozvati neku vrstu UartInit-a (9600); ali tada nećete znati šta se zaista dogodilo.

radimo ovo:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void) (nepotpisani char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRH = HI (razdjelnik prijenosa) ; UCSRA = 0; UCSRB=1<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int main(void) ( unsigned char i; #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO(bauddivider); UBRRH = HI(bauddivider); UCSRA = 0; UCSRB = 1<

Strašno? U stvari, postoji samo pet poslednjih linija pravog koda. Sve, to #define to je preprocesorski makro jezik. Gotovo isti vrhovi kao u Assembleru, ali je sintaksa nešto drugačija.

Oni će vam olakšati rutinske operacije za izračunavanje potrebnih koeficijenata. U prvom redu kažemo to umjesto XTAL možete sigurno zamijeniti 8000000, i L- indikacija tipa, kažu da je duga frekvencija takta procesora. Isto baudrate- frekvencija prijenosa podataka preko UART-a.

bauddivider već složeniji, umjesto njega će biti zamijenjen izraz izračunat formulom iz prethodna dva.
Pa i LO i HI iz ovog rezultata će se uzeti niski i visoki bajtovi, jer očigledno ne može stati u jedan bajt. AT HI x se pomera (ulazni parametar makroa) osam puta udesno, kao rezultat toga, od njega će ostati samo visoki bajt. I unutra LO radimo po bitu I sa brojem 00FF, ostavljajući samo niži bajt kao rezultat.

Dakle, sve što je urađeno je kao #define možete ga sigurno baciti i izračunati potrebne brojeve na kalkulatoru i odmah ih uneti u redove UBBRL = .... i UBBRH=…..

Može. Ali! Uradi ovo STROGO NEMOGUĆE!

Radit će ovako i onako, ali ćete imati tzv magični brojevi- vrijednosti preuzete niotkuda i nije jasno zašto, a ako otvorite takav projekat za par godina, onda će biti vraški teško shvatiti koje su to vrijednosti. A sad, ako hoćeš da promeniš brzinu, ili da promeniš frekvenciju kvarca i moraćeš sve da preračunaš, i tako si promenio par brojeva u kodu i to je to. Općenito, ako ne želite da vas smatraju lošim koderom, napravite kod tako da bude lak za čitanje, razumljiv i lako modificiran.

Onda je sve jednostavno:
Svi ovi "UBRLL and Co" su konfiguracijski registri UART predajnika s kojima ćemo komunicirati sa svijetom. I sada smo im dodijelili potrebne vrijednosti, postavljajući ih na željenu brzinu i željeni način rada.

Pogledaj unos 1< Znači sljedeće: uzmite 1 i stavite ga na svoje mjesto RXEN u bajtu. RXEN ovo je 4. bit registra UCSRB, dakle 1< formira binarni broj 00010000, TXEN je 3. bit, i 1<će dati 00001000. Jedno "|" to je po bitovima ILI, tako 00010000 | 00001000 = 00011000. Na isti način, preostali neophodni konfiguracijski bitovi se postavljaju i dodaju zajedničkoj hrpi. Kao rezultat toga, prikupljeni broj se upisuje u UCSRB. Detaljnije je opisano u podatkovnoj tablici na MK u odjeljku USART. Zato nemojte da vas ometaju tehnički detalji.

Gotovo, vrijeme je da vidimo šta će se desiti. Kliknite na kompilaciju i pokrenite emulaciju (Ctrl+F7).

Otklanjanje grešaka
Prolazile su svakakve trake napretka, studio se mijenjao i žuta strelica se pojavila blizu ulaza u glavnu funkciju. Ovdje se trenutno nalazi procesor i simulacija je pauzirana.

Činjenica je da je u početku, zapravo, bilo na liniji UBRRL = LO(bauddivider); Uostalom, ono što imamo u definiciji nije kod, već samo preliminarni proračuni, tako da je simulator malo dosadan. Ali sada je shvatio da je prva instrukcija ispunjena i ako se popneš na drvo I/O View, do USART sekcije i tamo pogledajte UBBRL bajt, vidjet ćete da tamo već postoji vrijednost! 0x33.

Napravi još jedan korak. Pogledajte kako će se promijeniti sadržaj drugog registra. Dakle, prođite kroz sve njih, obratite pažnju na činjenicu da su svi navedeni bitovi postavljeni kao što sam vam rekao, i da su postavljeni istovremeno za cijeli bajt. Stvari neće ići dalje od Povratka - program je završen.

Otvaranje
Sada resetirajte simulaciju na nulu. Kliknite tamo Resetiraj (Shift+F5). Otvorite rastavljeni listing, sada ćete vidjeti šta se stvarno dešava u kontroleru. Pogled -> Disassembler. A ne YYAAAA!!! Assembler!!! HORRIBLE!!! ALI MORAŠ. Pa da kasnije, kada nešto krene po zlu, ne zaglupljuješ u kodu i ne postavljaš lađa pitanja po forumima, nego odmah uđi u utrobu i pogledaj gdje ti je utikač. Nema tu ništa strašno.

Prvo će biti topovi iz serije:

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 JMP +00000034 JMP 0x000023 JMP +00000022: 940C0034 JMP +000026: 940C0034 JMP 0x00000034 JMP 0x00000034 JMP 2002: 940C0034 JMP 0x000034

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 JMP +00000034 JMP 0x000023 JMP 0x000023: 940C0034: 940C0034 JMP +000026: 940C0034 JMP 0x00000034 JMP 0x00000034 JMP 2002: 940C0034 JMP 0x000034 Skoči

Ovo je tabela vektora prekida. Na to ćemo se vratiti kasnije, za sada, samo pogledajte i zapamtite da je tu. Prva kolona je adresa fleš ćelije u kojoj se nalazi komanda, druga je kod komande, treća mnemonika komande, ista asemblerska instrukcija, treći operandi komande. Oh, i automatski komentar.
Dakle, ako pogledate, onda postoje neprekidni prijelazi. A JMP komandni kod je četiri bajta, sadrži adresu za skok napisanu unazad - niži bajt na nižoj adresi i kod komande za skok 940C

0000002B: BE1F OUT 0x3F,R1 Izlaz na I/O lokaciju

Upišite ovu nulu na adresu 0x3F Ako pogledate u kolonu I/O view, vidjet ćete da je adresa 0x3F adresa SREG registra - registra zastavice kontrolera. One. resetujemo SREG da pokrenemo program pri nultim uslovima.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Učitaj odmah +0000002D: E0D4 LDI R29,0x04 Učitaj odmah +0000002E: BFDE OUT 0x3E,R29 Izlaz na I/O lokaciju +0000002 Out to I/O lokaciju +0000002 Out to I/OUT

0000002C: E5CF LDI R28,0x5F Učitaj odmah +0000002D: E0D4 LDI R29,0x04 Učitaj odmah +0000002E: BFDE OUT 0x3E,R29 Izlaz na I/O lokaciju +0000002 Izlaz na I/O lokaciju +0000002 Izlaz na I/OUT

Ovo učitava pokazivač steka. Ne možete direktno učitavati registre u I/O, samo preko međuregistra. Dakle, prvo LDI do srednjeg, a onda odatle OUT do I/O. Također ću vam reći više o steku. U međuvremenu, znajte da je ovo tako dinamično memorijsko područje, da visi na kraju RAM-a i pohranjuje adrese i međuvarijable u sebi. Sada smo naznačili odakle će stek početi.

00000032: 940C0041 JMP 0x00000041 Skoči

Skok na saaaaamy kraj programa, i tamo imamo isključene prekide i čvrsto petlje na sebi:

1 2 +00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relativni skok

00000041: 94F8 CLI Global Interrupt Disable +00000042: CFFF RJMP PC-0x0000 Relativni skok

Ovo je u slučaju nepredviđenih okolnosti, kao što je izlazak iz glavne funkcije. Kontroler se može izvući iz takve petlje ili hardverskim resetiranjem, ili, što je vjerojatnije, resetiranjem od nadzornog nadzora. Pa, ili, kao što sam rekao gore, popravimo ova mjesta u hex editoru i vozimo se gdje god želimo. Također imajte na umu da postoje dvije vrste skokova JMP i RJMP, prvi je direktan skok na adresu. Zauzima četiri bajta i može napraviti direktan skok preko cijelog memorijskog područja. Drugi tip tranzicije - RJMP - je relativan. Njegova komanda zauzima dva bajta, ali on skače sa trenutne pozicije (adrese) 1024 koraka naprijed ili nazad. A njegovi parametri ukazuju na pomak od trenutne tačke. Češće se koristi, tk. zauzima polovinu prostora u blicu, a dugi prelazi su retko potrebni.

1 +00000034: 940C0000 JMP 0x00000000 Skoči

00000034: 940C0000 JMP 0x00000000 Skoči

A ovo je skok na sam početak koda. Neka vrsta ponovnog pokretanja. Ovdje možete provjeriti da li svi vektori skaču. Iz ovog zaključka - ako sada omogućite prekide (oni su podrazumevano onemogućeni) i imate prekid, ali nema rukovaoca, onda će doći do softverskog resetovanja - program će biti bačen na sam početak.

glavna funkcija. Sve je isto, ne možete ni opisati. Pogledajte samo u registrima upisan je već izračunat broj. Preprocesor kompajlera napreduje!!! Dakle, bez "magičnih" brojeva!

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

00000036: E383 LDI R24,0x33 Učitavanje odmah +00000037: B989 OUT 0x09,R24 Izlaz na I/O lokaciju 15: UBRRH = HI(bauddivider); +00000038: BC10 OUT 0x20,R1 Izlaz na I/O lokaciju 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 Izlaz na I/O lokaciju 17: UCSRB = 1<

A evo i dovratka:

1 2 3 +0000003E: E080 LDI R24,0x00 Učitaj odmah +0000003F: E090 LDI R25,0x00 Učitaj odmah +00000040: 9508 RET Podprogramski povratak

0000003E: E080 LDI R24,0x00 Učitaj odmah +0000003F: E090 LDI R25,0x00 Učitaj odmah +00000040: 9508 RET Podrutinski povratak

Pitanje je zašto kompajler dodaje takve vrhove? I ovo nije ništa drugo do Return 0, definisali smo funkciju kao int main (void), pa smo popizdili još četiri bajta, ne razumijem šta :) A ako uradite void main (void), onda će ostati samo RET , ali će se pojaviti upozorenje da kažu da naša glavna funkcija ne vraća ništa. Generalno, radi šta hoćeš :)

Komplikovano? Izgleda da nije. Kliknite na korak-po-korak izvršenje u disassembler modu i pogledajte kako procesor izvršava pojedinačne instrukcije, što se dešava sa registrima. Kako je kretanje kroz komande i konačno petljanje.

Nastavak za par dana...

Offtop:
Alexei78 Napravio sam dodatak za firefox koji olakšava navigaciju po mojoj stranici i forumu.
Diskusija i preuzimanje,

Postoje različiti programski jezici za AVR mikrokontrolere, ali asembler i C su možda najpogodniji, jer ovi jezici pružaju najbolju implementaciju svih potrebnih mogućnosti za upravljanje hardverom mikrokontrolera.

Asembler je programski jezik niskog nivoa koji koristi direktni skup instrukcija mikrokontrolera. Kreiranje programa na ovom jeziku zahteva dobro poznavanje komandnog sistema programabilnog čipa i dovoljno vremena za razvoj programa. Asembler gubi u odnosu na C u pogledu brzine i pogodnosti razvoja programa, ali ima značajne prednosti u veličini konačnog izvršnog koda, a samim tim i u brzini njegovog izvršavanja.

C vam omogućava da kreirate programe sa mnogo većom udobnosti, dajući programeru sve prednosti jezika visokog nivoa.
Još jednom treba napomenuti da je AVR arhitektura i komandni sistem kreirani uz direktno učešće programera C kompajlera i uzima u obzir karakteristike ovog jezika. Prevođenje izvornog koda napisanog u C je brzo i proizvodi kompaktan, efikasan kod.

Glavne prednosti C u odnosu na asembler su: velika brzina razvoja programa; svestranost koja ne zahteva temeljno proučavanje arhitekture mikrokontrolera; bolja dokumentabilnost i čitljivost algoritma; dostupnost biblioteka funkcija; podrška za izračune s pokretnim zarezom.

Jezik C harmonično kombinuje mogućnosti programiranja niskog nivoa sa karakteristikama jezika visokog nivoa. Mogućnost programiranja na niskom nivou olakšava rad direktno na hardveru, a svojstva jezika visokog nivoa omogućavaju kreiranje lako čitljivog i promjenjivog programskog koda. Pored toga, skoro svi prevodioci C imaju mogućnost da koriste asemblerske umetke za pisanje kritičnih delova programa u smislu vremena izvršavanja i resursa.

Jednom riječju, C je najpogodniji jezik i za početnike da se upoznaju sa AVR mikrokontrolerima i za ozbiljne programere.

Kompajleri se koriste za pretvaranje izvornog koda programa u datoteku firmvera mikrokontrolera.

Atmel pruža moćan asemblerski kompajler koji je uključen u razvojno okruženje Atmel Studio zasnovano na Windows-u. Zajedno sa kompajlerom, razvojno okruženje sadrži debuger i emulator.
Atmel Studio je potpuno besplatan i dostupan je na Atmel web stranici.

Trenutno postoji dosta C kompajlera za AVR. Najmoćniji od njih je kompajler IAR Systems iz Štokholma. Upravo su njeni zaposlenici sredinom 90-ih sudjelovali u razvoju komandnog sistema AVR. IAR C kompajler ima opsežne mogućnosti optimizacije koda i dolazi kao deo integrisanog razvojnog okruženja IAR Embedded Workbench (EWB), koje takođe uključuje asemblerski kompajler, linker, menadžer projekta i biblioteke i debuger. Cijena pune verzije paketa je 2820 EUR. Na web stranici kompanije možete preuzeti besplatnu probnu verziju u trajanju od 30 dana ili neograničenu verziju s ograničenjem veličine koda od 4 KB.

Američka kompanija Image Craft iz Palo Alta u Kaliforniji proizvodi kompajler za jezik C, koji je stekao prilično veliku popularnost. JumpStart C za AVR ima prihvatljivu optimizaciju koda i nije preskup (od $50 do $499 u zavisnosti od verzije). Demo verzija JumpStart C za AVR je potpuno funkcionalna 45 dana.

Ništa manju popularnost nije osvojio rumunski Code Vision AVR C kompajler, cena pune verzije ovog kompajlera je relativno niska i iznosi 150 EUR. Kompajler dolazi sa integrisanim razvojnim okruženjem, koje, pored standardnih karakteristika, uključuje i prilično zanimljivu karakteristiku - CodeWizardAVR Automatic Program Generator. Prisustvo serijskog terminala u razvojnom okruženju omogućava otklanjanje grešaka u programima koristeći serijski port mikrokontrolera. Programeri mogu preuzeti besplatnu probnu verziju s ograničenjem veličine koda od 4 KB i onemogućenim spremanjem generiranog C izvornog koda.

MikroElektronika, locirana u Beogradu, proizvodi čitavu porodicu kompajlera za AVR mikrokontrolere. C kompajler pod nazivom mikroC PRO za AVR košta 249 dolara. Tu su i mikroBasic i mikroPascal po istoj ceni. Postoje demonstracije na web lokaciji programera s ograničenjem veličine koda od 4096 bajtova. Prednost ove familije kompajlera je jedinstvena platforma i jedinstvena ideologija, koja može da obezbedi laku tranziciju ne samo između jezika, već i između mikrokontrolera (postoje verzije kompajlera za PIC, STM32, 8051...).

Integrisano razvojno okruženje postalo je zaista kultno. Uključuje moćne kompajlere C i asemblera, AVRDUDE programer, debuger, simulator i mnoge druge programe i pomoćne programe. WinAVR se savršeno integriše sa Atmelovim razvojnim okruženjem AVR Studio. Asembler je identičan u ulaznom kodu kao i AVR Studio asembler. Prevodioci C i asemblera imaju mogućnost kreiranja datoteka za otklanjanje grešaka u COFF formatu, što vam omogućava da koristite ne samo ugrađene alate, već i moćni AVR Studio simulator. Još jedan važan plus je što se WinAVR distribuira besplatno bez ograničenja (proizvođači podržavaju GNU General Public License).

Ukratko, WinAVR je idealan izbor za one koji počinju da savladavaju AVR mikrokontrolere. Upravo se ovo razvojno okruženje smatra glavnim u ovom kursu.

Bitove operacije su zasnovane na logičkim operacijama, koje smo već pokrili ranije. Oni igraju ključnu ulogu u programiranju AVR mikrokontrolera i drugih tipova. Gotovo nijedan program ne može bez upotrebe bitnih operacija. Do sada smo ih namjerno izbjegavali kako bismo olakšali učenje MK programiranja.

U svim prethodnim člancima programirali smo samo I/O portove i nismo koristili dodatne ugrađene čvorove, kao što su tajmeri, analogno-digitalni pretvarači, prekidi i drugi interni uređaji bez kojih MK gubi svu snagu.

Prije nego što pređete na savladavanje ugrađenih MK uređaja, morate naučiti kako kontrolirati ili provjeriti pojedinačne bitove AVR MK registara. Prethodno smo vršili provjeru ili postavljali bitove cijelog registra odjednom. Hajde da vidimo u čemu je razlika, pa nastavimo dalje.

Bitwise operacije

Najčešće smo ga koristili prilikom programiranja AVR mikrokontrolera, jer ima veću jasnoću u odnosu na početnike MK programere i dobro je razumljiv za njega. Na primjer, trebamo postaviti samo 3. bit porta D. Za ovo, kao što već znamo, možemo koristiti sljedeći binarni kod:

PORTD = 0b00001000;

Međutim, ovom komandom postavljamo 3. bit na jedan, a sve ostale (0, 1, 2, 4, 5, 6 i 7.) resetujemo na nulu. A sada zamislimo situaciju da se 6. i 7. znamenka koriste kao ulazi ADC-a i u ovom trenutku na odgovarajuće izlaze MK-a stiže signal sa nekog uređaja, a mi resetujemo ove signale koristeći gornju naredbu. Kao rezultat toga, mikrokontroler ih ne vidi i vjeruje da signali nisu došli. Stoga, umjesto takve naredbe, trebali bismo koristiti drugu koja bi postavila samo 3. bit na jedan, a da ne utječe na ostale bitove. Za to se obično koristi sljedeća bitna operacija:

LUKA |= (1<<3);

U nastavku ćemo detaljno analizirati njegovu sintaksu. A sada još jedan primjer. Recimo da trebamo provjeriti status 3. bita PIND registra i na taj način provjeriti stanje gumba. Ako se ovaj bit resetuje na nulu, tada znamo da je dugme pritisnuto, a zatim se izvršava komandni kod, koji odgovara stanju pritisnutog dugmeta. Ranije bismo koristili sljedeću notaciju:

if (pind == 0b00000000)

(bilo koji kod)

Međutim, uz pomoć njega ne provjeravamo niti jedan, - treći, već sve bitove PIND registra odjednom. Stoga, čak i ako se pritisne dugme i željeni bit se resetuje, ali u tom trenutku se primi signal na bilo koji drugi pin porta D, odgovarajući bit će biti postavljen na jedan, a uslov u zagradi će biti netačan. Kao rezultat toga, kod u vitičastim zagradama neće biti izvršen čak ni kada se pritisne dugme. Stoga, za provjeru statusa pojedinačnog 3. bita PIND registra, treba koristiti bitnu operaciju:

ako (~PIND & (1<<3))

(bilo koji kod)

Za rad sa pojedinačnim bitovima mikrokontrolera, programski jezik C ima u svom arsenalu, pomoću kojeg možete promijeniti ili provjeriti stanje jednog ili više pojedinačnih bitova odjednom.

Postavljanje jednog bita

Za postavljanje jednog bita, kao što je port D, koristi se bitna operacija ILI. To je ono što smo koristili na početku članka.

PORTD = 0b00011100; // početna vrijednost

PORTD = PORTD | (jedan<<0); применяем побитовую ИЛИ

LUKA |= (1<<0); // сокращенная форма записи

PORTD == 0b00011101; // rezultat

Ova komanda postavlja bit na nulu, a ostatak ostavlja nepromijenjenim.

Na primjer, postavimo 6. bit porta D.

PORTD = 0b00011100; // početno stanje porta

LUKA |= (1<<6); //

PORTD == 0b01011100; // rezultat

Za pisanje od jednog do nekoliko odvojenih bitova odjednom, na primjer, nula, šesti i sedmi port B primjenjuje se sljedeća notacija.

PORTB = 0b00011100; // početna vrijednost

PORTB |= (1<<0) | (1<<6) | (1<<7); //

PORTB == 0b1011101; // rezultat

Resetovanje (nuliranje) pojedinačnih bitova

Za resetiranje jednog bita, koriste se tri prethodno razmatrane naredbe odjednom: .

Resetujmo 3. bit registra PORTC i ostavimo ostatak nepromijenjen.

PORTC = 0b00011100;

PORTC &= ~(1<<3);

PORTC == 0b00010100;

Izvršimo slične radnje za 2. i 4. cifru:

PORTC = 0b00111110;

PORTC &= ~((1<<2) | (1<<4));

PORTC == 0b00101010;

Prebacivanje ritma

Pored podešavanja i resetovanja, koristi se i korisna komanda koja prebacuje jedan bit u suprotno stanje: jedan na nulu i obrnuto. Ova logična operacija se široko koristi u izgradnji različitih svjetlosnih efekata, na primjer, kao što je novogodišnji vijenac. Razmotrimo primjer PORTA-e

PORTA = 0b00011111;

PORTA ^= (1<<2);

PORTA == 0b00011011;

Promijenite stanje nulte, drugog i šestog bita:

PORTA = 0b00011111;

PORTA ^= (1<<0) | (1<<2) | (1<<6);

PORTA == 0b01011010;

Provjera statusa pojedinačnog bita. Da vas podsjetim da se provjera (za razliku od pisanja) I/O porta vrši čitanjem podataka iz PIN registra.

Najčešći test se izvodi pomoću jedne od dvije izjave petlje: if i while. Ranije smo već upoznati sa ovim operaterima.

Provjera pražnjenja na prisutnost logičke nule (resetiranje) sa ako

ako (0==(PIND & (1<<3)))

Ako je treći bit porta D obrisan, izvršava se Code1. U suprotnom, Code2 se izvršava.

Slične radnje se izvode sa i u ovom obliku snimanja:

ako (~PIND & (1<<3))

Provjera pražnjenja na prisutnost logičke jedinice (postavke) s ako

ako (0 != (PIND & (1<<3)))

ako (PIND & (1<<3))

Gore navedene dvije petlje rade slično, ali zbog fleksibilnosti programskog jezika C, mogu se napisati drugačije. Operacija != znači da nije jednaka. Ako je treći bit PD I/O porta postavljen (jedan), tada se izvršava Code1, ako nije, Code2.

Čeka se malo resetovanje sa dok

dok (PIND & (1<<5))

Code1 će se izvršavati sve dok je 5. bit PIND registra postavljen. Resetovanjem će početi izvršavanje Code2.

Čeka se postavljanje bita dok

Ovdje vam sintaksa jezika C omogućava pisanje koda na dva najčešća načina. U praksi se koriste obje vrste snimanja.