Programfeltöltés ATmega mikrovezérlőkre

Tartalom:

  • Programfeltöltés az ATmega328p chip-be Arduino UNO-val
  • Programfeltöltés az ATmega328p chip-be STK500 programozóval
  • Programfeltöltés az ATmega328 chip-be AVR ISP Schield használatával
  • Fuse bitek állapotának megváltoztatása, hatásai a működésre, belső órajel használata
  • Programfeltöltés ATmega8 vezérlő-re, MiniCore alaplapkezelő
  • Arduino nano régi és új bootloadere közötti különbségek, bootloader csere, alapértelmezet chip frekvencia megváltoztatása
  • MiniCore alaplapkezelő hiba és javítása

——————————————————————————————————

Egy Arduino UNO R3-at használok programfejlesztésre, de az elkészült programot egy ATmega328 mikrovezérlőbe kellett beégetnem. Régebben nem volt még programozóm amivel egy chip-be betölthettem volna a programot, ezért az Arduino UNO R3-at szerettem volna erre felhasználni. Ennek a műveletsornak a lépéseit rögzítettem az alábbi dokumentációban. A kezdő lépésekhez a TAVIR weblapon találtam leírásokat!

A probléma megoldására a mai napig (2020) háromféle módszert használtam:

  1. Próbapanelon összerakott környezettel és az Arduino IDE ArduinoISP példaprogramjával.
  2. Egy 2019-ban Aliexpres-en vásárolt AVR ISP shield panel felhasználásával. Ez lényegileg ugyanaz mint az előző megoldás, csak kényelmesebbé vált a feltöltés során az „égetendő” chip mechanikai kezelése, dugdosása.
  3. STK500 programozó használata.

Az első két módszer lényegében azonos lépésekből áll:

  1. Feltöltjük a programfeltöltésre szolgáló programot az Arduino UNO R3-ra. Ezzel elkészül a „programozó” készülékünk
  2. A mikrokontrollerbe töltendő programot „programozóval” töltjük be a chip-be. Ekkor az Arduino Uno R3 lesz a programozó, ami 3 vezetékkel lesz összekötve az ATmega328P chip megfelelő lábaival. Nyilván chip-nek tápot kell adni, és kell minimum egy kvarc kristály és két kondi az órajel előállításhoz.

Az STK500 programozó esetén az első lépés kimarad, hiszen Arduino UNO-ra nincs is szükség, azt a programozó helyettesíti. A leírás végén erről is olvashatsz, de legelőször nézzük meg azt az esetet, amikor nincs programozónk, de van kéznél Arduino Uno.

  1. A programozó szoftver feltöltése Arduino-ra

Első lépés az égető szoftver feltöltése az Arduino UNO R3-ra.

Csatlakoztatni kell az USB portra az Arduino UNO R3-at, és beállítani az eszközök /alappanel menüben az Arduino Uno alappanelt, hiszen most magára az R3-ra szeretnék programot rátölteni. Mégpedig az ArduinoISP programot, amitől programozó lesz belőle.

Ezt követi a programozó megadása az eszközök/programozó menüpontban. Az ArduinoISP-t állítottam be:

Most jön a program kiválasztása. A file/minták menüből választottam ArduinoISP menüpontot. Ez a program kifejezetten erre a feladatra lett készítve:

Ezután jön a program égetése az R3-ra. Kattintsunk a feltöltés ikonra:

Villognak kicsit a ledek az Arduino UNO R3-on, és el is készült programozó.

  1. A program feltöltése „Arduino as ISP” programozóval

Ekkor kell összerakni az ATmega328P-t egy próbapanelon. Kell hozzá néhány alkatrészt. Itt a kapcsolási rajz:

Ezen a kapcsolási rajzon szerepel egy led a soros áramkorlátozó ellenállással. Nyilván ezt nem kell feltételül berakni be, csak nem találtam pont olyan rajzot a neten, ami a minimális alkatrészeket tartalmazza.

Sokat segít az összerakásnál a mikrovezérlő lábkiosztása, ezért segítségül itt van ez is:

Az én panelem így nézett ki:

Elismerem, hogy kicsit áttekinthetetlen. A kvarc-ot közvetlenül a mikrovezérlő lábaihoz dugtam be, a kondenzátorokat pedig a panel egyik végén kialakított „GND csomópontba”. Így a kondik teljes lábhosszúságára szükség volt. A reset láb felhúzó ellenállása látható még a képen a panel bal alsó sarkában.

Ekkor következik az R3 programozó és az ATmega328 összevezetékezése. Arduino weblapon található rajz teljesen áttekinthető és egyértelmű:

Mindez nálam kicsit csúnyábban fest:

Amikor elkészült a „kábelezés” beállítottam a programozót az eszközök/programozó menüpontban. Az ArduinoI as ISP-t kell választani, tekintve, hogy az Arduino UNO R3 ettől a perctől kezdve egy külső programozó készülék:

Egyébként ha nem akarjuk folyton az Arduino R3-at használni programozásra, meglehetősen olcsón kapható az Aliexpres-en a már említett STK500 programozó. Az STK500 nevet kell a keresőbe beírni, és bőségesen válogathatunk az olcsóbbnál olcsóbb eszközök között. 1000Ft alatt már lehet kapni, ami kb. így néz ki:


Olvastam a neten fórumokban, hogy a kínai cuccok szarok. Ez biztosan így is van. Az én amatőr körülményeimben azonban tökéletesen megfeleltek. A képen látható cucc valójában ugyanaz, mint amit az Arduino UNO és a hozzá vezetékezett dugdosós panelen összeraktam. Egy kisebb ATmega vezérlő van rajta, és egy USB soros illesztő IC, Nomeg a kábelek, amik megkönnyítik a dugdosást.

Most jön az alaplap kiválasztása. Persze itt nem alaplapról van szó, hanem egy chip-ről. Bár a felsorolt alaplapok között nem fogunk ATmega328P nevűt találni alapból, ne essünk kétségbe. Mivel akkoriban (2015-ben) én sem találtam, elkezdtem próbálkozni. Láss csodát, az Arduino UNO alaplappal pont működött a dolog (hiszen azon is ATmega328 chip található). Nyilván más alaplapokkal is ment volna! Nem tudom, hogy ezek miben különböznek, talán nem is érdekes:

…és ezzel minden előkészület megtörtént! Megkezdődhetett a program beégetése. Tanulás képen a blink alapprogramot égettem be, ezt könnyű volt kipróbálni égetés után. Tehát a file/példák/basic/blink programot nyitjuk meg:

És következhet a pont az i-re. Be kell égetni a programot a chip-be. Ehhez a vázlat/feltöltés programozót használva menüpontot kell választani:

A képernyőn csak egy halovány felirat jelent meg a program alsó üzeneteket megjelenítő részén arról, hogy folyik az égetés (elfelejtettem kifotózni). Az R3 ledjei vadul villogtak pár másodpercig. Aztán „égetés kész” felirat jelent meg.

Valóságban nem ezzel kezdtem, hanem a bootloader égetéssel. Ráadásul a vásárolt chip-ben már volt bootloader az ismertető szerint, de ezt is ki akartam próbálni. Ehhez az eszközök menü/bootloader beégetése menüpontot kellett kiválasztani. Ezt a lépést a továbbiakban már soha nem csináltam, nyilván nem is kell. Összesen négy chip-et vettem eddig, ezek már gyárilag tartalmazták a bootloadert!

Természetesen az elkészült chip-et le is ellenőriztem. Lehúzogattam a programozó vezetékeket, csak a tápfeszt hagytam rajta. Rádugtam a 28-as lábra egy ledet (az Arduino 13-as digitális ki/bemenete egyben a beépített led, ami az ATmega328P chip-en a 28-as számú kivezetés), ami szépen villogott!!

Program feltöltés AVR ISP Schield használatával

Teltek múltak a hónapok, és chip égetésére nem is volt szükségem, de egy újabb munkához megint csak kellett. Közben az előző módszer leírásában említett próbapanelen vezetékezett környezet megsemmisült. Az Aliexpres-en megláttam egy Arduino UNO R3-ra rádugható panelt, amin már kész a környezet, az ATmega328P chip könnyedén bedugható a nyitható-zárható foglalatba. Így néz ki:

Ez szuper! Tulajdonképpen semmi nem változott, ez csak egy kész vezetékezés a kvarcz kristállyal, két kondenzátorral. Található még rajta 3 led, ami a feltöltés állapotáról tájékoztat. Égetés közben a ledeken látható egy kicsike „tűzijáték”, amit próbáltam értelmezni. Ha minden rendben, akkor a zöld led látványosan pulzál. Piros, ha valami nincs rendben. Egy kis hangszóró is van rajta, ami hangosan tülköl hiba esetén. Beállítani úgy kell mindent, amit a fentebb lévő leírásban olvasható.

Azonban sokat szívtam vele, mert előkerült egy ATmega8 chip. Nem vettem észre, hogy nem ATmega328P van a kezemben, és csodálkoztam, hogy nem működik. Több órás próbálkozás után végre rászántam magam és értelmeztem a hibaüzenetet. Előkerült egy nagyító, és megbizonyosodhattam róla, hogy az ATmega328 tényleg nem ugyanaz mint az ATmega8.
Olyan nyúlfarknyi programot kellett feltöltenem, ami az ATmega8-ban is elfért. Keresni kellett tehát egy olyan alaplapot, ami megfelel az ATmega8-nak!
Már előzőleg is említettem, hogy a feltöltéskor az alaplap választásakor bizonytalan voltam, mert nem találni ATmega328P alaplapot, csak Arduino UNO alaplapot, amivel szerencsére sikerült a feltöltés. Az ATmega8-nak viszont semmit nem találtam. Mindent kipróbáltam, semmivel nem működött. Így nem volt mit tenni el kellett kezdenem böngészni a netet, hátha van megoldás. Persze, hogy van! Találtam valahol egy cikket, ami pont erről szólt. Az alábbiakat kell tenni:

Meg kell keresni az Arduino IDE-ben a file/beállítások menüt, és a “további Alaplap-kezelő URL-ek:” sorba be kell írnia következőt: https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json

Most el kell kezdeni az alaplap kiválasztást és rögtön a legfelső “Alaplap kezelő” menüpontot kiválasztani:

A megjelenő keresőbe írjuk be “minicore”, és válasszuk ki az egyetlen megjelenő alaplapot, és telepítsük:

…és igen, megtörtént a csoda. Van már az alaplapok között ATmega chip-ből mindenféle:

Túl hosszú volt az alaplap felsorolások listája, ezért inkább két képet csináltam. Viszont érdemes megfigyelni, hogy ez első képen kiválasztott ATmega8 alaplap alatt megjelent egy csomó új menüpont, amikre eddig nem kellett odafigyelni. A minicore alaplap kezelő leírásban erről rengeteg részletet találunk. A minicore kiválasztásakor a telepítés nyomógomb megnyomása előtt (keressük meg újra) kattintsunk a “More info” linkre, és szemezgessünk a rengeteg infóból.
Engem ezek közül az órajel frekvenciáról szóló rész hozott izgalomba. Egy alkalommal szerettem volna kvarc kristály nélkül egyetlen led-et vezérelni. Pontosabban egy RGB led-ből akartam változtatható színű hangulatfényt építeni csupán virtusból. Remek lett volna, ha semmi nem kell a vezérlőn kívül. Olvasgattam is a vezérlő adatlapját, amiben megtaláltam a belső RC oszcillátorról szóló leírást. De azt már a szerény angol tudásom birtokában nem tudtam megfejteni, hogy ezt miképpen kellene beállítani. Feltettem hát a kérdést az egyik fórumon, hogy valaki segítsen. Nem az volt a válasz, hogy „ezt meg ezt kell csinálni”, hanem arról érdeklődtek, minek ez nekem, miért akarok filléreket spórolni a kvarc kristályon és hasonlók. Elég lett volna nekem egy “Nem tudom!” vagy “Nem akarom megmondani!” is. Ez volt az a a pillanat, amikor rájöttem, sokan nem is akarnak segíteni.
Ezeknek a plusz menüpontoknak a működéséről az STK500 programozónál még lesz némi információ. Ha tovább olvasod a leírást, hamarosan odaérsz.

Program feltöltés STK500 programozóval Arduino nano-ra (vagy másra):

A programozó használatához minimális odafigyelésre van szükség. Ugyanis az Arduino nano áramkörére betervezték ugyan az ICISP csatlakozót, de a programozóval történő csatlakoztatás nem teljesen egyértelmű. Az Arduino nano “pinout” ábráján külön kirajzolták a csatlakozót:

Azonban itt nem szerepel semmi arról, hogy melyik az “1”-es csatlakozó pont, amit a nyákon feltüntettek. Persze könnyű kitalálni, hiszen ez az ábra is felülnézetben ábrázolja a csatlakozót. A programozó picike kis nyáklemezén, ami csatlakozót tartalmazza, szerepel az egyes kivezetések neve, így könnyű kitalálni, hogy a MISO lábat a csatlakozó jobb felső pontjához kell irányítani! A gyártók természetesen nagyon jók a megtévesztésben, ugyanis tapasztalatom szerint a a fenti rajzon a jobb felső kivezetéshez rajzolt pici kis pont (én inkább karikának látom), az a valós áramkörökön egy vonal. Itt a rajzon 0 a valóságban 1. Így én a programozó csatlakoztatását mindig imával kezdem: „add Utram, hogy ne kelljen újat vennem…”. Miután csatlakoztattuk a programozót az Arduino nano-hoz és bedugjuk a programozót az USB portba, a nano-n a megszokott tápfesz jelző piros led világit. Megnyugodhatunk, nem rontottuk el.
A programozó bedugásakor a Windows 10 USBasp nevű drivert próbált telepíteni, de a Windows eszköz kezelőjében látható volt, hogy a driver nem elérhető:

Nyilván az a baj, hogy az eszköznek driverre van szüksége. Kis kutakodás után a neten (Google usbasp szóra sok találatot ad fel). Két helyen is találtam drivert. Az egyik a következő elérési utvonalról tölthető le: https://protostack.com.au/download/USBasp-win-driver-x86-x64-v3.0.7.zip
Az itt található állományt ki kell bontani, és elindítani az installdriver.exe programot. Megnyomni a szokásos next-next gombokat, és kész is. A másik lehetőség a fórumokon a Zadig (https://zadig.akeo.ie/) weboldal. Innen a le kell tölteni a driver telepítő programot , és futtatni.

Az a lényeg, hogy a Windows eszközkezelőben megjelenjen egy USBasp nevű eszköz és rendben működjön. Ezzel az eszközzel azonban nem keletkezik COM port, így az Arduino IDE programban az eszközök menüben a “Port” menüpont szürke marad. Ez azonban nem baj. Alaplapnak válasszuk ki az éppen aktuális alaplapot (pl. Arduino nano, vagy Arduino UNO stb.). Programozónak válasszuk az USBasp nevű programozót. Ne felejtsük el, hogy a programot ekkor nem a szokásos módon a feltöltés ikonnal lehet elvégezni, hanem a vázlat menüpontban a “Feltöltés programozót használva Ctrl + Shift + U” menüpontot kell használni. Azon se lepődjünk meg, hogy a program feltöltés figyelmeztető üzenetet (Warning) eredményez.

Ezt nyugodtan figyelmen kívül hagyhatjuk, a feltöltés rendben megtörtént. Ha bootloadert égetünk, ugyanezt fogjuk tapasztalni. A bootloader feltöltése (csak) a képen látható figyelmeztető üzeneteket eredményezte, így látszólag felkerült a chip-re, de valójában nem történt meg. Nem jöttem rá, hogy mi a hiba, de kísérletezgetéssel sikerült mégis a bootloader feltöltés. Abból indultam mi, hogy a bootloadert nem egy Arduino nano-ra akarom feltölteni, hanem egy ATmega328 chip-re. Azonban az Arduino IDE kiválasztható alaplapjai között nem szerepel ez a mikrovezérlő. Azonban kicsivel ez előtt leírtam, hogyan lehet letölteni a minicore alaplap kezelő könyvtárat. Ebben már van ATmega328. Így ezt választottam ki:

Ezt követően már lényegesen több beállítási lehetőség jelent meg, amiből semmit nem állítottam át, csak rákattintottam a bootloader égetése menüpontra.:

Ekkor már lényegesen több információ jelent meg a feltöltésről, és sikeres is volt. A feltöltés infóiból egy részlet:

Az Arduino piros led-je másodpercenként két gyors felvillanást produkált a feltöltését követően. Az eredeti program törlődött.
Azt figyeltem még meg, hogy az új bootloader-es nano bekapcsoláskor másként villogtatja a led-et. Amikor bedugom az usb portba és tápfeszt kap, az új bootloader hét alkalommal dupla felvillanással jelez:

A régi bootloader csak szimpla felvillanásokat produkál:

Fuse bitek módosítása

Amikor megtaláltam a mincore alaplap kezelőt, kikísérletezgetni kezdtem. Elővettem az ATmega8 chip-et, összehuzaloztam egy led villogtató kacsolást a kvarcz kristállyal, két kondenzátorral. Ekkor már volt STK500-as programozóm, azt is belehuzaloztam a kapcsolásba. Be kellett kötni a GND, VCC, reset, Miso, Mosi és Sck vezetékeket. Amint a programozót bedugtam az USB portba, máris feszültséget kapott az ATmega8 chip. Ha lett volna rajta program, minden bizonnyal villog is a led azonnal. Töltöttem is rá egy blink példa programot, és a led villogott. Most jött a kísérletezgetés. Sorban kiválasztottam az esetemben lehetséges órajeleket. Nyilván az 1Mhz és 8Mhz belső órajel, és 16Mhz külső jöhet szóba. Rátöltöttem először az 1Mhz belső órajel beállítással egy bootloadert a chip-re:

A bootloader rátöltése törli a programot, ezért miután megláttam a bootloader betöltését nyugtázó OK üzenetet alul, a “Feltöltés programozót használva” menüponttal rátöltöttem újra a chip-re a blink programot. És a led villog. Gyorsan lekapkodtam a kvartz kristályt a kapcsolásról, adtam neki külön 5V tápfeszt, és a led tovább villog. Kipróbáltam a 8Mhz beállítást is (kvarcz-ot nem kell visszatenni), és azzal is működött. Aztán vissza akartam állni a kvarcz kristályos 16Mhz külső órajelre. Na ez már nem sikerült, csak ha a bootloader égetés előtt visszaraktam a kvarcz kristályt és a két kondit a helyére.
A bootloader égetése közben a képernyő alján rengeteg információ jelenik meg. Ezekből kiszemezgettem, hogy mit is csinál a folyamat, és milyen fuse biteket állít be:

 Bootloader-elBootloader nélkül
1Mhz belső órajelLfuse:10100001 Hfuse:11010100Lfuse:10100001 Hfuse:11010101
8Mhz belső órajelLfuse:10100100 Hfuse:11010100Lfuse:10100100 Hfuse:11010101
16Mhz külső órajelLfuse:10111111 Hfuse:11000100Lfuse:10111111 Hfuse:11000101

Még esetleg a BOD beállítás lehet hasznos a megjelenő menüpontok közül. ez a BOD paraméter azt a feszültséget határozza meg a vezérlőnek, ami alatt leáll a működés. Pl. ha elemről tápláljuk a vezérlőt és az elem feszültsége a beállított 2,7V alá csökken, akkor a vezérlő leállítja magát. Ez jobb, mintha bizonytalan működést idéz elő az elégtelen tápfeszültség, mivel egyes részei még működnek a vezérlőnek, míg mások nem.
Találtam táblázatot, hogy egyes vezérlőknél milyen feszültség értékeket lehet beállítani:

atmega328ATmega168atmega88ATmega48ATmega8
4.3V4.3V4.3V4.3V4.0V
2.7V2.7V2.7V2.7V2.7V
1.8V1.8V1.8V1.8V
TiltvaTiltvaTiltvaTiltvaTiltva

Viszont erre még nem volt szükségem, így kísérleteket nem végeztem a BOD feszültség tárgyában!

...és még két gyakorlati tapasztalat:

Vettem néhány új ATMEGA328P chip-et, és szerettem volna programot feltölteni rá. Általában a blink programmal próbálkozom, mert ha az felmegy, és van LED a chip-re kötve (és miért ne lenne), akkor rögtön látszik, hogy működik a világ! Hát most nem működött! Pontosabban nem pont úgy, ahogy a blink-nek működnie kellene! A LED 10sec periódusidővel villogott. Fórumokon találtam bejegyzést arról, hogy sok chip-et gyárilag 1Mhz sebességre állítanak be a FUSE bitekben. Ezért először rá kell tölteni egy bootloadert a chip-re, akkor is ha nem kell bootloader! Természetesen a paraméterekben a 16Mhz legyen beállítva, de hát ez az alapértelmezett, így nehéz elrontani! Aztán lehet feltölteni a programot, akár a bootloader törlésével. …és a világ jól működik!

Meglepetés ért a MiniCore alaplapkezelő könyvtárral is. Írtam egy nagyon egyszerű kis programot, ami egy RF-433-as rádió vevővel működött, és a RadioHead és a Wire könyvtárakat használta. A program olyan kicsi lett, hogy elfért egy ATmega8 chip-ben is. Nosza töltsük bele. Azonban a MiniCore alaplapkezelő vezérlő készletéből kiválasztva a chip-et, a egy csomó hibaüzenet keletkezett annak a programnak a fordítása során, ami már működött Arduino nano-ra töltve. Kiválasztottam az ATmega328 chip-et, de ugyanazok a hibák jöttek a fordítás során. Idézet a hibákból:

C:\Users\Zoli\OneDrive\Arduino\programok\Radios_kozponti_egyseg\Vev_I2C\Vev_I2C_2\Vev_I2C_2.ino: In function ‘void setup()’: Vev_I2C_2:15:30: error: invalid conversion from ‘void (*)()’ to ‘void (*)(int)’ [-fpermissive]
   Wire.onReceive( slave_fogad); 
                              ^

Szinte minden függvényhívásra ugyanez a hiba keletkezett, amit nem igazán tudtam értelmezni. Természetesen a Google a barátunk ebben is tudott segíteni! Találtam egy fórum bejegyzést amin nem Arduino környezetben szó esett a -fpermissive kapcsolóról, az ott talált kifejezésekkel kiegészítve egyszer csak ráakadtam a következő Arduino-s fórumbejegyzésre:

https://forum.arduino.cc/t/cant-compile-code-for-atmega328/529000/16

… innen már ment minden, mint a karikacsapás! A módszert leírták, változtatás nélkül továbbadom! A lényeg az, hogy a MiniCore alaplapkezelőben van egy hiba, amit a fejlesztő már nem javított ki. Nevezetesen a compiler meghívásakor kifelejtette az említett -fpermissive kapcsolót  a paraméterek közül. Ezt kell csak valahogyan pótolni. A dolog nagyon egyszerű:

  1. keressük meg a MiniCore alaplapkezlő könyvtárát (nálam itt van a gépen, de ez mindenkinél más: „C:\Users\Zoli\AppData\Local\Arduino15\packages\MiniCore\hardware\avr\2.1.3”)
  2. Készítsünk ide egy platform.local.txt nevű szövegfile-t
  3. A szövegflie tartalma legyen: compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD

Ezzel készen is vagyunk! A következő fordításnál már nem lesznek hibaüzenetek. Megjegyzem, ha az Arduino IDE beállításaiban a fordító hibaüzeneteiben bekapcsoljuk a fordító figyelmeztetésekben az összes opciót, akkor  feti hibaüzenetek meg fognak jelenni, de ettől még a program lefordul.

Ha a MiniCore alaplapkezelőhöz frissítés jelenne meg a jövőben, akkor az el fogja törölni a szövegfájlunkat, azaz minden frissítés után el kell végezni a fentieket, ha használni szeretnénk a programot. Sok sikert a MiniCore használatához!

Mennyire volt hasznos amit olvastál? Értékelés után szövegesen is leírhatod megjegyzéseidet és véleményedet!

Kattints egy csillagra az értékeléshez!

Szövegesen is leírhatod véleményedet! Ha kérdésed van, ne felejtsd el megadni az email címedet!