AVR: programmering i AVR Studio-miljön. Integrerad felsökningsmiljö AVR Studio från Atmel Avr studio

För att arbeta med AVR Studio 4 måste du installera den själv. Om det redan är installerat kan du hoppa över det här steget.

Installation:
skapa en katalog c:/avr/ - det är här arbetsprogrammen kommer att finnas.
skapa en katalog, till exempel c:/works/ – det är här dina verk kommer att lagras.
Det är nödvändigt att det finns genvägar så att det inte blir några problem med dem.

Det finns i allmänhet AVRStudio5, men AVRStudio4 räcker fortfarande.

Allt arbete kommer att ske i AVRStudio4, WinAVR behövs bara på grund av AVR-GCC-biblioteket (så att du kan skriva i C)
MEN! Du måste installera WinAVR först, annars hämtas inte AVR-GCC-biblioteket.

Jag tror att du kommer att reda ut det här.
AVR-GCC för att skriva i C
Atmel Avr Assembler respektive för montör.

Det är bättre att börja förstå MK från början. Och detta betyder från Assembler, vilket innebär att du skapar den som är Atmel AVR Assembler.

Välj sedan Atmega8 mikrokontroller.

när projektet skapas kommer det att finnas ett stort, vitt, tomt blad. det kommer att finnas en kod här.

lite om innehållet i detta blad

"kommentarer" är text som kompilatorn hoppar över vid kompilering.
det måste finnas en speciell symbol före början av kommentaren, jag använder symbolen; "semikolon", det finns också "dubbelt snedstreck" (//),
här är exempel på kommentarer

/* * En kommentar av denna typ (flera rader), * används vanligtvis för * åtföljande information * om källkoden, d.v.s. * namn, utvecklare etc. */ NOP // Den här kommentaren används främst för att förklara syftet med ett kommando, eller en bit kod SLEEP ; Denna kommentar, precis som den föregående, kan användas för förklaring (för anteckningar) i koden

kommandon skrivs på varje rad. de där. ett kommando - en rad.
Låt oss säga att det finns kommandon med två "parametrar", med en eller utan någonting

MOV R16, R17; två parametrar INC R16; en SEI-parameter; utan parametrar

MOV R16, R17; tre byte INC R16; två byte SEI ; en byte

Ser du sambandet mellan lagstorlek och parametrar?

Varje mikrokontroller har sin egen assembler, även om deras mnemonics är liknande, d.v.s. MOV-kommandot för MK av en serie kommer att se i maskinkod, säg 0x12, och för en annan 0x55.
För att under kompileringen kompileras den i koden vi behöver, måste vi berätta för kompilatorn för vilken mikrokontroller vi skriver programmet.
Detta väljs vanligtvis när du skapar ett projekt.
Av denna anledning valde vi Atmega8 mikrokontroller.

Men det är inte allt. För att göra vårt liv enklare har AVRStudio4 en uppsättning konstanter, som kallas något som "Macroassembler".

För att ladda dem måste du infoga raden i början av koden

Inkludera "m8def.inc" // med .include-kommandot laddade vi m8def.inc-filen; och nu kommer det att bli lättare för oss;)

Allra i början av koden placeras en avbrottstabell. Jag kommer att förklara vad det är och hur det fungerar i ett annat inlägg. Men nu, låt oss skriva det så här:

RJMP ÅTERSTÄLLNING ; Återställ hanterare RETI; RJMP EXT_INT0 ; IRQ0 Hanterare RETI; RJMP EXT_INT1 ; IRQ1-hanterare RETI; RJMP TIM2_COMP ; Timer2 Jämför Handler RETI; RJMP TIM2_OVF ; Timer2 Spillhanterare RETI; RJMP TIM1_CAPT ; Timer1 Capture Handler RETI; RJMP TIM1_COMPA ; Timer1 JämförA Handler RETI; RJMP TIM1_COMPB ; Timer1 JämförB Hanterare RETI; RJMP TIM1_OVF ; Timer1 Spillhanterare RETI; RJMP TIM0_OVF ; Timer0 Spillhanterare RETI; RJMP SPI_STC ; SPI Transfer Complete Handler RETI; RJMP USART_RXC ; USART RX Complete Handler RETI; RJMP USART_UDRE ; UDR Tom hanterare RETI; RJMP USART_TXC ; USART TX komplett hanterare RETI; RJMP ADC ; ADC-konvertering komplett hanterare RETI; RJMP EE_RDY ; EEPROM Ready Handler RETI; RJMP ANA_COMP ; Analog komparatorhanterare RETI; RJMP TWSI ; Tvåtråds seriellt gränssnittshanterare RETI; RJMP SPM_RDY ; Lagra programminne redo hanterare

Efter detta kommer själva koden

OMSTART: ; initialiseringstoken MAIN: NOP ; huvudslingmarkör RJMP MAIN

Men det finns en (eller snarare inte en, utan många) funktioner.

För att underlätta att skriva kod, för dess tydlighet och för att underlätta relativa övergångar fick vi markörer, hur ser de ut? "RESET:" och "MAIN:" är markörer; deras namn kan innehålla nästan alla latinska tecken och siffror. Markörer kan inte ha namn på funktioner och kommandon, till exempel "NOP".
Hur kommer man till dem? Låt oss säga RJMP-kommandot.

Från Markers kan vi också göra en subrutin (procedur), när vi är klara kommer vi tillbaka till varifrån den anropades. För att anropa det, använd kommandot "RCALL (subrutin)", och för att återgå från subrutinen (proceduren), måste du avsluta det med kommandot "RET". Vi borde sluta med kod så här:

STARTA OM: MAIN: NOP RCALL PPP1 ; anropa subrutinen RJMP MAIN PPP1: NOP RET ; avsluta subrutinen

Hur "RCALL"-kommandot fungerar, när det anropas placeras adressen från vilket det anropades på STACKEN, och när "RET"-kommandot anropas tas det bort från "stack"-registret. STACKEN måste initieras.

För att vi ska kunna arbeta med vår MK måste vi initialisera den. därför att mk, den här enheten är universell, den har många in-/utgångsportar och kringutrustning. såsom USART, PWM, DAC, ADC, etc. Det första steget i att initiera mikrokontrollern är att indikera början av "stacken". Vi utför initiering efter "RESET:"-markören.

LDI R16,HÖG(RAMEND) UT SPH,R16 LDI R16,LÅG(RAMEND) UT SPL,R16

Om vi ​​inte hade skrivit in kommandot .include “m8def.inc” i början av koden, skulle vi ha behövt skriva det så här:

LDI R16,0x04 OUT SPH,R16 LDI R16,0x5f OUT SPL,R16

Skillnaden är betydande, enligt mig.

STACK är ett minne av lagringstyp: (sist in, först ut).
Butikstypen är inte en stormarknad, utan ett horn från ett maskingevär. Jag hoppas att alla kan föreställa sig hur patroner laddas i den och hur de sedan tas bort därifrån.
Du måste ägna mycket uppmärksamhet åt STACK-minnet, eftersom... alla mindre misstag i arbetet med det kan leda till ett stackfel. Detta är ett så viktigt ämne att jag bestämde mig för att ägna ett helt ämne åt det och kommer att skriva det i en separat anteckning.

Så vi fick följande kod:

Inkludera "m8def.inc" RJMP RESET ; Återställ hanterare RETI; RJMP EXT_INT0 ; IRQ0 Hanterare RETI; RJMP EXT_INT1 ; IRQ1-hanterare RETI; RJMP TIM2_COMP ; Timer2 Jämför Handler RETI; RJMP TIM2_OVF ; Timer2 Spillhanterare RETI; RJMP TIM1_CAPT ; Timer1 Capture Handler RETI; RJMP TIM1_COMPA ; Timer1 JämförA Handler RETI; RJMP TIM1_COMPB ; Timer1 JämförB Hanterare RETI; RJMP TIM1_OVF ; Timer1 Spillhanterare RETI; RJMP TIM0_OVF ; Timer0 Spillhanterare RETI; RJMP SPI_STC ; SPI Transfer Complete Handler RETI; RJMP USART_RXC ; USART RX Complete Handler RETI; RJMP USART_UDRE ; UDR Tom hanterare RETI; RJMP USART_TXC ; USART TX komplett hanterare RETI; RJMP ADC ; ADC-konvertering komplett hanterare RETI; RJMP EE_RDY ; EEPROM Ready Handler RETI; RJMP ANA_COMP ; Analog komparatorhanterare RETI; RJMP TWSI ; Tvåtråds seriellt gränssnittshanterare RETI; RJMP SPM_RDY ; Lagra programminne redo Hanterare ÅTERSTÄLL: LDI R16,HÖG(RAMEND) UT SPH,R16 LDI R16,LÅG(RAMEND) UT SPL,R16 RGMP ÅTERSTÄLL MAIN: NOP ; huvudslingmarkör RJMP MAIN

I det här skedet kan vi kompilera projektet och köra det för felsökning, men eftersom vår kod inte gör någonting kan vi bara identifiera syntaxfel i koden.

För korrekt felsökningsprocess måste du ställa in emulatorn frekvensen med vilken MK kommer att fungera, detta görs först efter kompilering och start av felsökning,
Det betyder att vi hittar "Bygg" i menyraden, öppnar den och ser "Bygg och kör", varefter vi kommer att se en gul pil mittemot det första kommandot i vår kodlista. Nu letar vi efter "Debug" i menyraden och klickar på "AVR Simulator Options", följande fönster öppnas:

Där vi kan ändra MK och dess frekvens, också, på panelen till höger, ser vi lite information om vår MK: dess maximala frekvens, minneskapacitet (EEPROM, RAM, FLASH). Öppna nu databladet på Atmega8, på sidan 203 (allmän lista över register) och 205 (allmän lista över kommandon) och börja skriva ditt program.
Och kom ihåg, var inte rädd för att experimentera med simulatorn, den går inte sönder!


Hallå.

Den här artikeln kommer att tilltala dem som tror att de har "växt upp" från Arduino och är redo att kliva in i världen av "seriös" mikrokontrollerprogrammering. Förutom det faktum att du kommer att "pumpa upp dina programmerares färdigheter", kommer du att ha möjlighet att välja vilken mikrokontroller som helst för dina projekt, och naturligtvis kommer du att uppskatta hastigheten på programmen och storleken på minnet de upptar.

Allt kommer att beskrivas (för    ), från början till slut, - installation och förberedelse av nödvändig programvara, montering av den enklaste "Gromov" programmeraren (var inte rädd, det finns bara tre dioder och sju motstånd), MK firmware och skriva kod i AVR Studio. Hela processen kommer att åtföljas av illustrationer och exempel.

Låt mig göra en reservation direkt: datorn måste vara utrustad med en COM-port (USB till COM-adaptern fungerar inte bra). Om din dator inte har en sådan kontakt på baksidan, är den förmodligen på moderkortet (i form av stift), då kan allt lösas med denna "utkastning"

Tyvärr, för ägare av bärbara datorer utan COM är artikeln endast av akademiskt intresse.

Så, låt oss börja...

Vad kommer du att behöva?

"Mjuk"


UniProf- ett universellt program för att blinka olika ATmega-mikrokontroller, enkelt och bekvämt, och viktigast av allt, fungerar perfekt med vår programmerare. Författaren är den ryske utvecklaren Mikhail Nikolaev.

Naturligtvis kan du flasha MK från AVR Studio, men för detta behöver du en speciell programmerare. Därför kommer vi att skriva koden i studion och flasha de resulterande hex-filerna med UniProf med vår hemmagjorda programmerare. Dessutom kommer metoden att blinka fast programvara från kommandoraden att beskrivas.

Linux-användare måste använda antingen en virtuell maskin eller Wine. Det fungerade inte för mig med Wine, jag kan inte se porten alls, och jag har inte provat det med en virtuell maskin.

  Fungerar felfritt i vin (Debian 8.5, wine1.6).

All programvara är gratis.

"Järn"

Vi kommer att genomföra experiment på Arduino pro mini med ATmega328-chip. Kvarts frekvens (8/16MHz), samt spänning (3,3/5v), spelar ingen roll. (se nedan)

I framtiden kommer du att programmera olika Atmel-mikrokontroller, men för första gången är det här kortet helt rätt. Det är bra eftersom det praktiskt taget är en bar kontroller med minimal ledning och lödda stift. Precis vad du behöver.

Om markeringar på mikrokontroller

Efter namnet finns siffror, som oftast anger mängden minne.

Bokstaven efter siffrorna indikerar matningsspänningsparametrarna.

Inget brev- regulatorns matningsspänning är inom 4,5-5,5 volt.
L- versioner av styrenheter som arbetar med reducerad (Låg) matningsspänning (2,7 - 5,5 volt).
V- versioner av styrenheter som arbetar på låg matningsspänning (1,8-5,5 volt).
U- versioner av styrenheter som arbetar på ultralåg matningsspänning (0,7-5,5 volt).
P- lågeffektversioner (upp till 100 nA i avstängt läge).
A- minskad strömförbrukning, täcker hela klockfrekvensområdet för alla versioner, matningsspänning 1,8-5,5 volt (i vissa modeller har nya funktioner och nya register lagts till, samtidigt som full kompatibilitet med tidigare versioner bibehålls).

Mikrokontroller « A" och inte- A" har vanligtvis samma signatur, vilket orsakar vissa svårigheter, eftersom säkringsbitarna är olika.

Exempel:

ATmega8- programminneskapacitet är 8 kilobyte, matningsspänning är 4,5-5,5 volt.
ATmega8L- programminneskapacitet är 8 kilobyte, matningsspänning är 2,7-5,5 volt.
ATtiny43U- minneskapacitet 4 kilobyte, modifiering - 3, matningsspänning - 0,7-5,5 volt.
ATtiny44A- minneskapacitet 4 kilobyte, modifiering - 4, reducerad strömförbrukning, matningsspänning 1,8-5,5 volt.

Det händer att en styrenhet utan bokstav kan ha en reducerad matningsspänning (1,7 eller 1,8 volt). Detta måste förtydligas i databladet.

ATtiny841- minneskapacitet 8 kilobyte, modifiering - 41, matningsspänning - 1,7-5,5 volt.

Efter bindestrecket indikeras mikrokontrollerversionen, bestående av siffror som indikerar styrenhetens maximala frekvens (vid lämplig matningsspänning), och från bokstäver som anger höljesalternativ, driftstemperaturintervall och tillverkningsfunktioner.

En eller två bokstäver efter frekvensen indikerar hustyp:

UniProf
Att skriva ett program är halva striden, du måste fortfarande på något sätt stoppa in det i handkontrollen. Så låt oss ägna mer uppmärksamhet åt detta.

Det skulle vara trevligt om din Arduino var laddad med standard Blink (den kommer med från fabriken).

Låt oss starta UniProf... Kanske följande fönster dyker upp:

Denna är ansluten till LPT-porten, så klicka bara OK.

Programfönstret öppnas då:

Om porten inte är vald korrekt visas ett fönster som frågar...

Klicka på OK och välj önskad port.

Om MK inte detekteras automatiskt, kommer ett fönster med manuellt val att visas:

Tyvärr inte med på listan atmega328, så vi väljer mega32 (de har samma mängd flashminne) och tryck på OK.

Efter detta, istället för ordet okänd, kommer den anslutna styrenheten att visas...

32Kär mängden Flash-minne, och 1024 - EEPROM volym.

Nu, om allt är som på bilden, öppna då hjälpen   och läs noga vad som står där. Författaren var väldigt kortfattad, så det kommer inte ta mycket tid. Tryck inte på några knappar än.

Har du träffat? Bra, nu kan vi gå vidare. Avmarkera rutan bredvid EEPROM och du kommer att se det ändrade gränssnittet:

Efter att ha avmarkerat kryssrutan EEPROM utförs inte läsning och skrivning av detta minnesområde.

Eftersom vi kommer att arbeta med hex-filer kommer vi att ta bort "bocken" Allmän Och BIN, och markera även rutan Broms!, kommer detta att öka läs/skrivtiden, men kommer att öka stabiliteten.

Processen är inte snabb så du måste vänta. Blå rutor kommer att krypa nedanför och siffror kommer att räknas i det nedre högra hörnet. Det första passet kommer att läsa PROGRAM-området, och det andra kommer att läsa EEPROM.

Jag har en ny Arduino med en standard Blink inbyggd (när programmeraren är ansluten slutar dioden att blinka). Om du har samma sak kommer följande bild att dyka upp:

Till höger ser vi att det inte finns något i EEPROM, och till vänster, i PROGRAM, finns det ett inspelat program (som jag sa, det här är Blink). Använd nu nedåtpilen för att rulla reglaget tills data tar slut...

... scrolla nu till slutet. Du kommer att se mer data - det här är Arduino bootloader.

Nu föreslår jag att ta en paus från min artikel och läsa om MK:s struktur, detta kommer att öka din förståelse av materialet avsevärt. Allt är skrivet väldigt bra och tydligt. Tja, när du har läst den, kom tillbaka och låt oss fortsätta...

Avmarkera EEPROM. Vi behöver det egentligen inte, men det kommer att vara tydligt att det finns en "tick" Broms!

Låt oss nu spara allt som är firmware i styrenheten, så att vi efter experiment kan återställa det till sitt ursprungliga tillstånd.

Tryck på  -knappen och spara firmware, kalla det något i stil med - origProMini328.hex. Det var allt, nu har du en backup.

... och klicka sedan på den redan välbekanta knappen Läs. Efter detta kommer du att se att alla celler i PROGRAM är tomma. Inte bara programmet togs bort, utan även Arduino bootloader.
Det vill säga, nu kommer du inte att kunna ladda upp skisser med den traditionella metoden. Sedan, om du vill, återställ allt från säkerhetskopian med en lätt handrörelse.

Nu kommer vi att blinka kontrollern med samma "Blink", bara skriven i AVR Studio.

Så här ser koden ut:

#define F_CPU 16000000UL #inkludera #omfatta #define PIN_PB5 5 // PB5 (Arduino - D13) #define PIN_PB5_PORT PORTB #define PIN_PB5_DDR DDRB int main(void) ( PIN_PB5_DDR = 1<< PIN_PB5; // устанавливаем PIN_PB5 (PB5 (ардуина - D13)) как ВЫХОД while(1) { PIN_PB5_PORT = 1 << PIN_PB5; _delay_ms(300); PIN_PB5_PORT = 0 << PIN_PB5; _delay_ms(300); } return 0; }
Om du använder en Arduino med 8 MHz kvarts så är det inget fel på detta, dioden blinkar bara hälften så ofta.

Här är hur mycket utrymme den tar:

AVRDude

Uniprof är, liksom många andra liknande program, endast ett grafiskt tillägg över AVRDude-programmet (AVR Downloader-Uploader), som sedan utför alla ovan beskrivna åtgärder på mikrokontrollern.
Eftersom den AVRDude har inte ett eget grafiskt gränssnitt, du måste arbeta med det från kommandoraden. Detta kan verka obekvämt för vissa, men det är precis tvärtom; att arbeta från konsolen är helt enkelt fantastiskt. Bekvämt, enkelt och inte knutet till något OS, eftersom avrdude förmodligen finns för allt. Nu kommer du att se detta.

För användare

Avrdude ingår i AVR-verktygskedjan, så installera den (efter installation av AVR Studio) som skrevs i början av artikeln.

CD\
...gå till roten på disken MED.

Genom att ange kommandot:

Om så är fallet, då avrdude redo att gå och fortsätta.

Nu måste vi lägga till vår programmerare i konfigurationsfilen avrdude (C:\Program Files (x86)\Atmel\AVR Tools\AVR Toolchain\bin\ avrdude.conf) . Öppna den i programmet Anteckningar++ och efter inskriptionen "PROGRAMMERDEFINITIONER" lägg till dessa rader:

Programmerar-id = "gromov"; desc = "Serial port banging, reset=dtr sck=rts mosi=txd miso=cts"; typ = serbb; återställ = 4; sck = 7; mosi = 3; miso = 8; ;
Lite smällande.

Spara och stäng filen, den behövs inte längre.

Gå tillbaka till terminalen och ge kommandot för att kontrollera kommunikationen mellan MK och programmeraren:

Avrdude -n -c gromov -P com1 -p m328p
Du kanske har en annan com-port.

Installera avrdude

Sudo apt installera avrdude

Genom att ange kommandot:

Du bör se hjälpinformation.

Om så är fallet, då avrdude redo för arbete.

Konfigurera porten:

Sudo stty 9600 ignbrk -brkint -icrnl -imaxbel -opost -isig -icanon -iexten -echo noflshDetta måste göras efter varje omstart av datorn, eller lägg till det i rc.local.

Där /dev/ttyS0 är com1, /dev/ttyS1 - com2 etc.
I framtiden kommer jag att skriva i team /dev/ttyS0, du kanske har /dev/ttyS1 etc.

Lägg till programmeraren i konfigurationsfilen /etc/avrdude.conf

Sudo nano /etc/avrdude.conf

Lägg till följande rader efter "PROGRAMMERDEFINITIONER":

Programmerar-id = "gromov"; desc = "Serial port banging, reset=dtr sck=rts mosi=txd miso=cts"; typ = "serbb"; återställ = 4; sck = 7; mosi = 3; miso = 8; ;
Programmeraren använder Bit-banging-teknik.

Se till att när du kopierar förblir citaten bara citat, annars kan de ändras (på grund av skillnaden i kodningar) och avrdude kommer att svära.

Spara och stäng filen.

Ge kommandot för att kontrollera kopplingen mellan MK och programmeraren:

Sudo avrdude -n -c gromov -P /dev/ttyS0 -p m328p

Om det finns en koppling blir svaret så här:

Det är där skillnaderna mellan operativsystem slutar och kommandona dupliceras.

Lägg till ett argument till kommandot -v eller -v -v (kan läggas till alla kommandon) för att visa fullständig information:

Avrdude -n -v -c gromov -P com1 -p m328p ###WIN###
sudo avrdude -n -v -c gromov -P /dev/ttyS0 -p m328p ###Linux###


Avrdudes slutsats är att både i Windows och i Linux är samma, så från och med nu kommer jag att ta skärmdumpar endast i Win.

Det finns mer information här, till exempel kan du se vilka säkringar som är installerade. Här matas de ut i hexadecimal (HEX) tal. Till exempel, hfuse 0xDA, i binärt ser det ut så här - . Det vill säga, det är samma bitar som är avmarkerade i grafiska gränssnitt.

När du har att göra med säkringar, kom ihåg att i ATmega mikrokontroller är säkringarna inverterade. Det är 0 - Det här Yucheno, och 1 - av Yucheno. Detta orsakar förvirring i onlineräknare (se nedan).

Låt oss läsa firmware från området blixt (samma som PROGRAM i uniprof) kommando:

Avrdude -c gromov -P com1 -p m328p -U flash:r:readfl.txt:h ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U flash:r:readfl.txt:h ###Linux###

I uniprof visades koden i programmet, men här kommer den att skrivas till en fil.

Firmware läst och skrivit till fil readfl.txt. Brev h (hex) i slutet anger att data ska skrivas i hexadecimalt format. Om du skriver ett brev b (binär), kommer att skrivas i det binära systemet, och om r (rå), då kommer data att vara i "rå" form (kryakozyabra).

Från och med nu antas det att win-användare finns i roten på disken MED (C:\), och Linux-användare arbetar från sin hemmapp, så filerna kommer att sparas där (om inte annat anges). Den firmware som kommer att laddas upp till MK bör finnas där.

För win kommer filen att finnas här C:\readfl.txt, och för linux, i /home/user/readfl.txt. Du kan öppna den här filen och ta en titt.

Läser EEPROM:

Avrdude -c gromov -P com1 -p m328p -U eeprom:r:reader.txt:h ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U eeprom:r:reader.txt:h ###Linux###

Läser blixt och eeprom tillsammans:

Avrdude -c gromov -P com1 -p m328p -U flash:r:readfl.txt:h -U eeprom:r:reader.txt:h ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U flash:r:readfl.txt:h -U eeprom:r:reader.txt:h ###Linux###

Radera kontrollenheten:

Avrdude -e -c gromov -P com1 -p m328p ###WIN###
sudo avrdude -e -c gromov -P /dev/ttyS0 -p m328p ###Linux###

Koppla bort "återställnings"-stiftet - dioden blinkar inte, programmet kommer att raderas.

Låt oss flasha MK med den tidigare nedladdade filen 328test.hex. Ligger vid roten av skivan C(c:\328test.hex) i Windows eller i hemmappen (/home/user/328test.hex) i linux.

Avrdude -c gromov -P com1 -p m328p -U flash:w:328test.hex ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U flash:w:328test.hex ###Linux###

Om du nu stänger av "återställningen" kommer kontrollern att vakna till liv.

Notera. Vid blinkande MK via avrdude, det är inte nödvändigt att radera styrenheten, programmet gör det själv. Men om du anger parametern -D, då kommer MK inte att rengöras automatiskt.

EEPROM firmware:

Avrdude -c gromov -P com1 -p m328p -U eeprom:w:eeprom.hex ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U eeprom:w:eeprom.hex ###Linux###

Läser alla säkringar:

Avrdude -c gromov -P com1 -p m328p -U hfuse:r:hfuse.txt:h -U lfuse:r:lfuse.txt:h -U lock:r:lock.txt:h -U efuse:r:efuse .txt:h ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U hfuse:r:hfuse.txt:h -U lfuse:r:lfuse.txt:h -U lock:r:lock.txt:h -U efuse :r:efuse.txt:h ###Linux###

Vissa kontroller kanske inte har någon säkring.

Endast läsning Låg säkring:

Avrdude -c gromov -P com1 -p m328p -U lfuse:r:lfuse.txt:h ###WIN###
sudo avrdude -c gromov -P com1 -p m328p -U lfuse:r:lfuse.txt:h ###Linux###

Låg säkring är ansvarig för att välja klocksignalkällan (intern, extern), dess frekvens och paus innan styrenheten startar efter att ström anslutits till den. Nu har du värdet skrivet där - 0xff, vilket motsvarar extern kvarts från 8 MHz och uppåt.

Nu kommer vi att blinka en annan luse, som kommer att överföra din ATmeg till arbete från en intern 8 MHz generator.

Avrdude -c gromov -P com1 -p m328p -U lfuse:w:0xe2:m ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U lfuse:w:0xe2:m ###Linux###

Om du har en 16 MHz Arduino kommer dioden att blinka dubbelt så långsamt.
I framtiden, när du kodar i AVR Studio, kan du ange en frekvens på 8 MHz och avlöda kvartsen och därigenom få ytterligare två gratis digitala stift till ditt förfogande.

Men det är senare, och låt oss nu återställa allt som det var genom att blinka med den tidigare säkringen:

Avrdude -c gromov -P com1 -p m328p -U lfuse:w:0xff:m ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U lfuse:w:0xff:m ###Linux###

Dioden blinkar korrekt.

Säkringar kan blinka var för sig eller tillsammans:

Avrdude -c gromov -P com1 -p m328p -U hfuse:w:0xda:m -U lfuse:w:0xff:m -U efuse:w:0x05:m ###WIN###
sudo avrdude -c gromov -P /dev/ttyS0 -p m328p -U hfuse:w:0xda:m -U lfuse:w:0xff:m -U efuse:w:0x05:m ###Linux###
Dessa kommandon behöver inte ges. Jag presenterar dem för tydlighetens skull.

I framtiden, när du behöver använda andra kontroller, kommer du att markera rutorna i online-kalkylatorn och få värdena (länken finns i det övre vänstra hörnet) i hex-format och flasha det.

Nu återstår bara att ta reda på parametrarna avrdude och du kan gå vidare till den sista delen.

-c gromov- typ av programmerare, eller snarare namnet som det är skrivet under i konfigurationen (avrdude.conf).
-P com1– Nåväl, allt är klart här.
-p m328p- beteckning typ MK.
-U- efter detta alternativ indikeras minnesområdet (blixt, eeprom, xfuse), där eventuella åtgärder kommer att utföras (r - läs, w - skriv).
Kolon fungerar som separatorer.

Här, med namnen på mikrokontroller och deras alias, programmerare och andra alternativ.

Smeknamn MK

uc3a0512- AT32UC3A0512
c128- AT90CAN128
c32- AT90CAN32
c64- AT90CAN64
pwm2- AT90PWM2
pwm2b- AT90PWM2B
pwm3- AT90PWM3
pwm316- AT90PWM316
pwm3b- AT90PWM3B
1200 - AT90S1200 (****)
2313 - AT90S2313
2333 - AT90S2333
2343 - AT90S2343 (*)
4414 - AT90S4414
4433 - AT90S4433
4434 - AT90S4434
8515 - AT90S8515
8535 - AT90S8535
usb1286- AT90USB1286
usb1287- AT90USB1287
usb162- AT90USB162
usb646- AT90USB646
usb647- AT90USB647
usb82- AT90USB82
m103- ATmega103
m128- ATmega128
m1280- ATmega1280
m1281- ATmega1281
m1284p- ATmega1284P
m1284rfr2- ATmega1284RFR2
m128rfa1- ATmega128RFA1
m128rfr2- ATmega128RFR2
m16- ATmega16
m161- ATmega161
m162- ATmega162
m163- ATmega163
m164p- ATmega164P
m168- ATmega168
m168p- ATmega168P
m169- ATmega169
m16u2- ATmega16U2
m2560- ATmega2560 (**)
m2561- ATmega2561 (**)
m2564rfr2- ATmega2564RFR2
m256rfr2- ATmega256RFR2
m32- ATmega32
m324p- ATmega324P
m324pa- ATmega324PA
m325- ATmega325
m3250- ATmega3250
m328- ATmega328
m328p- ATmega328P
m329- ATmega329
m3290- ATmega3290
m3290p- ATmega3290P
m329p- ATmega329P
m32u2- ATmega32U2
m32u4- ATmega32U4
m406- ATMEGA406
m48- ATmega48
m48p- ATmega48P
m64- ATmega64
m640- ATmega640
m644- ATmega644
m644p- ATmega644P
m644rfr2- ATmega644RFR2
m645- ATmega645
m6450- ATmega6450
m649- ATmega649
m6490- ATmega6490
m64rfr2- ATmega64RFR2
m8- ATmega8
m8515- ATmega8515
m8535- ATmega8535
m88- ATmega88
m88p- ATmega88P
m8u2- ATmega8U2
t10-ATtiny10
t11- ATtiny11
t12- ATtiny12
t13- ATtiny13
t15-ATtiny15
t1634- ATtiny1634
t20- ATtiny20
t2313- ATtiny2313
t24- ATtiny24
t25- ATtiny25
t26- ATtiny26
t261- ATtiny261
t4- ATtiny4
t40- ATtiny40
t4313-ATtiny4313
t43u- ATtiny43u
t44- ATtiny44
t45- ATtiny45
t461- ATtiny461
t5- ATtiny5
t84- ATtiny84
t85- ATtiny85
t861- ATtiny861
t88- ATtiny88
t9- ATtiny9
x128a1- ATxmega128A1
x128a1d- ATxmega128A1revD
x128a1u- ATxmega128A1U
x128a3- ATxmega128A3
x128a3u- ATxmega128A3U
x128a4- ATxmega128A4
x128a4u- ATxmega128A4U
x128b1- ATxmega128B1
x128b3- ATxmega128B3
x128c3- ATxmega128C3
x128d3- ATxmega128D3
x128d4- ATxmega128D4
x16a4- ATxmega16A4
x16a4u- ATxmega16A4U
x16c4- ATxmega16C4
x16d4- ATxmega16D4
x16e5- ATxmega16E5
x192a1- ATxmega192A1
x192a3- ATxmega192A3
x192a3u- ATxmega192A3U
x192c3- ATxmega192C3
x192d3- ATxmega192D3
x256a1- ATxmega256A1
x256a3- ATxmega256A3
x256a3b- ATxmega256A3B
x256a3bu- ATxmega256A3BU
x256a3u- ATxmega256A3U
x256c3- ATxmega256C3
x256d3- ATxmega256D3
x32a4- ATxmega32A4
x32a4u- ATxmega32A4U
x32c4- ATxmega32C4
x32d4- ATxmega32D4
x32e5- ATxmega32E5
x384c3- ATxmega384C3
x384d3- ATxmega384D3
x64a1- ATxmega64A1
x64a1u- ATxmega64A1U
x64a3- ATxmega64A3
x64a3u- ATxmega64A3U
x64a4- ATxmega64A4
x64a4u- ATxmega64A4U
x64b1- ATxmega64B1
x64b3- ATxmega64B3
x64c3- ATxmega64C3
x64d3- ATxmega64D3
x64d4- ATxmega64D4
x8e5- ATxmega8E5

Linux-användare kan använda vin.

Jag hoppas att du redan har allt installerat, så låt oss starta AVR Studio...


Här ombeds vi att skapa ett nytt projekt eller öppna ett gammalt. Klick Nytt projekt


Välja AVR GCC, eftersom vi kommer att skriva i SI och inte i assembler.
Vi ger projektet ett namn och kryssar i rutorna.
Välja Plats (Jag skapade AVR-mappen på C:\-enheten) Mappar med projekt skapas automatiskt där.
Klick Nästa


Välja AVR Simulator, eftersom vi inte har en speciell programmerare som tillåter felsökning, och vår mikrokontroller är det ATmega328p.
Klick Avsluta.

Efter dessa manipulationer är studion redo för arbete.

Till vänster finns vägarna till projektet. I mitten finns en textredigerare där koden är skriven. Till höger finns regulatorregistren. Längst ner till vänster finns felsökningsinformation.

Av de knappar vi för närvarande är intresserade av dessa -

Bygg projektet.
Bygg projektet och börja felsöka.
Kompilerar filen.
Rengöring.
Projektuppsättning. Så klicka på den...

Här kan du ändra typ av MK, ställa in klockfrekvensen (vi skriver det direkt i koden), optimeringsnivå, samt bestämma vilka filer som kommer att skapas.
Klicka på ikonerna till vänster för intresse och klicka Annullera.
Jag kommer inte att förklara dessa och andra alternativ, men senare kommer jag att ge en länk med en kompetent beskrivning.

Kopiera nu koden som skrivits i början av artikeln och klistra in den i redigeraren:

Vi angav klockfrekvensen i koden eftersom biblioteket kräver det fördröjning.h.

Bygget lyckades, det fanns inga fel eller varningar.

Nu går vi vidare C:\AVR\my328\default\, vi hittar där hex-filen vi skapade - my328.hex och flasha in den i kontrollen. Vad ska man blinka (avrdude eller uniprof) välja själv.

I avrdude kommer det se ut så här:

Avrdude -c gromov -P com1 -p m328p -U flash:w:\AVR\my328\default\my328.hex ###WIN###
avrdude -c gromov -P /dev/ttyS0 -p m328p -U flash:w:my328.hex ###Linux###

Inaktivera "återställningen" och se dioden blinka en gång per sekund. Jag hoppas att jag har övertygat dig om enkelheten och bekvämligheten med kommandoraden.

För att göra tillbaka Arduino till en Arduino har du en backup.

Som redan skrivits ovan kommer jag inte att gå in på förklaringar av att arbeta med AVR Studio, och jag kommer inte heller att ge lektioner i SI-språket. För det första var detta inte min plan. (Jag ville bara hjälpa till att göra övergången från Arduino till AVR Studio)

En IDE är en integrerad utvecklingsmiljö som innehåller olika mallar, bibliotek och felsökningsfunktioner. Om vi ​​pratar om, sedan 2004 har ett kraftfullt mjukvarupaket, AVR studio, utvecklats för dem.

Första versionerna

De första versionerna av studion inkluderade en assembler för , du kan extrahera den från de första monteringarna, men senare övergavs detta projekt och C AVR valdes som huvudspråk. Kompilatorn var en betald och mycket seriös produkt IAR. Du kan ladda ner gratis WINAVR; för att göra detta måste du installera den efter att ha installerat studion.

Notera! Det är bättre att göra detta först efter att du har installerat AVR studio 4 och andra versioner.

AVR studio 4 (bilden ovan) var med under lång tid. Många utvecklare av mikrokontroller har stött på detta problem. Senare uppgraderades IDE till AVR studio 5. Förutom gränssnittet blev det inga speciella förändringar, och först då bytte utvecklarföretaget om produkten och bytte namn till Atmel studio 6.

AVR studio 5-miljön stödde följande mikrokontroller:

  • AVR32;
  • XMEGA.

Atmel studio 6 skilde sig avsevärt från AVR studio 5; de mest märkbara innovationerna i versionen var:

  1. Microsoft Visual Studio 2010 började arbeta med AVR-familjen.
  2. Förbättrad syntaxmarkering jämfört med AVR studio 5.
  3. Tillagda tips och automatisk komplettering av en uppsättning kommandon, vilket påskyndar utvecklingsprocessen.
  4. Generellt sett har hela driften av miljön blivit mer tillförlitlig.
  5. Tillagt stöd för ARM Cortex-M.
  6. WinAVR behöver inte längre installeras separat, GCC installeras nu under installationsprocessen, till skillnad från yngre versioner.

I Atmel studio 6 skedde ett steg till det bättre för användaren av programmet, vilket påverkade Atmel-familjernas popularitet. Det var dock inte möjligt att uppnå tillräckligt stöd för ryska tecken i filsökvägar.

Aktuell version – Atmel studio 7

Utvecklingsmiljön jag använde var Visual Studio Isolated Shell 2015; å ena sidan stöds inte denna lösning på Windows XP, å andra sidan vidtogs dessa åtgärder för att förbättra både programmets utseende och dess funktionalitet.

Det kanske mest betydelsefulla är tillägget av Arduino-stöd i Atmel studio 7. Det betyder att du kan gå från en uppsättning enkla skisser till att använda alla C-funktioner, felsökning, MCU-simulator och andra funktioner. Kombinationen av Arduino och Atmel studio 7 gav en ny omgång i utvecklingen av denna enkla lärplattform.

Att studera Atmel studio med Arduino kommer att ge en möjlighet att gå vidare till en komplett och produktiv behärskning och djupare bekantskap med hjärtat av Arduino - Atmega mikrokontroller.

Dessutom, från Atmels webbplats kan du ladda ner ett paket för att använda och ansluta LCD-skärmen. Som ett exempel för mastering kan du använda LCD 1602; det finns många lektioner om det på Internet, och utvecklaren har 16 tecken och 2 rader tillgängliga på displayen.

Var ska man börja lära sig?

Du bör naturligtvis börja med att köpa en programmerare; Den mest budgetvänliga är USBASP. USBASP-programmeraren stöds inte i Atmel Studio 7.


Ladda ner drivrutinerna för programmeraren och AVRdude-programmet, och för att få det hela att fungera kan du använda kommandot via kommandoraden:

"avrdude -c usbasp -p atmega32 -U flash:w: namnet på firmwarefilen. hex -U lfuse:w:0x6a:m -U hfuse:w:0xff:m"

och aktivera dess stöd genom att skapa en profil i atmel studio 7 (titel – externa verktyg), och i Argument-objektet skriv in "-c usbasp -p atmega32 -U flash:w:$(TargetName).hex" och så vidare för varje typ du använder mikrokontroller.

Detta är det enda sättet att koppla ihop studion och USBASP-programmeraren. Var försiktig när du blinkar - du kan skada mikrokontrollerns signatur, och den kan bara återställas med en 12 V (högspänning) programmerare.

Vilken litteratur ska jag använda för träning?

Först av allt, ladda ner manualer från den officiella webbplatsen för varje mikrokontroller. Det är svårt att rekommendera en specifik lärobok, men det finns ”DI Halt - AVR. Utbildningskurs" kan du använda den - skaparen av detta material är en utövare, författare till många artiklar om olika internetresurser och helt enkelt en respekterad person i specialistkretsar.

Jag har sagt mer än en eller två gånger att studera MK ska börja med assembler. En hel kurs på webbplatsen ägnades åt detta (även om det inte är särskilt konsekvent, men efter hand kammar jag det till ett adekvat utseende). Ja, det är svårt, resultatet kommer inte att vara den första dagen, men du kommer att lära dig att förstå vad som händer i din kontroller. Du kommer att veta hur det fungerar, och inte kopiera andras källor som en apa och försöka förstå varför det plötsligt slutade fungera. Dessutom är det mycket lättare för C att skapa redneck-kod som kommer ut med en höggaffel vid det mest olämpliga ögonblicket.

Tyvärr vill alla ha resultat direkt. Så jag bestämde mig för att gå åt andra hållet - göra en tutorial på C, men med att visa hans underkläder. En bra inbäddningsprogrammerare håller alltid sin hårdvara hårt vid bulten, så att den inte kan ta ett enda steg utan tillstånd. Så först blir det C-koden, sedan vad kompilatorn producerade och hur det hela faktiskt fungerar :)

Å andra sidan är C:s starka sida kodportabilitet. Om du förstås skriver allt rätt. Separera arbetsalgoritmerna och deras hårdvaruimplementationer i olika delar av projektet. Sedan, för att överföra algoritmen till en annan mikrokontroller, räcker det att endast skriva om gränssnittslagret, där alla anrop till hårdvaran skrivs, och lämna all arbetskod som den är. Och förstås läsbarhet. C-källkoden är lättare att förstå vid första anblicken (även om ... till exempel, jag bryr mig inte om vad jag ska peka på - vare sig det är C eller ASM :)), men återigen, om allt är skrivet korrekt. Jag kommer också att uppmärksamma dessa punkter.

Mitt felsökningskort kommer att fungera som den experimentella hårdvaran på vilken lejonparten av alla exempel kommer att installeras.

Det första C-programmet för AVR

Att välja en kompilator och ställa in miljön
Det finns många olika C-kompilatorer för AVR:
Först av allt detta IAR AVR C- är nästan definitivt erkänd som den bästa kompilatorn för AVR, eftersom själva styrenheten skapades i nära samarbete mellan Atmel och specialister från IAR. Men du måste betala för allt. Och den här kompilatorn är inte bara en dyr kommersiell programvara, utan har också så många inställningar att det tar mycket ansträngning att helt enkelt kompilera den i den. Jag utvecklade verkligen ingen vänskap med honom; projektet ruttnade på grund av konstiga fel vid länkningsstadiet (senare fick jag reda på att det var en sned spricka).

Andra kommer WinAVR GCC- en kraftfull optimeringskompilator. Helt öppen källkod, plattformsoberoende, i allmänhet, alla glädjeämnen i livet. Den integreras också perfekt i AVR Studio, så att du kan felsöka direkt där, vilket är jävligt bekvämt. I allmänhet valde jag det.

Det finns också CodeVision AVR Cär en mycket populär kompilator. Det blev populärt på grund av sin enkelhet. Du kan få ett fungerande program i den på bara några minuter - startkodsguiden underlättar detta avsevärt genom att stämpla ut standarder för initiering av alla möjliga saker. För att vara ärlig är jag lite misstänksam mot det - när jag väl var tvungen att demontera ett program skrivet av den här kompilatorn visade det sig vara någon form av röra och inte kod. En fruktansvärd mängd onödiga rörelser och operationer, vilket resulterade i en ansenlig mängd kod och långsam prestanda. Men det kanske fanns ett fel i DNA:t hos personen som skrev den ursprungliga firmwaren. Plus att han vill ha pengar. Inte lika mycket som IAR, men märkbart. Och i demoläge låter den dig inte skriva mer än 2kb kod.
Naturligtvis finns det en spricka, men om du ska stjäla är det en miljon, i IAR-bemärkelse :)

Det finns också Image Craft AVR C Och MicroC från mikroelektronik. Jag behövde inte använda någondera, men S.W.G. mycket berömmande MicroPascal, säger de, en fruktansvärt bekväm programmeringsmiljö och bibliotek. Jag tror att MicroC inte kommer att vara sämre, men det är också betalt.

Jag valde som sagt WinAVR av tre anledningar: det är gratis, det integreras i AVR Studio och det finns bara massor av färdig kod skriven för den för alla tillfällen.

Så ladda ner WinAVR-installationen med AVR Studio. Därefter installeras studion först, sedan rullas WinAVR ovanpå och kopplas till studion i form av en plugin. Jag rekommenderar starkt att du installerar WinAVR på en kort väg, ungefär som C:\WinAVR, på så sätt slipper du många problem med sökvägar.

Skapa ett projekt
Så, studion är installerad, C är fastskruvad, det är dags att försöka programmera något. Låt oss börja med det enkla, det enklaste. Starta studion, välj ett nytt projekt där, som AVR GCC-kompilator och ange namnet på projektet.

Ett arbetsfält öppnas med en tom *.c-fil.

Nu kommer det inte att skada att konfigurera visningen av vägar i studiobokmärkena. För att göra detta, gå till:
Meny Verktyg - Alternativ - Allmänt - Filflikar och välj "Endast filnamn" från rullgardinsmenyn. Annars kommer det att vara omöjligt att fungera - fliken kommer att innehålla hela sökvägen till filen och det kommer inte att finnas mer än två eller tre flikar på skärmen.

Projektuppsättning
I allmänhet anses det vara klassiskt att skapa en make-fil där alla beroenden beskrivs. Och det är nog rätt. Men för mig, som växte upp med helt integrerade IDE som uVision eller AVR Studio detta tillvägagångssätt är djupt främmande. Därför kommer jag att göra det på mitt sätt, allt med hjälp av studiomedel.

Peka på knappen med kugghjulet.


Det här är inställningarna för ditt projekt, eller snarare inställningarna för automatisk generering av en make-fil. På den första sidan behöver du bara ange den frekvens med vilken din MK kommer att fungera. Detta beror på säkringsbitarna, så vi antar att vår frekvens är 8000000Hz.
Var också uppmärksam på optimeringslinjen. Nu finns det -Os - detta är storleksoptimering. Lämna det som det är nu, så kan du försöka spela med den här parametern. -O0 är ingen optimering alls.

Nästa steg är att konfigurera sökvägarna. Först av allt, lägg till din projektkatalog där - du kommer att lägga till tredjepartsbibliotek där. Sökvägen ".\" visas i listan.

Make-filen har skapats, du kan titta på den i standardmappen i ditt projekt, ta bara en titt och se vad som finns där.


Det var allt tills vidare. Klicka på OK överallt och gå till källan.

Formulering av problemet
Ett tomt pappersark är frestande att implementera någon listig idé, eftersom det banala blinkandet av en diod inte längre fungerar. Låt oss omedelbart ta tjuren vid hornen och implementera kopplingen till datorn - det här är det första jag gör.

Det kommer att fungera så här:
När en etta (kod 0x31) kommer till COM-porten slår vi på dioden, och när en nolla kommer (kod 0x30) stängs den av. Dessutom kommer allt att göras på avbrott, och bakgrundsuppgiften kommer att blinka en annan diod. Enkelt och meningsfullt.

Montering av kretsen
Vi måste ansluta USB-USART-omvandlarmodulen till USART-stiften på mikrokontrollern. För att göra detta, ta en bygel från två ledningar och placera den på stiften korsvis. Det vill säga, vi ansluter styrenhetens Rx till omvandlarens Tx och omvandlarens Tx till styrenhetens Rx.

I slutändan är detta diagrammet:


Jag överväger inte att ansluta de återstående stiften, ström eller återställa, det är standard.

Skriver kod

Låt mig genast göra en reservation för att jag inte kommer att fördjupa mig specifikt i beskrivningen av själva C-språket. Det finns helt enkelt en kolossal mängd material för detta, allt från det klassiska "C Programming Language" från K&R till olika manualer.

Jag hittade en sådan metod i mitt förråd, jag använde den en gång för att studera detta språk. Allt där är kort, tydligt och rakt på sak. Jag sätter gradvis ihop det och drar det till min hemsida.

Det är sant att inte alla kapitel har överförts än, men jag tror att det inte kommer att dröja länge.

Det är osannolikt att jag kan beskriva det bättre, så från utbildningskursen, istället för en detaljerad förklaring av subtiliteterna, kommer jag helt enkelt att tillhandahålla direktlänkar till enskilda sidor i den här manualen.

Lägger till bibliotek.
Först och främst lägger vi till de nödvändiga biblioteken och rubrikerna med definitioner. När allt kommer omkring är C ett universellt språk och vi måste förklara för honom att vi arbetar specifikt med AVR, så skriv raden i källkoden:

1 #omfatta

#omfatta

Denna fil finns i mappen WinAVR och den innehåller en beskrivning av alla register och portar på styrenheten. Dessutom är allt där listigt, med bindning till en specifik styrenhet, som överförs av kompilatorn via göra fil i parameter MCU och baserat på denna variabel kopplas en header-fil till ditt projekt med en beskrivning av adresserna till alla portar och register för just denna styrenhet. Wow! Utan det är det också möjligt, men då kommer du inte att kunna använda symboliska registernamn som SREG eller UDR och du måste komma ihåg adressen till var och en som "0xC1", vilket kommer att vara en huvudvärk.

Själva laget #omfatta<имя файла> låter dig lägga till innehållet i vilken textfil som helst i ditt projekt, till exempel en fil med en beskrivning av funktioner eller en bit annan kod. Och för att direktivet skulle kunna hitta den här filen angav vi sökvägen till vårt projekt (WinAVR-katalogen är redan registrerad där som standard).

Huvudfunktion.
Ett C-program består helt av funktioner. De kan kapslas och anropas från varandra i valfri ordning och på olika sätt. Varje funktion har tre nödvändiga parametrar:

  • Returvärdet är t.ex. sin(x) returnerar värdet på sinus av x. Som i matematik, kort och gott.
  • De överförda parametrarna är samma X.
  • Funktionskropp.

Alla värden som överförs och returneras måste vara av någon typ, beroende på data.

Alla C-program måste innehålla en funktion huvud som en ingång till huvudprogrammet, annars är det inte alls C :). Genom närvaron av main i någon annans källkod från en miljon filer kan du förstå att detta är huvuddelen av programmet, där allt börjar. Så låt oss fråga:

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

int main(void) ( return 0; )

Det är det, det första enklaste programmet har skrivits, det spelar ingen roll att det inte gör någonting, vi har precis börjat.

Låt oss ta reda på vad vi gjorde.
int Detta är den datatyp som huvudfunktionen returnerar.

Naturligtvis i en mikrokontroller huvud i princip ingenting kan returneras och i teorin borde det vara det void main(void), men GCC är ursprungligen designad för PC och där kan programmet returnera värdet till operativsystemet när det är klart. Därför GCC på void main(void) svär vid varning.

Detta är inte ett fel, det kommer att fungera, men jag gillar inte varningar.

tomhet detta är den typ av data som vi skickar till funktionen, i det här fallet huvud kan därför inte heller acceptera något utifrån tomhet- en dummy. En stubb används när det inte finns något behov av att sända eller returnera något.

Här är de { } lockiga hängslen är ett programblock, i detta fall kroppen av en funktion huvud, kommer koden att finnas där.

lämna tillbaka- det här är returvärdet som huvudfunktionen kommer att returnera vid slutförandet, eftersom vi har en int, det vill säga ett tal, då måste vi returnera ett tal. Även om detta fortfarande inte är meningsfullt, eftersom... på mikrokontrollern kan vi bara gå ingenstans från main. Jag returnerar null. För det spelar ingen roll. Men kompilatorn är vanligtvis smart och genererar inte kod för det här fallet.
Även om, om pervers, då från huvud Du kan gå till MK - till exempel falla in i bootloader-sektionen och köra den, men detta kommer att kräva att du manipulerar på låg nivå med firmwaren för att korrigera övergångsadresserna. Nedan ser du själv och förstår hur du gör. För vad? Detta är en annan fråga, i 99,999% av fallen är detta inte nödvändigt :)

Vi gjorde det och gick vidare. Låt oss lägga till en variabel, vi behöver den egentligen inte och det är ingen idé att introducera variabler utan den, men vi lär oss. Om variabler läggs till inuti kroppen av en funktion, är de lokala och existerar endast i den här funktionen. När du avslutar funktionen raderas dessa variabler och RAM-minnet allokeras för viktigare behov. .

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

int main(void) (osignerad char i; return 0;)

osignerad betyder osignerad. Faktum är att i den binära representationen allokeras den mest signifikanta biten till tecknet, vilket innebär att talet +127/-128 passar in i en byte (char), men om tecknet kasseras kommer det att passa från 0 till 255. Vanligtvis behövs inte skylten. Så osignerad.
iär bara ett variabelnamn. Inte mer.

Nu måste vi initiera portarna och UART. Naturligtvis kan du ta och ansluta biblioteket och anropa någon form av UartInit(9600); men då vet du inte vad som egentligen hände.

Vi gör så här:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void) (osignerad 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<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

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

Skrämmande? Faktum är att det bara finns fem sista raderna med riktig kod. Allt som #definiera Det är ett förbehandlare makrospråk. Nästan samma saker som i Assembly, men syntaxen är något annorlunda.

De kommer att underlätta dina rutinoperationer för att beräkna de nödvändiga koefficienterna. I första raden säger vi det istället XTAL du kan säkert ersätta 8000000, och L- indikering av typen, som säger att lång är processorns klockfrekvens. Det samma baudrate— Frekvens för dataöverföring via UART.

bauddivider redan mer komplicerat, istället för det kommer uttrycket som beräknats med formeln från de två föregående att ersättas.
Bra och L.O. Och HEJ de låga och höga byten kommer att tas från detta resultat, eftersom Det kanske uppenbarligen inte passar in i en byte. I HEJ X (makroingångsparametern) förskjuts åtta gånger åt höger, vilket resulterar i att endast den mest signifikanta byten återstår. Och i L.O. vi gör bitvis OCH med siffran 00FF, som ett resultat kommer bara den låga byten att finnas kvar.

Så allt som är gjort är som #definiera du kan säkert slänga det och beräkna de nödvändiga siffrorna på en miniräknare och omedelbart skriva in dem på raderna UBBRL = …. och UBBRH = …..

Burk. Men! Gör det här ABSOLUT OMÖJLIGT!

Det kommer att fungera så eller så, men du kommer att ha sk magiska siffror- värderingar hämtade från ingenstans och av okända anledningar, och om man öppnar ett sådant projekt om ett par år så blir det jävligt svårt att förstå vad dessa värderingar är. Även nu, om du vill ändra hastigheten eller ändra kvartsfrekvensen, måste allt räknas om igen, men du ändrade ett par siffror i koden och det är allt. I allmänhet, om du inte vill bli stämplad som en kodare, gör sedan din kod så att den är lätt att läsa, förståelig och lätt att ändra.

Då är allt enkelt:
Alla dessa "UBRRL och Co" är konfigurationsregister för UART-sändaren med hjälp av vilka vi kommer att kommunicera med världen. Och nu har vi tilldelat dem de nödvändiga värdena, ställt in dem till önskad hastighet och läge.

Inspelningstyp 1< Betyder följande: ta 1 och sätt den på plats RXEN i byte. RXEN detta är den fjärde biten i registret UCSRB, Alltså 1< bildar det binära talet 00010000, TXEN- det här är den 3:e biten, och 1< ger 00001000. Singel "|" det är bitvis ELLER, alltså 00010000 | 00001000 = 00011000. På samma sätt ställs de återstående nödvändiga konfigurationsbitarna in och läggs till den allmänna högen. Som ett resultat registreras det insamlade numret i UCSRB. Mer detaljer beskrivs i databladet om MK i avsnittet USART. Så låt oss inte distraheras av tekniska detaljer.

Klart, dags att se vad som hände. Klicka på kompilering och starta emulering (Ctrl+F7).

Felsökning
Alla möjliga förloppsstaplar sprang igenom, studion ändrades och en gul pil dök upp nära ingången till huvudfunktionen. Det är här processorn körs för närvarande och simuleringen är pausad.

Faktum är att det från början faktiskt var på raden UBRRL = LO(bauddivider); Det vi har i definition är trots allt inte kod, utan bara preliminära beräkningar, varför simulatorn är lite tråkig. Men nu insåg han, den första instruktionen är klar och om du klättrar upp i trädet I/O-vy, till USART-sektionen och titta på UBBRL-byten där, kommer du att se att värdet redan finns där! 0x33.

Ta det ett steg längre. Se hur innehållet i det andra registret förändras. Så gå igenom dem alla, var uppmärksam på att alla angivna bitar är inställda som jag sa till dig, och de är inställda samtidigt för hela byten. Det går inte längre än till Return – programmet är över.

Öppning
Återställ nu simuleringen till noll. Klicka där Återställ (Skift+F5). Öppna den demonterade listan, nu kommer du att se vad som faktiskt händer i kontrollern. Visa -> Demonterare. Och inte YYAAAAAA!!! Assemblerare!!! SKRÄCK!!! OCH DET ÄR NÖDVÄNDIGT. Så att du senare, när något går fel, inte är dum i koden och inte ställer lata frågor på forumen, utan omedelbart sätter dig i magen och ser var du har fastnat. Det finns inget läskigt där.

Först kommer toppar från serien:

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 Hoppa +00000002: 940C0034 JMP 0x00000034 Hoppa +00000004: 940C0034 JMP 0x00000 +4C000000 +4C34 JMP 0x00000 +4C 0x00000034 Hopp +00000008: 940C0034 JMP 0x00000034 Hopp +0000000A: 940C0034 JMP 0x00000034 Hopp +0000000C: 34 J0C000x04 J0C0004 0000000E: 940C0034 JMP 0x00000034 Hopp +00000010: 940C0034 JMP 0x00000034 Hopp +00000012: 940C0034 JMP 0x00000 +400000 +4000 JMP 940C0000 0x00000034 Hopp +00000016: 940C0034 JMP 0x00000034 Hopp +00000018: 940C0034 JMP 0x00000034 Hopp +0000001A: 940 J0C000x4 : 940C0034 JMP 0x00000034 Hopp +0000001E: 940C0034 JMP 0x00000034 Hopp +000000020: 940C0034 JMP 0x00000030 9 JMP 020000034 0200000034 0200000034 JMP 020000034 JMP 020000034 0200000030 34 Hopp +00000024: 940C0034 JMP 0x00000034 Hopp +00000026: 940C0034 JMP 0x00000034 Hopp +00000028: 940C0030 Hopp 00304 JMP 00304

00000000: 940C002A JMP 0x0000002A Hopp +00000002: 940C0034 JMP 0x00000034 Hopp +00000004: 940C0034 JMP 0x00000 +4C34 JMP 0x00000 +40000 0x00000034 Hopp +00000008: 940C0034 JMP 0x00000034 Hopp +0000000A: 940C0034 JMP 0x00000034 Hopp +0000000C: 940 J0C0000000000E440 : 940C0034 JMP 0x00000034 Hopp +00000010: 940C0034 JMP 0x00000034 Hopp +00000012: 940C0034 JMP 0x00000030 9 JMP 000000034 Hopp +000000012: 940C0034 JMP 0x00000030 9 JMP 000000030 0400000034 JMP 010000034 0400000034 JMP 010000034 34 Hopp +00000016: 940C0034 JMP 0x00000034 Hopp +00000018: 940C0034 JMP 0x00000034 Hopp +0000001A: 940C0034 JMP +000040 JMP 00004 : 940C0034 JMP 0x00000034 Hopp +0000001E: 940C0034 JMP 0x00000034 Hopp +000000020: 940C0034 JMP 0x00000030 9 JMP 020000034 0200000034 0200000034 JMP 020000034 JMP 020000034 0200000030 34 Hopp +00000024: 940C0034 JMP 0x00000034 Hopp +00000026: 940C0034 JMP 0x00000034 Hopp +00000028: 940C0030 Hopp 00304 JMP 00304

Detta är avbrottsvektortabellen. Vi återkommer till det senare, men för nu är det bara att titta och komma ihåg att det finns. Den första kolumnen är adressen till flashcellen i vilken kommandot ligger, den andra är kommandokoden, den tredje är kommandot mnemonic, samma monteringsinstruktion, den tredje är kommandots operander. Tja, automatisk kommentar.
Så, om du tittar, finns det kontinuerliga övergångar. Och JMP-kommandokoden är fyra byte, den innehåller hoppadressen skriven bakåt - den låga byten vid den låga adressen och hoppkommandokoden 940C

0000002B: BE1F OUT 0x3F,R1 Ut till I/O-plats

Spelar in denna nolla på adress 0x3F. Om du tittar på I/O-vykolumnen kommer du att se att adress 0x3F är adressen till SREG-registret - kontrollenhetens flaggregister. De där. vi återställer SREG för att köra programmet på nollvillkor.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F Ladda omedelbart +0000002D: E0D4 LDI R29,0x04 Ladda omedelbart +0000002E: BFDE OUT 0x3E,R29 Ut till I/O plats +0000002F:/8 Ut till I/O plats +00000002F:/8000002F

0000002C: E5CF LDI R28,0x5F Ladda omedelbart +0000002D: E0D4 LDI R29,0x04 Ladda omedelbart +0000002E: BFDE OUT 0x3E,R29 Ut till I/O plats +0000002F:/8 Ut till I/O plats +00000002F:/8 Ut till I/O plats

Detta laddar stackpekaren. Du kan inte ladda direkt i I/O-register, endast genom ett mellanregister. Därför först LDI till mellanliggande, och sedan därifrån OUT till I/O. Jag kommer också att berätta mer om stacken senare. För nu, vet att detta är ett dynamiskt minnesområde som hänger i slutet av RAM och lagrar adresser och mellanliggande variabler. Nu har vi angett var vår stack ska börja från.

00000032: 940C0041 JMP 0x00000041 Hopp

Hoppa till slutet av programmet, och där har vi ett förbud mot avbrott och looping tätt på sig själv:

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

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

Detta är vid oförutsedda omständigheter, som att avsluta huvudfunktionen. Styrenheten kan tas ut ur en sådan slinga antingen genom en hårdvaruåterställning eller, mer troligt, genom en återställning från en vakthund. Tja, eller, som jag sa ovan, korrigera detta i hex-editorn och galoppera iväg dit vårt hjärta vill. Observera också att det finns två typer av övergångar: JMP och RJMP; den första är en direkt övergång till en adress. Den upptar fyra byte och kan direkt hoppa genom hela minnesområdet. Den andra typen av övergång är RJMP - relativ. Hans kommando tar två byte, men han flyttar sig från den aktuella positionen (adressen) 1024 steg framåt eller bakåt. Och dess parametrar indikerar offset från den aktuella punkten. Det används oftare pga tar upp halva utrymmet i en spolning, och långa övergångar behövs sällan.

1 +00000034: 940C0000 JMP 0x00000000 Hopp

00000034: 940C0000 JMP 0x00000000 Jump

Och detta är ett hopp till början av koden. En sorts omstart. Du kan kontrollera att alla vektorer hoppar här. Slutsatsen från detta är att om du nu aktiverar avbrott (de är inaktiverade som standard) och ditt avbrott inträffar men det finns ingen hanterare, så kommer det att ske en mjukvaruåterställning - programmet kommer att kastas tillbaka till början.

Funktion huvud. Allt är likt, du behöver inte ens beskriva det. Se bara på det redan beräknade antalet som förs in i registren. Kompilatorns förprocessor rockar!!! Så inga "magiska" siffror!

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

00000036: E383 LDI R24,0x33 Ladda omedelbart +00000037: B989 OUT 0x09,R24 Ut till I/O plats 15: UBRRH = HI(bauddivider); +00000038: BC10 UT 0x20,R1 Ut till I/O-plats 16: UCSRA = 0; +00000039: B81B UT 0x0B,R1 Ut till I/O-plats 17: UCSRB = 1<

Och här är buggen:

1 2 3 +0000003E: E080 LDI R24.0x00 Ladda omedelbart +0000003F: E090 LDI R25.0x00 Ladda omedelbart +00000040: 9508 RET Subrutin retur

0000003E: E080 LDI R24.0x00 Ladda omedelbart +0000003F: E090 LDI R25.0x00 Ladda omedelbart +00000040: 9508 RET Subrutin retur

Frågan är varför kompilatorn lägger till sådana toppar? Och det här är inget annat än Return 0, vi definierade funktionen som int main(void) och så slösade vi ytterligare fyra byte för ingenting :) Och om du gör void main(void) kommer bara RET att finnas kvar, men en varning kommer att visas , att vår huvudfunktion inte returnerar något. I allmänhet, gör som du vill :)

Svår? Uppenbarligen inte. Klicka steg-för-steg-exekvering i disassembler-läge och se hur processorn utför individuella instruktioner, vad som händer med registren. Hur sker rörelse genom kommandon och slutlig looping?

Fortsättning om ett par dagar...

Offtop:
Alexei78 Jag skapade ett plugin för Firefox som gör det lättare att navigera på min webbplats och mitt forum.
Diskussion och nedladdning,

Atmel Studio är en integrerad utvecklingsplattform som ger möjlighet att designa och felsöka applikationer utvecklade för Atmels mikrokontroller baserade på ARM Cortex-M-seriens processorarkitektur. Atmel Studio är en sömlös, lättanvänd miljö som ger möjlighet att felsöka och bygga applikationer skapade i C/C++ eller assemblerspråk. Den har ett inbyggt voluminöst bibliotek med helt gratis Atmel Software Framework-källkod, som inkluderar mer än 1 600 projekt för ARM- och AVR-arkitekturer. Att ha ett sådant bibliotek är en stor bonus för alla programmerare. Denna IDE kan användas för att programmera en mängd olika AVR-baserade mikrokontroller, såväl som Atmel SAM3-baserade flash-mikrokontroller som använder Cortex-M3, Cortex-M4-kärnor.

Atmel Studio innehåller också verktyg som kommer att göra livet för alla programmerare mycket enklare. Plattformen innehåller lösningar som Atmel Spaces och Atmel Gallery. Atmel Gallery är en onlinebutik med utvecklingsverktyg och integrerad programvara. Atmel Spaces är ett molnbaserat utrymme för gemensam utveckling och lagring av hårdvaru- och mjukvaruprojektfiler för Atmels mikrokontroller.

Nyckelfunktioner och funktioner

  • är en helt gratis integrerad utvecklingsmiljö;
  • stöder C/C++ och Assembler-språk;
  • åtföljs av detaljerad dokumentation;
  • inkluderar ett omfattande bibliotek med källkodsexempel för olika applikationer;
  • designad för programmering av Atmel-mikrokontroller.

Speciella krav

  • processorklockfrekvens på 1,6 GHz och högre;
  • för 32-bitars system från 1 GB RAM;
  • för 64-bitars system från 2 GB RAM;
  • när du kör på en virtuell maskin rekommenderas ytterligare 512 MB RAM;
  • 6 GB ledigt hårddiskutrymme.

Vad är nytt i den här versionen?

7.0.790 (25.02.2016)

  • lagt till stöd för utökad debugger (EDBG);
  • lagt till stöd för profiler för gränssnittsinställningar. Du kan växla mellan profiler med knapparna i inställningspanelen;
  • lagt till möjligheten att importera bibliotek till tidigare importerade projekt. Lade till stöd för Arduino Zero och Zero Pro;
  • parallellbyggning är nu aktiverad som standard;
  • uppdaterad firmware för Xplained Mini;
  • Funktionen "Visa alla filer" i Solution Explorer har åtgärdats.