Programmēšanas mikrokontrolleru secība avr. avr mikrokontrollera programmēšana

Laba diena dārgie radio amatieri!
Es sveicu jūs vietnē ""

Kas ir mikrokontrolleris un kāpēc tas ir vajadzīgs. Apskatīsim tā definīciju:

- mikroshēma, kas paredzēta elektronisko ierīču vadīšanai, vai citā veidā - vienkāršs dators (mikrodators), kas spēj veikt vienkāršus uzdevumus.

Tas ir, patiesībā mikrokontrolleris ir ierīce, kas ļauj realizēt mūsu idejas (pat trakās), bet, protams, savu iespēju robežās. Un pats galvenais, idejas realizācija tiek panākta nevis veidojot sarežģītas elektroniskas struktūras, bet tikai, būtībā, ar mūsu domu spēku (vai tu vēlētos kļūt par burvi?).
Radioamatieru vidū populārākie ir divu veidu mikrokontrolleri:
PIC- Mikročipu tehnoloģija
AVR- Atmel

Es gribētu izdarīt nelielu atkāpi un precizēt vienu no savām pozīcijām. Es nerunāšu par šī vai cita veida mikrokontrolleru, šīs vai citas programmatūras un vispār visu, kas saistīts ar mikrokontrolleriem, priekšrocības, lai kaut ko ieteiktu un vēl jo vairāk - uzspiestu lasītājiem. Tas viss ir atkarīgs no gaumes, personīgās izvēles un jūsu galīgajiem mērķiem mikrokontrolleru apguvē. Tā kā “neaptveramību nevar aptvert”, es vadīšu visu savu turpmāko stāstījumu saistībā ar AVR mikrokontrolleriem un, kas nav ļoti izplatīta, bet mana iecienītākā programma “Algoritm Builder”. Dažādiem mikrokontrolleru veidiem, programmām, protams, ir atšķirības, taču tām ir arī daudz kopīga. Un mēs apgūsim mikrokontrolleru pasauli tā, lai vēlāk iegūtās zināšanas bez problēmām varētu pielietot PIC un jebkurai programmatūrai. Un vēlreiz atgādināšu, ka šī rakstu sērija ir mans mēģinājums palīdzēt tiem, kuri pirmo reizi dzirdēja par mikrokontrolleru esamību un vēlas saprast, kā ar tiem strādāt.

Kas jums ir nepieciešams, lai uzzinātu, kā strādāt ar mikrokontrolleriem? Es izceltu dažus, manuprāt, galvenos nosacījumus:
1. Vēlme un neatlaidība .
Šeit viss ir ļoti vienkārši: ir vēlme - viss izdosies. Un vēlme ar neatlaidību vispār ir super lieta.
2. Zināšanas par mikrokontrollera ierīci.
Padziļinātas zināšanas šeit nav svarīgas (un varbūt nemaz nav vajadzīgas), taču ir jāzina, kas ir “uz mikrokontrollera”. Tikai zinot, no kā sastāv mikrokontrolleris, kādas tam ir ierīces, to iespējas, kā tās darbojas – tikai tad mēs varēsim pilnībā izmantot mikrokontrollera iespējas.
3. Programmēšanas valodas un mikrokontrollera vadības komandu zināšanas.
To, kā mikrokontrolleris darbosies, kādus uzdevumus tam piešķirsiet un kā tas tos veiks, nosaka tajā iegultā programma - programma, kuru jūs pats veidojat mikrokontrollerim. Un mēs pie šī punkta pakavēsimies sīkāk, lai apsvērtu problēmas, kas varētu rasties nākotnē.

Programma(tulkojumā šis vārds nozīmē “recepte”) - gaidāmo notikumu vai darbību provizorisks apraksts.

Piemēram, mēs vēlamies, lai mikrokontrolleris mirgo gaismas diode. Vienkāršs uzdevums, bet tomēr, lai mikrokontrolleris šo uzdevumu izpildītu, vispirms soli pa solim jāapraksta visas mikrokontrollera darbības, jāuzraksta programma, kas tai jāizpilda, lai iegūtu mums vajadzīgo rezultātu – mirgojošu LED. . Kaut kas tamlīdzīgs:
♦ Iedegas LED:
- konfigurējiet izeju, kurai ir pievienota gaismas diode, lai strādātu ar informācijas izvadi
- pielieciet šai tapai loģisko līmeni, kas ļaus iedegt LED
♦ Pagaidiet kādu laiku:
- dodieties uz apakšprogrammu, kas veido pauzi (kas arī ir "jākošļā")
- pēc pauzes apakšprogrammas pabeigšanas atgriezieties galvenajā programmā
♦ Izslēdziet LED:
- pielietojiet izvadei loģisko līmeni, nodzēšot LED
utt.
ar terminu Programma cits termins ir nesaraujami saistīts - Algoritms(piemēram, Vilks un zaķis, Toms un Džerijs).

Algoritms- instrukciju kopums, kas apraksta vēlamā rezultāta sasniegšanas procedūru.

Ja programmā esam visdetalizētākajā veidā noteikt darbības mikrokontrolleris, tad algoritmā mēs noteikt darbības virzienu mikrokontrolleris, uz kura pamata mēs pēc tam izveidosim programmu. Līdzīgi kā iepriekš minētajā piemērā:
♦ Iededziet LED
♦ Pagaidi mazliet
♦ Izslēdziet LED
utt.
Tādējādi algoritms ir programmas priekštecis. Un jo rūpīgāk un pārdomātāk tiks izveidots algoritms, jo vieglāk būs izveidot programmu.

Kopumā programma mikrokontrolleram ir mikrokontrollera darbību secība komandu un instrukciju kopas veidā, kas tai jāizpilda, lai sasniegtu mūsu mērķus.

Mikrokontrollera komandas izskatās kā vieninieku un nulles kopa:
00110101 011000100
tā sauktais - komandu kodi, un komandu kodi ir valoda, ko saprot mikrokontrolleris. Un, lai tulkotu mūsu algoritmu no krievu valodas mikrokontrollera valodā - tieši šajās nulles un vieninieku kopās, ir īpašas programmas.
Šīs programmas ļauj mums vairāk vai mazāk saprotamā valodā aprakstīt mikrokontrollera darbības secību un pēc tam šo secību pārtulkot mikrokontrollerim saprotamā valodā, kā rezultātā veidojas t.s. mašīnas kods- komandu un instrukciju secība (pašas nulles un vieninieki), ko saprot tikai mikrokontrolleris. Programmētāja rakstīto programmas tekstu sauc avota kods. Programma tiek tulkota no programmēšanas valodas (avota koda) mikrokontrollera valodā (mašīnas kods) tulkotāji. Tulkotājs pārvērš programmas tekstu mašīnkodos, kas pēc tam tiek ierakstīti mikrokontrollera atmiņā.
Šādās programmās mikrokontrollera darbības kārtību apraksta īpaša valoda - programmēšanas valoda. Programmēšanas valoda atšķiras no mūsu cilvēku valodas. Ja mūsu saziņas valoda galvenokārt ir paredzēta informācijas apmaiņai, tad:

Programmēšanas valoda - tas ir komandu, instrukciju pārsūtīšanas veids, skaidrs mikrokontrollera darbības ceļvedis.

Ir daudz programmēšanas valodu, un tās var iedalīt divos veidos:
zema līmeņa programmēšanas valodas
augsta līmeņa programmēšanas valodas
Kāda ir atšķirība. Un tie atšķiras ar to tuvumu mikrokontrolleram.
Mikroprocesoru tehnoloģiju rašanās rītausmā programmas tika rakstītas mašīnkodos, tas ir, viss darba algoritms tika secīgi uzrakstīts nulles un vieninieku formā. Programma izskatījās šādi:

01000110
10010011
01010010

Maz ticams, ka kāds spēs izdomāt šādu divu skaitļu kombināciju komplektu, un pirmo programmētāju darbs bija ļoti darbietilpīgs. Lai atvieglotu viņu dzīvi, programmētāji sāka radīt pirmās programmēšanas valodas. Tātad, jo tuvāk programmēšanas valoda ir šādai nulles un vieninieku kopai, jo tas ir “zemāks” un jo tālāk no tiem, jo ​​vairāk “augsts līmenis”.
Visizplatītākās mikrokontrolleru programmēšanas valodas:
- zema līmeņa valoda - montētājs
- augsta līmeņa valoda, C (Ci)
Apskatīsim piemēru to atšķirībai (šie piemēri ir abstrakti).
Pieņemsim, ka mums ir jāpievieno divi skaitļi: 25 un 35.
Vietējā kodā šī komanda varētu izskatīties šādi:
00000101 1101001
Zema līmeņa valodā:
ADD Rd, Rr
Augsta līmeņa valodā:
25+35
Atšķirība starp zema līmeņa un augsta līmeņa valodām ir redzama ar neapbruņotu aci, komentāri, kā saka, ir lieki.
Bet iedziļināsimies šajos piemēros. Mēs neanalizēsim mašīnas koda piemēru, jo tas ir identisks piemēram montētājā. Asamblejas instrukcijas pamatā ir tie paši mašīnu kodi (komandas), kuriem vienkārši tiek piešķirti burtu saīsinājumi, lai nepazustu nullēs un vieniniekos. Izmantojot komandu ADD Rd, Rr assembler, mēs iestatām mikrokontrolleri, lai tas saskaita divus atrastos skaitļus (un šim nolūkam tie vispirms ir jāieraksta tur) - pirmais Rd, otrais Rr un ievieto saskaitīšanas rezultātu Rd. Kā redzat, mēs uzstādījām ļoti konkrētu uzdevumu mikrokontrolleram: kur to iegūt, ko ar to darīt un kur likt rezultātu. Šajā gadījumā mēs strādājam tieši ar mikrokontrolleri.
Komanda augsta līmeņa valodā: 25+35 , mums pazīstams, mūsu acij tīkams matemātiskais apzīmējums. Bet šajā gadījumā mēs nestrādājam tieši ar mikrokontrolleri, mēs vienkārši uzstādām tam uzdevumu pievienot divus skaitļus. Rezultāts un darbību secība šajā gadījumā būs tāda pati kā, izpildot assembler komandu: vispirms šie divi skaitļi tiks kaut kur ierakstīti, pēc tam summēti un rezultāts kaut kur ievietots.
Un šeit ir galvenā atšķirība starp augsta līmeņa un zema līmeņa valodām. Ja Assembler mēs kontrolējam visu procesu (patīk vai nē): mēs zinām, kur šie divi skaitļi ir rakstīti, un mēs zinām, kur būs rezultāts, tad augsta līmeņa valodā mēs nekontrolējam procesu. Programma pati izlemj, kur iepriekš ierakstīt skaitļus un kur ievietot rezultātu. Vairumā gadījumu mums tas nav jāzina, jo mums galvenais rezultāts ir skaitlis 60 izvadē. Rezultātā programmas augsta līmeņa valodās ir lasāmākas, acij tīkamas un mazāka izmēra – galu galā mums nav “jākāpj visās bedrēs” un jākrāso katrs mikrokontrollera, programmas solis. izdara to vēlāk mūsu vietā, kad tas to kompilē – pārvērš to mašīnkodos. Bet ir arī mīnuss. Diviem vienādiem algoritmiem, kas rakstīti assemblerā un C valodā, pēc to pārvēršanas mašīnkodos, būs atšķirīgs izmērs: assemblerā rakstīta programma būs par 20-40% īsāka nekā programma, kas rakstīta C valodā - velns zina, uz kuru pusi iet C. sasniegt mums vajadzīgo rezultātu. Un ir gadījumi, kad augsta līmeņa valodai nav uzticības un C programmā viņi ievieto Assembler rakstītu kodu.
Profesionāli programmētāji, kā likums, zina vairākas programmēšanas valodas (vai strādā komandā, kurā ir dažādu valodu speciālisti), radoši apvienojot to iespējas un priekšrocības vienā programmā. Nu, mums, amatieriem, ir jāzina vismaz viena valoda (iesākumam), un mums ir jāsāk (un es par to esmu stingri pārliecināts, un neviens mani nepārliecinās) no zema līmeņa valodas - asamblejas.

Nu, es domāju, un šeit mums viss ir skaidrs - jums ir jāiemācās programmēšanas valoda, savādāk - nekādi.

Komandas un instrukcijas mikrokontrollera vadīšanai.
AVR mikrokontrolleriem ir vairāk nekā 130 dažādas komandas, kas ļauj realizēt visas tam piemītošās iespējas. Bet es uzreiz teikšu, ka daži amatieri tos visus zina, nemaz nerunājot par to visu izmantošanu. Parasti amatieru praksē zināšanu pietiek un pusei no komandām vai pat mazāk. Bet jums ir jāiemācās komandas. Jo vairāk komandu jūs zināt, jo sarežģītākas (šā vārda labā nozīmē) un elegantākas būs programmas.

Aritmētiskā loģiskā vienība un atmiņas organizācija - programmu atmiņa, datu atmiņa, nepastāvīgā atmiņa



Šajā apmācībā par avr es mēģināju aprakstīt visas visvienkāršākās lietas iesācējiem mikrokontrolleru programmēšanai. avr. Visi piemēri ir veidoti uz mikrokontrollera atmega8. Tas nozīmē, ka, lai atkārtotu visas nodarbības, jums būs nepieciešams tikai viens MK. Kā elektroniskās shēmas emulators tiek izmantots Proteus - manuprāt, labākais risinājums iesācējiem. Visos piemēros esošās programmas ir rakstītas avr CodeVision AVR C kompilatorā. Kāpēc ne kādā montētājā? Jo iesācējs jau ir piekrauts ar informāciju, un programma, kas reizina divus skaitļus, aizņem apmēram simts rindiņas assemblerā, un viņi izmanto C sarežģītos treknajos projektos CodeVision AVR kompilators ir uzasināts atmel mikrokontrolleriem, ir ērts kodu ģenerators, a labs interfeiss un tieši no tā var pazibināt ar mikrokontrolleri.

Šī apmācība parādīs un ar vienkāršiem piemēriem izskaidros, kā:

  • Sāciet programmēt mikrokontrollerus, kur sākt, kas jums nepieciešams.
  • Kādas programmas izmantot, lai rakstītu AVR programmaparatūru, simulētu un atkļūdotu kodu datorā,
  • Kādas perifērijas ierīces atrodas MK, kā tās vadīt, izmantojot savu programmu
  • Kā uzrakstīt gatavo programmaparatūru mikrokontrollerī un kā to atkļūdot
  • Kā izveidot PCB savai ierīcei
Lai spertu pirmos soļus MK programmēšanas virzienā, ir nepieciešamas tikai divas programmas:
  • Proteus ir emulatora programma (tajā varat izveidot shēmu, neizmantojot īstu lodēšanu, un pēc tam pārbaudīt mūsu programmu šajā shēmā). Vispirms palaidīsim visus projektus Proteusā, un tad jau varēsim pielodēt īstu ierīci.
  • CodeVisionAVR ir C programmēšanas valodas kompilators AVR. Tajā mēs izstrādāsim programmas mikrokontrolleram, un tieši no tā būs iespējams uzzibsnīt īstu MK.
Pēc Proteus instalēšanas palaidiet to
Viņš piedāvā apskatīt projektus, kas viņam iet, mēs pieklājīgi atsakāmies. Tagad izveidosim tajā visvienkāršāko shēmu. Lai to izdarītu, noklikšķiniet uz ikonas vizuāli nekas nenotiek. Tagad jums jānoklikšķina uz mazā burta R (izvēlēties no bibliotēkas) komponentu saraksta panelī tiks atvērts komponentu atlases logs
maskas laukā ievadiet tā komponenta nosaukumu, kuru vēlamies atrast bibliotēkā. Piemēram, mums jāpievieno mega8 mikrokontrolleris
rezultātu sarakstā iedur mega8 un nospiediet pogu labi. Komponentu sarakstā mums ir mikrokontrolleris mega8
Tādējādi mēs pievienojam vēl vienu rezistoru komponentu sarakstam, ievadot vārdu maskas laukā res un LED vadīja

Lai diagrammā novietotu daļas, noklikšķiniet uz detaļas, pēc tam noklikšķiniet uz diagrammas lauka, atlasiet komponenta atrašanās vietu un noklikšķiniet vēlreiz. Lai pievienotu zemējumu vai kopējo mīnusu ķēdei kreisajā pusē, noklikšķiniet uz "Termināls" un atlasiet Zemējums. Tādējādi, pievienojot visas sastāvdaļas un savienojot tās, mēs iegūstam tik vienkāršu shēmu
Viss, tagad mūsu pirmā shēma ir gatava! Bet jūs varētu jautāt, ko viņa var darīt? Bet nekā. Nekas, jo, lai mikrokontrolleris strādātu, ir jāraksta tam programma. Programma ir to instrukciju saraksts, kuras izpildīs mikrokontrolleris. Mums ir nepieciešams mikrokontrolleris, kas jāuzstāda uz kājas PC0 loģika 0 (0 volti) un loģika 1 (5 volti).

Programmas rakstīšana mikrokontrolleram

Programmu rakstīsim C valodā, izmantojot CodeVisionAVR kompilatoru. Pēc CV palaišanas tas jautā mums, ko mēs vēlamies izveidot: avotu vai projektu Mēs izvēlamies pēdējo un nospiediet pogu Labi. Tālāk mums tiks lūgts palaist CVAVR CodeWizard (tas ir nenovērtējams rīks iesācējam, jo ​​tas var ģenerēt programmas galveno skeletu) izvēlēties
Vednis sākas ar aktīvo cilni Chip, šeit mēs varam izvēlēties mūsu MK modeli - tas ir mega8, un frekvenci, ar kādu MK darbosies (pēc noklusējuma mega8 ir iestatīts uz 1 megahercu), tāpēc mēs iestatām visu, kā parādīts attēlā. augstāk redzamajā ekrānuzņēmumā. Dodieties uz cilni Ports
Atmega8 mikrokontrolleram ir 3 porti: ports C, ports D, ports B. Katram portam ir 8 kontakti. Portu tapas var būt divos stāvokļos:
  • Izvade
Ar DDRx.y reģistra palīdzību mēs varam iestatīt tapu kā ievadi vai izvadi. Ja iekšā
  • DDRx.y = 0 - izvade darbojas kā IEEJA
  • DDRx.y = 1 tapa darbojas IZEJA
Kad tapa ir konfigurēta kā izeja, mēs varam iestatīt to uz loģisko 1 (+5 volti) un loģisko 0 (0 volti). Tas tiek darīts, rakstot uz PORTx.y reģistru. Tālāk tiks detalizēti apspriests ievades-izejas porti. Un tagad mēs iestatām visu, kā parādīts ekrānuzņēmumā, un noklikšķiniet uz Fails-> Ģenerēt, saglabāt un iziet. Tālāk CodeWizard piedāvās mums saglabāt projektu, mēs to saglabājam un skatāmies kodu:

#iekļauts //bibliotēka laika aizkaves izveidei void main(void) ( PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x01; // padarīt PC0 kājas izvadi PORTD=0x00; DDRD=0x00; // Timer/Counter 0 inicializācija TCCR0=0x00; TCNT0=0x00; // Taimeris/Counter 1 inicializācija TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0xCR00; OxAL001ACH ; OCR1BL=0x00; // Taimera/Counter 2 inicializācija ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // Ārējo pārtraukumu(-u) inicializācija MCUCR=0x00; // Taimeris(-i)/skaitītājs(-i) ) Pārtraukumu(-u) inicializācija TIMSK=0x00; // Analog Comparator inicializācija ACSR=0x80; SFIOR=0x00; kamēr (1) ( ); )


Šeit viss jums var šķist biedējošs un nepazīstams, bet patiesībā viss nav tā. Kodu var vienkāršot, izmetot to MK perifērijas ierīču inicializāciju, kuras mēs neizmantojam. Pēc vienkāršošanas tas izskatās šādi:

#iekļauts //bibliotēka darbam ar mikrokontrolleri mega8 #include //bibliotēka laika aizkaves izveidei void main(void) ( DDRC=0x01; /* padarīt PC0 kāju izvades ierakstam 0x01 jums var šķist nepazīstams, un tas ir tikai cipars 1 heksadecimālā veidā, šī rinda būs līdzvērtīga 0b00000001 binārā, tad es rakstīšu tieši šādi. */ kamēr (1) ( ); )


Lietas ir labi. Bet, lai LED mirgotu, mums ir jāmaina PC0 kājas loģikas līmenis. Lai to izdarītu, galvenajai cilpai pievienojiet dažas rindiņas:

#iekļauts //bibliotēka darbam ar mikrokontrolleri mega8 #include //bibliotēka laika aizkaves izveidei void main(void) ( DDRC=0x01; /* padarīt PC0 kāju izvades ierakstam 0x01 jums var šķist nepazīstams, un tas ir tikai cipars 1 heksadecimālā veidā, šī rinda būs līdzvērtīga 0b00000001 binārā, tad es rakstīšu tieši šādi.*/ while (1)//galvenā programmas cilpa (// galvenās programmas cilpas operatora iekava atver PORTC.0=1; //iestatiet portu C 1 uz pin 0 delay_ms(500); //veiciet aizkavi 500 milisekundēs PORTC.0=0; // iestatiet portu C 0 uz pin 0 delay_ms(500); // veiciet 500 milisekundes aizkavi );// aizveriet operatora iekava no galvenās programmas cilpas)


Viss, tagad kods ir gatavs. Mēs noklikšķiniet uz ikonas Veidot visus projekta failus, lai apkopotu (tulkot MK procesora instrukcijās) mūsu programmu. Exe mapē, kas atrodas mūsu projektā, vajadzētu parādīties failam ar hex paplašinājumu, tas ir mūsu programmaparatūras fails MK. Lai mūsu programmaparatūru ievadītu Proteus virtuālajā mikrokontrollerā, jums ir jāveic dubultklikšķis uz Proteus mikrokontrollera attēla. Parādīsies šāds logs
noklikšķiniet uz mapes ikonas laukā Programmas fails, atlasiet hex - mūsu programmaparatūras failu un nospiediet pogu Labi. Tagad mēs varam palaist mūsu ķēdes simulāciju. Lai to izdarītu, Proteus loga apakšējā kreisajā stūrī noklikšķiniet uz pogas "Atskaņot".

Vairāk nekā vienu vai divas reizes esmu teicis, ka MK izpēte jāsāk ar montētāju. Tam tika veltīts vesels vietnes kurss (lai gan tas nav īpaši konsekventi, bet pakāpeniski es to izķemmēju līdz adekvātam izskatam). Jā, tas ir grūti, rezultāts nebūs pirmajā dienā, bet jūs iemācīsities saprast, kas notiek jūsu kontrolierī. Jūs zināt, kā tas darbojas, nevis kopēt citu cilvēku avotus kā mērkaķis un mēģināt saprast, kāpēc tas pēkšņi pārstāja darboties. Turklāt C ir daudz vieglāk sajaukt ar redneck kodu, kas visnepiemērotākajā brīdī iznāks ar dakšiņu.

Diemžēl visi vēlas rezultātus nekavējoties. Tāpēc nolēmu iet citu ceļu - uztaisīt pamācību par C, bet ar viņa apakšveļas demonstrāciju. Labs iegulšanas programmētājs vienmēr cieši tur savu dzelzs gabalu pie dravītes, neļaujot tam bez atļaujas spert nevienu soli. Tātad, kas vispirms būs C kods, pēc tam ko kompilators dzemdēja un kā tas viss darbojas realitātē :)

No otras puses, C stiprā puse ir koda pārnesamība. Ja, protams, visu uzrakstīt pareizi. Darba algoritmu un to dzelžaino implementāciju sadalīšana dažādās projekta daļās. Tad, lai pārsūtītu algoritmu uz citu MK, pietiks pārrakstīt tikai interfeisa slāni, kurā ierakstīta visa pieeja aparatūrai, un atstāt visu darba kodu tādu, kāds tas ir. Un, protams, lasāmība. Sish pirmkods ir vieglāk saprotams no pirmā acu uzmetiena (lai gan .. piemēram, man ir vienalga, ko uzsist - vismaz si, vismaz asm :)), bet atkal, ja viss ir uzrakstīts pareizi. Es arī pievērsīšu uzmanību šiem punktiem.

Kā eksperimentāls dzelzs gabals, uz kura tiks novietota lauvas tiesa no visiem piemēriem, būs mana atkļūdošanas dēlis.

Pirmā C programma AVR

Kompilatora izvēle un vides instalēšana
AVR ir daudz dažādu C kompilatoru:
Pirmkārt, šis IAR AVR C- gandrīz viennozīmīgi atzīts par labāko AVR kompilatoru, tk. pats kontrolieris tika izveidots, cieši sadarbojoties Atmel un IAR speciālistiem. Bet par visu ir jāmaksā. Un šis kompilators ir ne tikai dārga komerciāla programmatūra, bet arī tam ir tik daudz iestatījumu, ka jums vienkārši ir smagi jāstrādā, lai to tajā apkopotu. Man ar viņu īsti nebija draudzības, projekts sapuva dīvainu kļūdu dēļ saistīšanas stadijā (vēlāk uzzināju, ka tā bija greiza plaisa).

Otrais iet WinAVR GCC ir spēcīgs optimizācijas kompilators. Pilna atvērtā koda, starpplatformu, kopumā visi dzīves prieki. Tas arī lieliski integrējas AVR Studio, ļaujot atkļūdot tieši tur, kas ir ellīgi ērti. Kopumā es to izvēlējos.

Arī ir CodeVision AVR C ir ļoti populārs kompilators. Tas kļuva populārs savas vienkāršības dēļ. Jūs varat iegūt darba programmu dažu minūšu laikā - sākuma koda vednis to ievērojami veicina, apzīmogojot jebkuras uarts inicializācijas standartus. Ja godīgi, es pret viņu kaut kā izturos ar aizdomām - reiz nācās izjaukt šī kompilatora rakstīto programmu, sanāca kaut kāda putra nevis kods. Šausmīgi daudz nevajadzīgu žestu un darbību, kā rezultātā tika iegūts diezgan liels koda daudzums un lēna veiktspēja. Tomēr, iespējams, sākotnējā programmaparatūras rakstītāja DNS bija kļūda. Turklāt viņš grib naudu. Ne tik daudz kā IAR, bet pamanāms. Un demonstrācijas režīmā tas ļauj rakstīt ne vairāk kā 2 kb koda.
Protams ir plaisa, bet ja zog, tad miljonu, IAR izpratnē :)

Ir arī Image Craft AVR C un MicroC no mikroelektronikas. Nav nācies to izmantot, bet... SWGļoti daudz uzslavu mikropaskāls, saka, šausmīgi ērta programmēšanas vide un bibliotēkas. Domāju, ka MicroC būs ne sliktāks, bet arī apmaksāts.

Kā jau teicu, es izvēlējos WinAVR Trīs iemeslu dēļ: bezmaksas, tas integrējas AVR Studio, un tam ir rakstīts tikai virkne gatavu kodu visiem gadījumiem.

Tāpēc lejupielādējiet WinAVR ar un AVR Studio. Tālāk vispirms tiek instalēta studija, pēc tam no augšas WinAVR sarullējas un piekļaujas studijai spraudņa veidā. Es ļoti iesaku likt WinAVR uz īsa ceļa, piemēram, C:\WinAVR, tādējādi jūs izvairīsities no daudzām problēmām ar ceļiem.

Projekta izveide
Tātad, studija izveidota, C pieskrūvēts, laiks mēģināt kaut ko ieprogrammēt. Sāksim ar vienkāršāko, vienkāršāko. Palaidiet studiju, atlasiet jaunu projektu kā AVR GCC kompilatoru un ievadiet projekta nosaukumu.

Darbvieta tiek atvērta ar tukšu *.c failu.

Tagad nav par ļaunu konfigurēt ceļu parādīšanu studijas grāmatzīmēs. Lai to izdarītu, dodieties uz:
Izvēlnes rīki — Opcijas — Vispārīgi — Failu cilnes un nolaižamajā sarakstā atlasiet Tikai faila nosaukums. Pretējā gadījumā nebūs iespējams strādāt - cilnē būs pilns faila ceļš, un ekrānā būs ne vairāk kā divas vai trīs cilnes.

Projekta iestatīšana
Kopumā tiek uzskatīts, ka ir klasisks izveidot make failu, kurā būtu aprakstītas visas atkarības. Un tas droši vien ir pareizi. Bet man, kas uzauga ar pilnībā integrētiem IDE, piemēram uVision vai AVR studijašī pieeja ir dziļi sveša. Tāpēc es to darīšu savā veidā, ar visiem studijas līdzekļiem.

Noklikšķiniet uz zobrata pogas.


Šie ir jūsu projekta iestatījumi vai, pareizāk sakot, make faila automātiskās ģenerēšanas iestatījumi. Pirmajā lapā jums vienkārši jāievada frekvence, kādā jūsu MK darbosies. Tas ir atkarīgs no drošinātāju bitiem, tāpēc mēs pieņemam, ka frekvence ir 8000000Hz.
Pievērsiet uzmanību arī optimizācijas līnijai. Tagad ir -Os ir izmēra optimizācija. Pagaidām atstājiet to kā ir, tad varat mēģināt paspēlēties ar šo parametru. -O0 nav nekāda optimizācija.

Nākamais solis ir izveidot ceļus. Pirmkārt, pievienojiet tur sava projekta direktoriju - jūs tur ievietosit trešo pušu bibliotēkas. Ceļš ".\" parādīsies sarakstā

Make fails ir ģenerēts, jūs varat to apskatīt sava projekta noklusējuma mapē, vienkārši ieskatieties, skatiet, kas tur ir.


Tas pagaidām ir viss. Visur noklikšķiniet uz Labi un dodieties uz avotu.

Problēmas formulēšana
Tukšs šīferis vilina iemiesot kaut kādu viltīgu ideju, jo diodes banālā mirgošana vairs neievietojas. Nekavējoties ķersim vērsim pie ragiem un ieviesīsim savienojumu ar datoru – tas ir pirmais, ko daru.

Tas darbosies šādi:
Kad iekārta nonāks COM portā (kods 0x31), mēs ieslēgsim diodi, un, kad pienāks nulle (kods 0x30), mēs to dzēsīsim. Turklāt viss tiks darīts ar pārtraukumiem, un fona uzdevums būs citas diodes mirgošana. Vienkārši un jēgpilni.

Shēmas salikšana
Mums ir jāpievieno USB-USART pārveidotāja modulis ar mikrokontrollera USART tapām. Lai to izdarītu, mēs ņemam divu vadu džemperi un novietojam tos uz tapām šķērsām. Tas ir, mēs savienojam kontroliera Rx ar pārveidotāja Tx un pārveidotāja Tx ar kontroliera Rx.

Izrādās, ka šī ir shēma:


Es nedomāju pievienot atlikušās izejas, barošanas avotu, atiestatīt, tas ir standarts

Mēs rakstām kodu

Uzreiz izdarīšu atrunu, ka īpaši neiedziļināšos pašas C valodas aprakstā. Lai to izdarītu, ir vienkārši milzīgs daudzums materiālu, sākot no klasiskās "C programmēšanas valodas" no K&R līdz dažādām rokasgrāmatām.

Viena šāda metode tika atrasta manā krātuvē, es reiz pētīju šo valodu, izmantojot to. Viss ir īss, skaidrs un precīzs. Es to pakāpeniski ierakstu un velku uz savu vietni.

Tiesa, visas nodaļas vēl nav tur pārceltas, bet domāju, ka tas nav uz ilgu laiku.

Maz ticams, ka es aprakstīšu labāk, tāpēc no apmācības kursa tā vietā, lai detalizēti izskaidrotu Cish sarežģītību, es vienkārši sniegšu tiešas saites uz atsevišķām šīs rokasgrāmatas lapām.

Bibliotēku pievienošana.
Pirmkārt, mēs pievienojam nepieciešamās bibliotēkas un galvenes ar definīcijām. Galu galā C ir universāla valoda, un ir jāpaskaidro, ka mēs strādājam ar AVR, tāpēc ievadiet rindu avota kodā:

1 #iekļauts

#iekļauts

Šis fails atrodas mapē WinAVR un tajā ir visu kontroliera reģistru un portu apraksts. Un tur viss ir sarežģīti, atsaucoties uz konkrētu kontrolieri, kuru kompilators pārraida cauri veidot fails parametrā MCU un pamatojoties uz šo mainīgo, jūsu projektam ir pievienots galvenes fails ar visu šī konkrētā kontrollera portu un reģistru adrešu aprakstu. Kā! To var izdarīt arī bez tā, taču tad nevarēsit izmantot simboliskus reģistru nosaukumus, piemēram, SREG vai UDR, un būs jāatceras katra adrese, piemēram, "0xC1", un tas ir galvassāpes.

Tā pati komanda #iekļauts<имя файла> ļauj projektam pievienot jebkura teksta faila saturu, piemēram, failu ar funkciju aprakstu vai cita koda fragmentu. Un, lai direktīva varētu atrast šo failu, mēs norādījām ceļus uz mūsu projektu (WinAVR direktorijs jau ir reģistrēts tur pēc noklusējuma).

galvenā funkcija.
C programmā ir visas funkcijas. Tos var ligzdot un izsaukt vienu no otra jebkurā secībā un dažādos veidos. Katrai funkcijai ir trīs obligātie parametri:

  • Atdeves vērtība, piemēram, grēks (x) atgriež x sinusa vērtību. Kā matemātikā, īsumā.
  • Pārsūtītie parametri, tas pats x.
  • Funkciju korpuss.

Visām nodotajām un atgrieztajām vērtībām ir jābūt noteikta veida atkarībā no datiem.

Katrā C programmā ir jābūt funkcijai galvenais kā ieejas punkts galvenajai programmai, citādi tas nemaz nav C :). Pēc galvenā klātbūtnes kāda cita avota kodā no miljoniem failu, jūs varat saprast, ka šī ir galvenā programmas daļa, no kuras viss sākas. Šeit mēs iestatīsim:

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

int main(void) (atgriež 0; )

Tas arī viss, ir uzrakstīta pirmā vienkāršākā programma, nav svarīgi, ka tā neko nedara, mēs esam tikai sākuši.

Paskatīsimies, ko mēs izdarījām.
starpt ir datu tips, ko atgriež galvenā funkcija.

Protams, mikrokontrollerī galvenais principā neko nevar atdot, un teorētiski tā arī vajadzētu būt nederīgs galvenais (neesošs), bet GCC sākotnēji ir asināts datorā, un tur programma pēc pabeigšanas var atgriezt vērtību operētājsistēmai. Tāpēc GCC ieslēgts nederīgs galvenais (neesošs) zvēr ar Brīdinājumu.

Tā nav kļūda, derēs, bet man nepatīk brīdinājumi.

nederīgsŠis ir datu veids, ko mēs nododam funkcijai, šajā gadījumā galvenais arī nevar pieņemt neko no ārpuses, dzejnieks nederīgs- tukšs. Stubs tiek izmantots, ja nekas nav jānodod vai jāatdod.

Šeit ir šie { } cirtaini iekavas ir programmas bloks, šajā gadījumā funkcijas pamatteksts galvenais, kods atradīsies tur.

atgriezties- šī ir atgriešanas vērtība, ko galvenā funkcija sniegs beigās, jo mums ir int, tas ir, skaitlis, tad mums ir jāatgriež skaitlis. Lai gan joprojām nav jēgas, jo. uz mikrokontrollera no galvenā, mēs varam tikai nekur iet. Es atgriežu nulli. Par nefig. Un kompilators parasti ir gudrs un šim gadījumam kodu neģenerē.
Lai gan, ja perverss, tad no galvenais jūs varat doties uz MK - piemēram, izkrist bootloader sadaļā un izpildīt to, bet šeit jau būs nepieciešama programmaparatūras izvēle zemā līmenī, lai labotu pārejas adreses. Zemāk jūs redzēsit un sapratīsit, kā to izdarīt. Priekš kam? Tagad tas ir cits jautājums, 99,999% gadījumu tas nav nepieciešams :)

Gatavs, turpini. Pievienosim mainīgo, mums tas nav īsti vajadzīgs un bez tā nevajadzētu ieviest mainīgos, bet mēs mācāmies. Ja mainīgie tiek pievienoti funkcijas pamattekstā, tie ir lokāli un pastāv tikai šajā funkcijā. Izejot no funkcijas, šie mainīgie tiek dzēsti, un RAM atmiņa tiek piešķirta svarīgākām vajadzībām. .

1 2 3 4 5 6 int main(void) (neparakstīts char i; return 0;)

int main(void) (neparakstīta rakstzīme i; return 0; )

neparakstīts nozīmē neparakstīts. Fakts ir tāds, ka binārajā attēlojumā zīmei tiek piešķirts augstais bits, kas nozīmē, ka skaitlis +127/-128 iekļaujas vienā baitā (char), bet, ja zīmi atmet, tas ietilps no 0 līdz 255 Parasti zīme nav vajadzīga. Tā ka neparakstīts.
i ir tikai mainīgais nosaukums. Vairāk ne.

Tagad mums ir jāinicializē porti un UART. Protams, jūs varat paņemt un savienot bibliotēku un izsaukt kaut kādu UartInit (9600); bet tad tu nezināsi, kas īsti notika.

Mēs to darām:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void ) ( unsigned char i; #define XTAL 8000000L #define baudrate 9600L #define bodu dalītāju (XTAL/(16*baudrate)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddalītājs) ; UBRRH = HI(bauddalītājs) ; 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 bodrate 9600L #define boddivider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO (bauddalītājs); UBRRH = HI (bauddalītājs); UCSRA = 0; UCSRB = 1<

Baisi? Patiesībā ir tikai piecas pēdējās reālā koda rindas. Viss, tas #definēt tā ir priekšprocesora makro valoda. Gandrīz tādi paši topi kā Assembler, bet sintakse nedaudz atšķiras.

Tie atvieglos jūsu ikdienas darbības nepieciešamo koeficientu aprēķināšanai. Pirmajā rindā mēs sakām, ka tā vietā XTAL jūs varat droši aizstāt 8000000, un L- tipa indikācija, viņi saka, ka garš ir procesora pulksteņa frekvence. Tas pats pārraides ātrumu- datu pārsūtīšanas biežums, izmantojot UART.

bodu dalītājs jau sarežģītāk, tā vietā tiks aizstāta izteiksme, kas aprēķināta pēc formulas no iepriekšējām divām.
Nu un LO un SVEIKI no šī rezultāta tiks ņemti zemie un augstie baiti, jo tas acīmredzot nevar iekļauties vienā baitā. AT SVEIKI x tiek pārvietots (makro ievades parametrs) astoņas reizes pa labi, kā rezultātā no tā paliks tikai augstais baits. Un iekšā LO mēs veicam bitu UN ar numuru 00FF, kā rezultātā atstājam tikai zemo baitu.

Tātad viss, kas izdarīts, ir kā #definēt jūs varat to droši izmest un aprēķināt nepieciešamos skaitļus kalkulatorā un nekavējoties ievadīt tos rindās UBBRL = .... un UBBRH=…

Var. Bet! Dari šo STRUKTI NEIESPĒJAMI!

Darbosies tā un šitā, bet tev būs t.s burvju skaitļi- vērtības, kas ņemtas no nekurienes, un nav skaidrs, kāpēc, un, ja jūs atverat šādu projektu pēc pāris gadiem, tad būs sasodīti grūti saprast, kas ir šīs vērtības. Un tagad, ja vēlaties mainīt ātrumu, vai mainīt kvarca frekvenci un jums būs viss jāpārrēķina, un tāpēc jūs nomainījāt pāris ciparus kodā un viss. Vispār, ja negribi, lai tevi uzskata par sliktu kodētāju, tad taisi kodu tādu, lai tas būtu viegli lasāms, saprotams un viegli modificējams.

Tad viss ir vienkārši:
Visi šie "UBRLL un Co" ir UART raidītāja konfigurācijas reģistri, ar kuriem mēs sazināsimies ar pasauli. Un tagad mēs esam piešķīruši tiem nepieciešamās vērtības, iestatot tos uz vēlamo ātrumu un vēlamo režīmu.

Skatīt ierakstu 1< Nozīmē sekojošo: paņemiet 1 un ievietojiet to vietā RXEN baitā. RXENšis ir reģistra 4. bits UCSRB, tātad 1< veido bināro skaitli 00010000, TXEN ir 3. bits un 1< dos 00001000. Viens "|" tas ir bitiski VAI, tātad 00010000 | 00001000 = 00011000. Tādā pašā veidā atlikušie nepieciešamie konfigurācijas biti tiek iestatīti un pievienoti kopējai kaudzei. Rezultātā savāktais numurs tiek ierakstīts UCSRB. Tas ir sīkāk aprakstīts MK datu lapā USART sadaļā. Tāpēc nenovērsieties no tehniskajām detaļām.

Gatavs, laiks redzēt, kas notiks. Noklikšķiniet uz kompilācijas un sāciet emulāciju (Ctrl+F7).

Atkļūdošana
Cauri skrēja visādas progresa joslas, mainījās studija un pie galvenās funkcijas ieejas parādījās dzeltena bultiņa. Šeit pašlaik atrodas procesors, un simulācija ir apturēta.

Fakts ir tāds, ka sākotnēji tas bija rindā UBRRL = LO (bauddalītājs); Galu galā tas, kas mums ir definē, nav kods, bet vienkārši provizoriski aprēķini, tāpēc simulators ir nedaudz blāvs. Bet tagad viņš saprata, ka pirmais norādījums ir izpildīts un ja jūs uzkāpjat kokā I/O skats, uz USART sadaļu un paskaties tur UBBRL baitu, redzēsi, ka tur jau ir vērtība! 0x33.

Speriet vēl vienu soli. Paskaties, kā mainīsies cita reģistra saturs. Tāpēc apskatiet tos visus, pievērsiet uzmanību tam, ka visi norādītie biti ir iestatīti tā, kā es jums teicu, un tie tiek iestatīti vienlaikus visam baitam. Tālāk par Atgriešanos lietas netiks – programma ir beigusies.

Atvēršana
Tagad atiestatiet simulāciju uz nulli. Noklikšķiniet tur Atiestatīt (Shift+F5). Atveriet izjaukto sarakstu, tagad redzēsit, kas īsti notiek kontrollerī. Skatīt -> Demontētājs. Un ne YYAAAA!!! Montētājs!!! BRIESMĪGI!!! BET TEV OBLIGĀTI. Lai vēlāk, kad kaut kas noiet greizi, nekļūtu stulbs kodā un neuzdotu forumos stulbākus jautājumus, bet uzreiz iekāptu iekšā un paskatītos, kur jums ir kontaktdakša. Nekā briesmīga tur nav.

Vispirms būs topi no sērijas:

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

Šī ir pārtraukumu vektoru tabula. Mēs pie tā atgriezīsimies vēlāk, pagaidām, paskatieties un atcerieties, ka tas tur ir. Pirmā kolonna ir zibatmiņas šūnas adrese, kurā atrodas komanda, otrā ir komandas kods, trešā komandas mnemonika, tā pati montētāja instrukcija, trešie komandas operandi. Ak, un automātiskais komentārs.
Tātad, ja paskatās, tad ir nepārtrauktas pārejas. Un JMP komandas kods ir četri baiti, tajā ir lēciena adrese, kas rakstīta atpakaļ - zemais baits zemajā adresē un lēciena komandas kods 940C

0000002B: BE1F OUT 0x3F, R1 Out uz I/O atrašanās vietu

Ierakstiet šo nulli adresē 0x3F. Ja skatāties I/O skata kolonnā, redzēsit, ka adrese 0x3F ir SREG reģistra adrese - kontrollera karoga reģistrs. Tie. mēs atiestatām SREG, lai palaistu programmu nulles apstākļos.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Tūlītēja ielāde +0000002D: E0D4 LDI R29,0x04 Tūlītēja ielāde +0000002E: BFDE OUT 0x3E,R29 Izeja uz I/O atrašanās vietu +0000002F: BFCD uz I/O atrašanās vieta

0000002C: E5CF LDI R28,0x5F Tūlītēja ielāde +0000002D: E0D4 LDI R29,0x04 Tūlītēja ielāde +0000002E: BFDE OUT 0x3E,R29 Izeja uz I/O atrašanās vietu +0000002F: BFCD uz I/O atrašanās vieta

Tiek ielādēts steka rādītājs. Jūs nevarat tieši ielādēt reģistrus I / O, tikai izmantojot starpreģistru. Tāpēc vispirms LDI uz starpproduktu un pēc tam OUT uz I/O. Es arī pastāstīšu vairāk par steku. Tikmēr ziniet, ka šis ir tik dinamisks atmiņas apgabals, tas karājas RAM beigās un saglabā adreses un starpposma mainīgos. Tagad mēs esam norādījuši, no kurienes sāksies kaudze.

00000032: 940C0041 JMP 0x00000041 Pārlēkt

Pārlēciens uz programmas saaaaamy beigām, un tur mēs esam atspējoti pārtraukumi un cieši cilpa sev:

1 2 +00000041: 94F8 CLI globālā pārtraukuma atspējošana +00000042: CFFF RJMP PC-0x0000 Relatīvais lēciens

00000041: 94F8 CLI globālā pārtraukuma atspējošana +00000042: CFFF RJMP PC-0x0000 Relatīvais lēciens

Tas notiek neparedzētu apstākļu, piemēram, aiziešanas no galvenās funkcijas, gadījumā. Kontrolieri var izņemt no šādas cilpas vai nu ar aparatūras atiestatīšanu, vai, visticamāk, atiestatot no sargsuņa. Nu, vai, kā jau teicu iepriekš, salabojiet šīs vietas hex redaktorā un braucam, kur vien vēlamies. Ņemiet vērā arī to, ka ir divu veidu lēcieni JMP un RJMP, pirmais ir tiešs lēciens uz adresi. Tas aizņem četrus baitus un var veikt tiešu lēcienu pa visu atmiņas apgabalu. Otrs pārejas veids - RJMP - ir relatīvs. Viņa komanda aizņem divus baitus, bet viņš pārlec no pašreizējās pozīcijas (adreses) 1024 soļus uz priekšu vai atpakaļ. Un tā parametri norāda nobīdi no pašreizējā punkta. Biežāk lietots, tk. zibspuldzē aizņem pusi vietas, un reti ir nepieciešamas garas pārejas.

1 +00000034: 940C0000 JMP 0x00000000 lēciens

00000034: 940C0000 JMP 0x00000000 Pārlēkt

Un tas ir lēciens uz koda sākumu. Sava veida atsāknēšana. Šeit varat pārbaudīt, vai visi vektori pārlec. No šī secinājuma - ja jūs tagad iespējojat pārtraukumus (pēc noklusējuma tie ir atspējoti) un jums ir pārtraukums, bet nav apstrādātāja, tad notiks programmatūras atiestatīšana - programma tiks izmesta pašā sākumā.

galvenā funkcija. Viss ir vienāds, jūs pat nevarat aprakstīt. Paskaties tikai reģistros ir ievadīts jau aprēķinātais skaitlis. Kompilatora priekšprocesora ieži!!! Tātad bez "maģiskiem" skaitļiem!

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

00000036: E383 LDI R24,0x33 Tūlītēja ielāde +00000037: B989 OUT 0x09,R24 Out uz I/O vietu 15: UBRRH = HI (bauddalītājs); +00000038: BC10 OUT 0x20,R1 Out uz I/O vietu 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 Out uz I/O vietu 17: UCSRB = 1<

Un šeit ir jamba:

1 2 3 +0000003E: E080 LDI R24,0x00 Tūlītēja ielāde +0000003F: E090 LDI R25,0x00 Tūlītēja ielāde +00000040: 9508 RET Apakšprogrammas atgriešana

0000003E: E080 LDI R24,0x00 Tūlītēja ielāde +0000003F: E090 LDI R25,0x00 Tūlītēja ielāde +00000040: 9508 RET Apakšprogrammas atgriešana

Jautājums, kāpēc kompilators pievieno tādus topus? Un tas nav nekas vairāk kā Return 0, mēs definējām funkciju kā int main (void), tāpēc mēs vēl četrus baitus nopludinājām, nesaprotu ko :) Un ja izdarīsi void main (void), tad paliks tikai RET , bet parādīsies brīdinājums, ka viņi saka, ka mūsu galvenā funkcija neko neatgriež. Vispār dari ko gribi :)

Sarežģīti? Šķiet, ka tā nav. Noklikšķiniet uz soli pa solim izpilde disassembler režīmā un skatiet, kā procesors izpilda atsevišķas instrukcijas, kas notiek ar reģistriem. Kā notiek kustība caur komandām un beigu cilpu.

Turpinājums pēc pāris dienām...

Ārpus augšpusē:
Aleksejs78 Es izveidoju Firefox spraudni, kas atvieglo navigāciju manā vietnē un forumā.
Diskusija un lejupielāde,

AVR mikrokontrolleriem ir dažādas programmēšanas valodas, taču, iespējams, vispiemērotākās ir assembler un C, jo šīs valodas nodrošina vislabāko visu nepieciešamo mikrokontrollera aparatūras vadīšanai nepieciešamo iespēju ieviešanu.

Assembler ir zema līmeņa programmēšanas valoda, kas izmanto mikrokontrollera tiešo instrukciju kopu. Lai izveidotu programmu šajā valodā, ir nepieciešamas labas programmējamās mikroshēmas komandu sistēmas zināšanas un pietiekami daudz laika programmas izstrādei. Programmas izstrādes ātruma un ērtības ziņā Assembler zaudē C, taču tam ir ievērojamas priekšrocības gala izpildāmā koda lielumā un attiecīgi arī tā izpildes ātrumā.

C ļauj izveidot programmas ar daudz lielāku komfortu, sniedzot izstrādātājam visas augsta līmeņa valodas priekšrocības.
Vēlreiz jāatzīmē, ka AVR arhitektūra un komandu sistēma tika izveidota ar C kompilatora izstrādātāju tiešu līdzdalību un tā ņem vērā šīs valodas iezīmes. C valodā rakstīta pirmkoda kompilēšana ir ātra un rada kompaktu, efektīvu kodu.

Galvenās C priekšrocības salīdzinājumā ar montētāju ir: liels programmas izstrādes ātrums; daudzpusība, kas neprasa rūpīgu mikrokontrollera arhitektūras izpēti; labāka algoritma dokumentējamība un lasāmība; funkciju bibliotēku pieejamība; atbalsts peldošā komata aprēķiniem.

C valoda harmoniski apvieno zema līmeņa programmēšanas iespējas ar augsta līmeņa valodas iezīmēm. Zema līmeņa programmēšanas iespējas ļauj ērti darboties tieši uz aparatūras, un augsta līmeņa valodas īpašības ļauj izveidot viegli lasāmu un modificējamu programmas kodu. Turklāt gandrīz visiem C kompilatoriem ir iespēja izmantot montāžas ieliktņus, lai rakstītu kritiskās programmas sadaļas izpildes laika un resursu ziņā.

Vārdu sakot, C ir ērtākā valoda gan iesācējiem, lai iepazītos ar AVR mikrokontrolleriem, gan nopietniem izstrādātājiem.

Kompilatori tiek izmantoti, lai programmas avota kodu pārvērstu mikrokontrollera programmaparatūras failā.

Atmel nodrošina jaudīgu montāžas kompilatoru, kas ir iekļauts Windows balstītā Atmel Studio izstrādes vidē. Kopā ar kompilatoru izstrādes vidē ir atkļūdotājs un emulators.
Atmel Studio ir pilnīgi bezmaksas un pieejama Atmel vietnē.

Pašlaik AVR ir diezgan daudz C kompilatoru. Visspēcīgākais no tiem ir IAR Systems kompilators no Stokholmas. Tieši viņas darbinieki 90. gadu vidū piedalījās AVR komandu sistēmas izstrādē. IAR C Compiler ir plašas koda optimizācijas iespējas, un tas ir daļa no IAR Embedded Workbench (EWB) integrētās izstrādes vides, kurā ietilpst arī montētāja kompilators, saistītājs, projektu un bibliotēkas pārvaldnieks un atkļūdotājs. Komplekta pilnās versijas cena ir 2820 EUR. Uzņēmuma vietnē varat lejupielādēt bezmaksas novērtējuma versiju uz 30 dienām vai neierobežotu versiju ar koda lieluma ierobežojumu 4 KB.

Amerikāņu uzņēmums Image Craft no Palo Alto, Kalifornijā, ražo C valodas kompilatoru, kas ieguvis diezgan plašu popularitāti. JumpStart C for AVR ir pieņemama koda optimizācija, un tā nav pārāk dārga (no $ 50 līdz $ 499 atkarībā no versijas). JumpStart C demonstrācijas versija AVR ir pilnībā funkcionāla 45 dienas.

Ne mazāku popularitāti ieguva Rumānijas Code Vision AVR C Compiler, šī kompilatora pilnas versijas cena ir salīdzinoši zema un sastāda 150 EUR. Kompilatoram ir integrēta izstrādes vide, kurā papildus standarta iespējām ir iekļauta diezgan interesanta funkcija - CodeWizardAVR Automatic Program Generator. Seriālā termināļa klātbūtne izstrādes vidē ļauj atkļūdot programmas, izmantojot mikrokontrollera seriālo portu. Izstrādātāji var lejupielādēt bezmaksas novērtējuma versiju ar koda lieluma ierobežojumu 4 KB un atspējot ģenerētā C avota koda saglabāšanu.

MikroElektronika, kas atrodas Serbijas pilsētā Belgradā, ražo veselu kompilatoru saimi AVR mikrokontrolleriem. C kompilators ar nosaukumu mikroC PRO AVR maksā 249 USD. Ir arī mikroBasic un mikroPascal par tādu pašu cenu. Izstrādātāja vietnē ir demonstrācijas versijas ar koda lieluma ierobežojumu 4096 baiti. Šīs kompilatoru saimes priekšrocība ir vienota platforma un vienota ideoloģija, kas var nodrošināt vieglu pāreju ne tikai starp valodām, bet arī starp mikrokontrolleriem (ir kompilatoru versijas priekš PIC, STM32, 8051 ...).

Integrētā izstrādes vide ir kļuvusi patiesi ikoniska. Tas ietver jaudīgus C un montāžas kompilatorus, AVRDUDE programmētāju, atkļūdotāju, simulatoru un daudzas citas atbalsta programmas un utilītas. WinAVR lieliski integrējas ar Atmel AVR Studio izstrādes vidi. Montētāja ievades kods ir identisks AVR Studio montētājam. C un assembler kompilatoriem ir iespēja izveidot atkļūdošanas failus COFF formātā, kas ļauj izmantot ne tikai iebūvētos rīkus, bet arī izmantot jaudīgo AVR Studio simulatoru. Vēl viens svarīgs plus ir tas, ka WinAVR tiek izplatīts bez maksas bez ierobežojumiem (ražotāji atbalsta GNU vispārējo publisko licenci).

Rezumējot, WinAVR ir ideāla izvēle tiem, kas sāk apgūt AVR mikrokontrollerus. Tieši šī attīstības vide šajā kursā tiek uzskatīta par galveno.

Bitu operācijas ir balstītas uz loģiskām operācijām, kuras mēs jau aplūkojām iepriekš. Viņiem ir galvenā loma AVR mikrokontrolleru un citu veidu programmēšanā. Gandrīz neviena programma nevar iztikt bez bitu operāciju izmantošanas. Līdz šim esam apzināti izvairījušies no tiem, lai būtu vieglāk apgūt MK programmēšanu.

Visos iepriekšējos rakstos mēs programmējām tikai I/O portus un neizmantojām papildu iebūvētos mezglus, piemēram, taimerus, analogo-digitālo pārveidotājus, pārtraukumus un citas iekšējās ierīces, bez kurām MK zaudē visu jaudu.

Pirms pāriet uz iebūvēto MK ierīču apgūšanu, jums jāapgūst, kā kontrolēt vai pārbaudīt atsevišķus AVR MK reģistru bitus. Iepriekš mēs veicām pārbaudi vai iestatījām visa reģistra bitus uzreiz. Apskatīsim, kāda ir atšķirība, un tad turpināsim tālāk.

Bitu darbības

Visbiežāk, programmējot AVR mikrokontrollerus, mēs to izmantojām, jo ​​tam ir lielāka skaidrība, salīdzinot ar iesācēju MK programmētājiem, un tas ir labi saprotams. Piemēram, mums jāiestata tikai D porta 3. bits. Šim nolūkam, kā mēs jau zinām, mēs varam izmantot šādu bināro kodu:

PORTD = 0b00001000;

Tomēr ar šo komandu mēs iestatām 3. bitu uz vienu, bet visus pārējos (0, 1, 2, 4, 5, 6 un 7) atiestatām uz nulli. Un tagad iedomāsimies situāciju, ka 6. un 7. cipars tiek izmantoti kā ADC ieejas, un šajā laikā signāls no kādas ierīces nonāk attiecīgajās MK izejās, un mēs šos signālus atiestatām, izmantojot iepriekš minēto komandu. Rezultātā mikrokontrolleris tos neredz un uzskata, ka signāli nav atnākuši. Tāpēc šādas komandas vietā mums vajadzētu izmantot citu, kas iestatītu tikai 3. bitu uz vienu, vienlaikus neietekmējot pārējos bitus. Šim nolūkam parasti tiek izmantota šāda bitu operācija:

OSTA |= (1<<3);

Tālāk mēs detalizēti analizēsim tā sintaksi. Un tagad vēl viens piemērs. Pieņemsim, ka mums ir jāpārbauda PIND reģistra 3. bita statuss, tādējādi pārbaudot pogas stāvokli. Ja šis bits tiek atiestatīts uz nulli, tad mēs zinām, ka tiek nospiesta poga un pēc tam tiek izpildīts komandas kods, kas atbilst nospiestās pogas stāvoklim. Iepriekš mēs būtu izmantojuši šādu apzīmējumu:

if (pind == 0b00000000)

(jebkurš kods)

Taču ar tās palīdzību pārbaudām nevis vienu, 3., bet visus PIND reģistra bitus uzreiz. Tāpēc, pat ja tiek nospiesta poga un tiek atiestatīts vajadzīgais bits, bet tajā laikā tiek saņemts signāls uz jebkura cita porta D kontakta, atbilstošais bits tiks iestatīts uz vienu, un nosacījums iekavās būs nepatiess. Rezultātā kods krokainajās iekavās netiks izpildīts pat tad, kad tiek nospiesta poga. Tāpēc, lai pārbaudītu atsevišķa PIND reģistra 3. bita statusu, jāizmanto bitu darbība:

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

(jebkurš kods)

Lai strādātu ar atsevišķiem mikrokontrollera bitiem, C programmēšanas valodas arsenālā ir iespējams mainīt vai pārbaudīt viena vai vairāku atsevišķu bitu stāvokli vienlaikus.

Viena bita iestatīšana

Lai iestatītu vienu bitu, piemēram, portu D, tiek izmantota bitu VAI darbība. Tas ir tas, ko mēs izmantojām raksta sākumā.

PORTD = 0b00011100; // sākotnējā vērtība

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

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

PORTD == 0b00011101; // rezultāts

Šī komanda bitu iestata uz nulli, bet pārējo atstāj nemainīgu.

Piemēram, iestatīsim porta D 6. bitu.

PORTD = 0b00011100; // sākotnējais porta stāvoklis

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

PORTD == 0b01011100; // rezultāts

Lai rakstītu no viena līdz vairākiem atsevišķiem bitiem vienlaikus, piemēram, nulle, sestais un septītais ports B tiek piemērots šāds apzīmējums.

PORTB = 0b00011100; // sākotnējā vērtība

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

PORTB == 0b1011101; // rezultāts

Atsevišķu bitu atiestatīšana (nulles iestatīšana).

Lai atiestatītu vienu bitu, vienlaikus tiek izmantotas trīs iepriekš apspriestās komandas: .

Atiestatīsim PORTC reģistra 3. bitu un pārējo atstāsim nemainītu.

PORTC = 0b00011100;

PORTC &= ~(1<<3);

PORTC == 0b00010100;

Veiksim līdzīgas darbības ar 2. un 4. cipariem:

PORTC = 0b00111110;

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

PORTC == 0b00101010;

Bīta pārslēgšana

Papildus iestatīšanai un atiestatīšanai tiek izmantota arī noderīga komanda, kas pārslēdz vienu bitu pretējā stāvoklī: viens uz nulli un otrādi. Šo loģisko darbību plaši izmanto dažādu apgaismojuma efektu konstruēšanā, piemēram, piemēram, Jaungada vītnē. Apsveriet PORTA piemēru

PORTA = 0b00011111;

PORTA ^= (1<<2);

PORTA == 0b00011011;

Mainiet nulles, otrā un sestā bita stāvokli:

PORTA = 0b00011111;

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

PORTA == 0b01011010;

Atsevišķa bita statusa pārbaude. Atgādināšu, ka I/O porta pārbaude (pretstatā rakstīšanai) tiek veikta, nolasot datus no PIN reģistra.

Visizplatītākā pārbaude tiek veikta ar vienu no diviem cilpas paziņojumiem: if un while. Mēs jau esam pazīstami ar šiem operatoriem agrāk.

Izlādes pārbaude, vai nav loģiskās nulles (atiestatīšana) ar ja

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

Ja porta D trešais bits ir notīrīts, tiek izpildīts kods1. Pretējā gadījumā tiek izpildīts kods2.

Līdzīgas darbības tiek veiktas ar un šajā ierakstīšanas formā:

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

Izlādes pārbaude loģiskās vienības klātbūtnei (iestatījums) ar ja

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

if (PIND & (1<<3))

Iepriekš minētās divas cilpas darbojas līdzīgi, taču C programmēšanas valodas elastības dēļ tās var rakstīt atšķirīgi. Operācija != nozīmē nevienlīdzību. Ja ir iestatīts trešais PD I/O porta bits (viens), tad tiek izpildīts Code1, ja nē, Code2.

Gaida nelielu atiestatīšanu ar kamēr

kamēr (PIND & (1<<5))

Kods1 tiks izpildīts tik ilgi, kamēr ir iestatīts PIND reģistra 5. bits. Atiestatot to, tiks sākta Code2 izpilde.

Gaida, kad bits tiks iestatīts kamēr

Šeit C valodas sintakse ļauj rakstīt kodu divos no visizplatītākajiem veidiem. Praksē tiek izmantoti abi ierakstīšanas veidi.