Atmega8 kapcsolat. URM37 távolságérzékelő - csatlakozás az AVR-hez és a számítógéphez (USB-n keresztül)

A cikk a LED-ek mikrokontrollerhez való csatlakoztatását, a portokkal való munkát és a program írását SI-ben tárgyalja. A cikk elsősorban azoknak a kezdőknek szól, akik most kezdték el az AVR mikrokontrollereket.

Először ki kell választania egy mikrokontrollert. Az én esetemben ATmega8535. Ebben az esetben bármilyen mikrovezérlőt használhat, mivel ez a feladat bármely mikrokontroller alatt könnyen megvalósítható. Assembly-ben, SI-ben, Pascalban és Bascomban is lehet programot írni egy mikrokontrollerhez. SI nyelvet használtam, ezek a nyelvek különböznek egymástól.
A C és a Pascal közötti specifikus különbség az alábbiakban látható.

//Villogó LED void main() ( ddrB = 0b11111111; //beállítja a B portokat a kimeneti portra B = 0b11111111; //alapértelmezés szerint minden ki van kapcsolva, míg(1) ( portB = ˜portB; //a LED állapotának átváltása delay_ms(100 ); //késleltetés 100 ezredmásodperccel ) )

Program első; start ddrB:= $FF; //A B port beállítása B kimeneti portra:= $FF; //alapértelmezés szerint semmi sem világít, míg(1) do begin portB:= not(portB); //a LED állapotának váltása fordított késleltetésre_ms(100); //rövid késleltetés végét tesszük; vége.

Radioelemek listája

Kijelölés típus Megnevezés Mennyiség jegyzetÜzletA jegyzettömböm
U1 MK AVR 8 bites

ATmega8535

1 Jegyzettömbhöz
R1-R8 Ellenállás

220 Ohm - 1 kOhm

8 Jegyzettömbhöz
R9-R11 Ellenállás

10 kOhm

3 Jegyzettömbhöz
V1-V8 Fénykibocsátó dióda 8 Jegyzettömbhöz
Tapintat gomb 3

Emuláltuk az áramkört a Proteus programban, villogtunk a LED-en, és megtanultuk, hogyan kell villogni a virtuális mikrokontrollerünkön. Bizonyára sok olvasóban felmerült a gondolat: „Lehet villogni egy LED-et az MK-hoz csatlakoztatott gombbal?

Igen, természetesen lehetséges. Meglehetősen könnyű megvalósítani. Ezenkívül emulálhat egy gombot rögzítéssel vagy anélkül. Ezenkívül a Proteus programban mindkét típusú gombot használhatja ugyanazzal a gombmakróval. Milyen esetekben lehet ez hasznos? Például ki kell választanunk a készülék működési módjait. Nézzük meg közelebbről, hogyan lehet ezt megvalósítani egy mikrokontrollerrel, és végezzünk emulációt a Proteus programban.


Annak érdekében, hogy világos elképzelésünk legyen arról, hogy valóban két mód közül választhatunk, összeállítunk egy egyszerű áramkört 4 LED-ből egy gombos vezérléssel. Az első lehetőségnél az első és a negyedik LED felváltva világít. A második lehetőségnél ugyanaz, de fordított sorrendben, vagyis a negyediktől az elsőig. Az egyetlen dolog, amit tisztázni szeretnék, az az, hogy a gomb megnyomására vagy elengedésére csak az effektus kezdete előtt kerül sor. Amíg az effekt be nem fejezi munkáját, a program nem reagál a gomb megnyomására vagy elengedésére.

Tehát a lényegre. Így néz ki diagramunk a Proteus programban (kattintson a nagyításhoz):

Ebben a sémában már látunk eltéréseket az előző cikkben összegyűjtötttől. A diagram bal oldalán a gomb és a +5 voltos tápforrás megnevezése látható.

Ahogy már megbeszéltük, átvesszük a hatalmat, és a „Terminál” fülön landolunk. Ezeket teljesítménynek és földnek jelöljük.

Az áramkör tápellátását egy háromszöggel jelöljük, amelynek magasságában egy egyenes osztja el. A közelben, az ábrán látható a gomb megnevezése. A gombtól jobbra egy kitöltött piros kört látunk egy kétfejű nyíllal. Ha emuláció közben rákattint, a gomb rögzítve lesz és folyamatosan nyomva lesz. Újbóli megnyomása után a rögzítés megszűnik.


Használat előtt ugyanúgy ki kell választanunk egy gombot a könyvtárban, mint a többi részt. Ehhez írja be a „de” szót a „Maszk” mezőbe. Ezután az „Eredmények” mezőben írja be a „GOMB” szót:


Ezt követően a gomb megjelenik a listánkban a projektben használt kiválasztott részekkel együtt.

Milyen portokat használunk a projektben? Az alábbi ábrán a PA0, PB0, PB1, PB2 és PB3 portokról kimenő vonalak láthatók. A B porthoz LED-ek vannak csatlakoztatva, az A porthoz pedig egy gomb.

Tehát megnyomva lezárjuk a +5 voltos áramkört a PA0 porthoz és az ellenállás felső kivezetéséhez. Miért van itt egyáltalán ellenállásunk? A helyzet az, hogy a gomb áramkörét le kell zárni. Az ellenállás felszerelése után az áram a tápegység pozitív felől a gombon, az ellenálláson és tovább folyik a földre.

Elég, ha az ellenállás értéke 200 Ohm. Tehát a gomb megnyomásakor a PA0 portot +5 voltos tápfeszültségre kötjük, és ha lekérdezzük a PA0 lábról feszültség meglétét vagy hiányát, akkor befolyásolhatjuk programunk végrehajtását.

Az alábbiakban képernyőképeket adtam a programunk szövegéhez:


Tehát a különbség az előző projekthez képest az, hogy az RA port mind a 8 lábát bemenetként konfiguráljuk, a PB0 - PB3 port érintkezőit kimenetként és a PB4 - PB7 csatlakozót bemenetként konfiguráljuk.


Ezután állapottesztet használunk a programunkban " ha"


Tehát az „if” utáni sorban, zárójelben a végrehajtási feltételt látjuk. Az alábbi kód akkor fut le, ha a PA0 porton logikai nulla vagy nulla volt. Ez a zárójelben lévő szöveg a port biteltolása. A következő cikkek egyikében elemezzük, de egyelőre elég, ha azt hisszük, hogy ezzel lenyomjuk a gombot fekvőtámasz. Ezután kapcsos zárójelben megjelenik a program szövege, amely végrehajtódik, ha a feltétel igaz. Ha a feltétel nem igaz, a program folytatja a végrehajtást, kihagyva a kapcsos zárójelben lévő szöveget.

Hasonlóképpen, a „ha” feltételt használva a gombot bekapcsoljuk megnyomva. Felhívjuk figyelmét, hogy a zárójelben lévő szöveg megváltozott. Ez azt jelenti, hogy ha van logikai egységünk a PA0 lábon, akkor teljesítjük a feltételt, vagyis a zárójelben lévő szöveget. Vagyis a gomb megnyomásakor az elsőtől a negyedikig egyenként kigyulladnak és kialszanak a LED-ek, lenyomva és nyomva tartva pedig a negyediktől az elsőig világítanak és kialszanak a LED-ek. Így befolyásolhatjuk a program végrehajtását egy gomb megnyomásával, lekérdezve, hogy van-e rajta logikai nulla vagy logikai egy

Továbbá, amely tartalmazza a „Sishnik”, a HEX és a Proteus fájlt.

És itt a videó

Óra módszerek

Az MK órajelének kanonikus módja egy kvarc rezonátor csatlakoztatása a megfelelő érintkezőkhöz (18.11. ábra, a). A C1 és C2 kondenzátorok kapacitása tipikus esetben 22-36 pF legyen (a kvarc beépítését lásd a 15. fejezetben). A legtöbb Tiny és Mega modell speciális konfigurációs bittel rendelkezik, amely lehetővé teszi a fogyasztás szabályozását. Ha ez a bit egyre van állítva (programozatlan), az oszcillációs amplitúdó lecsökken, azonban a lehetséges frekvenciatartomány és az általános zajtűrés beszűkül, ezért ennek az üzemmódnak a használata nem javasolt (lásd alább). Alacsony frekvenciájú kvarc rezonátor is használható (például 32 768 Hz-es „órajel”), míg a C1 és C2 kondenzátorokat nem kell beszerelni, mivel a lejtés O értékre állításakor a belső 36 pF-os kondenzátorok is tartalmazzák. az MC-ben vannak csatlakoztatva.

Kvarc helyett kerámia rezonátor is használható. E sorok írója az MK-t nem szabványos frekvencián tudta futtatni, ugyanabban a kapcsolódásban kvarc helyett miniatűr induktivitást használva (4,7 μH értékével és 91 pF kondenzátorkapacitásával a frekvencia körülbelül 10 MHz).

Rizs. 18.11. Az AVR mikrokontroller órajelének módszerei: a - kvarc rezonátor; b - külső generátor; c - RC láncok

Az MK természetesen külső generátorról is órajelezhető (18.11. ábra, b). Ez különösen akkor kényelmes, ha az MK-t külső komponensekkel kell szinkronizálni, vagy megfelelő generátorok (például az Epson SG-8002 sorozata) használatakor nagyon pontos órajel-frekvenciára van szükség.

Ellenkezőleg, ha nincs szükség a pontosságra, használhat külső LAN-láncot (18.11. ábra, c). Ebben az áramkörben a C1 kapacitásnak legalább 22 pF-nak kell lennie, és az R1 ellenállást a 3,3-100 ohm tartományból kell kiválasztani. Ebben az esetben a frekvenciát az F = 2/3 RC képlet határozza meg, a CI egyáltalán nem állítható be, ha logikai nullát ír az SCR konfigurációs cellába, és ezzel egy belső 36 pF-os kondenzátort csatlakoztat.

Végül pedig teljesen nélkülözheti a külső komponenseket - használja a beépített IG generátort, amely négy frekvencián tud működni, körülbelül 1, 2, 4 és 8 MHz-en. Ez a funkció a legalacsonyabb kategóriás modokban használható legjobban (1x Tiny, 8 tűs kiszerelésben kapható - ekkor a rezonátor vagy külső oszcillátor csatlakoztatására szolgáló érintkezők más célokra is használhatók, például normál I/O portokhoz. Klasszikus család beépített RC oszcillátor nem volt.

Alapértelmezés szerint a Tiny és Mega családok MK-i úgy vannak beállítva, hogy a beépített oszcillátorral 1 MHz-es frekvencián működjenek (cksel = oooi), így a többi üzemmódban való működéshez ennek megfelelően kell beállítani a cksel konfigurációs cellákat (lásd a táblázatot). 18.1). Ennek gyakorlati végrehajtásáról a 19. fejezetben lesz szó. Ezeknek a celláknak az ajánlott értéke a hagyományos 1 MHz-es és nagyobb rezonátorokhoz a cksel cellákban egy, az sk-ban pedig nulla.

Részletek

A cellák beépítésénél figyelembe kell venni, hogy a cksel = oooo állapot (a kvarcrezonátornál leggyakrabban használt értékhez képest tükör iiii) az MK-t külső oszcillátorról óra üzemmódba kapcsolja, és ebben az állapotban nem is tud. külső frekvencia alkalmazása nélkül programozható. Illetve ha alacsony frekvenciájú rezonátorral próbálod beállítani az üzemmódot, akkor a nagyfrekvenciás MC már nem indul el, és nem minden programozó tud ilyen alacsony órajelen dolgozni. Ezért a cellák, és nem csak a cksel manipulálásakor rendkívül óvatosnak kell lennie, és jó ötletnek kell lennie arról, hogy pontosan mit is telepít. Erről részletesebben a következő fejezetben lesz szó.

18.1. táblázat. A CKSEL konfigurációs cellák beállítása az óramódoktól függően

Óra forrása

Külső frekvencia

Beépített /?C-generátor

Beépített RC oszcillátor

Beépített /?C-generátor

Beépített RC oszcillátor

Külső RC lánc

Külső /?C-lánc

Külső RC lánc

Külső RC lánc

Alacsony frekvenciájú rezonátor

16.1. táblázat (vége)

Óra forrása

Kerámia rezonátor

Kerámia rezonátor

kvarc rezonátor

Kvarc rezonátor

Párhuzamos I/O portok

Az I/O portok (ismételjük, hogy nem szabad összetéveszteni sem az MK I/O-regisztereivel, sem soros portjaival a külső eszközökkel történő információcseréhez) a különböző modellekben 1-től 7-ig terjedhetnek. A portok névlegesen 8 bitesek, bizonyos esetekben A bit kapacitását a csomag tűinek száma korlátozza, és kevesebb lehet nyolcnál. A portokat A, B, C, D stb. betűk jelölik, és nem feltétlenül sorrendben: az alacsonyabb modellekben például csak B és D portok lehetnek (mint az ATtiny2313-ban), vagy általában csak egy port B (mint az ATtinylx-ben).

A tokban lévő érintkezők számának csökkentése érdekében az esetek túlnyomó többségében a portoknak megfelelő külső érintkezők fő funkciójukon (kétirányú bemenet/kimenet) mellett további egy-egy kiegészítővel is rendelkeznek. Vegye figyelembe, hogy a Reset láb kivételével, ha alternatív módban tud működni, nincs szükség speciális port érintkező váltásra. Ha például inicializálunk egy UART soros portot a programunkban, akkor a megfelelő port lábak (például az ATmega8335-ben ezek a PDO és PD1 port lábak) egy alternatív funkcióban, UART bemenetként és kimenetként működnek. A csapok ilyen speciális használata közötti időközönként azonban elvileg használhatók közönséges kétirányú csapként. A gyakorlatban áramkör-tervezési intézkedések alkalmazása szükséges a funkciók egymástól való elkülönítésére, ezért nem ajánlott visszaélni ezzel a funkcióval.

A portok kellően önállóak, üzemmódjuk egymástól függetlenül állítható. Alapértelmezés szerint a tápfeszültség bekapcsolásakor az összes további eszköz le van tiltva, és a portok bemenetként működnek, és nagy sebességgel (azaz nagy bemeneti impedanciával) a harmadik állapotban vannak. A kimenethez speciális utasítások szükségesek, amelyekhez a programban be kell állítani a kívánt kimenetnek megfelelő bitet az adatirány-regiszterben (ezt a regisztert DDRx-nek nevezzük, ahol x egy adott portot jelölő betű, pl. Az A port ddra lesz). Ha a bit nullázva van (vagyis egyenlő a logikai nullával), akkor a kimenet bemenetként működik (alapértelmezés szerint); ha be van állítva (vagyis egyenlő egy logikaival), akkor kimenetként működik.

A kimenet egy állapotba állításához külön be kell állítani a megfelelő bitet a port adatregiszterben (a portx-szel jelölve), és az O-ra állításhoz ezt a bitet alaphelyzetbe kell állítani. Nem szabad összetéveszteni a kimenet működési irányát (input-output, DDRx regiszter) és állapotát (O-1, portx).

A portx adatregiszter valójában csak egy kimeneti puffer; bármit írunk bele, az azonnal kimenetre kerül. De ha beállítod a port pin-jét a bemenetre (vagyis logikai nullát írsz a ddrx irányregiszterbe), ahogy az alapértelmezés szerint történik, akkor a portx adatregiszter kicsit más szerepet fog játszani - a bitjeit nullára állítani azt jelenti, hogy a bemenet nagy ellenállású harmadik állapotban van, és egyre állítva egy 35-120 kOhm ellenállású „felhúzó” ellenállást kötünk a terminálra.

Megjegyzések a margókon

A legtöbb esetben a beépített felhúzó ellenállás nem elegendő a megbízható működéshez - az interferencia miatt az MC meghibásodhat, és jobb, ha ezzel a belsővel párhuzamosan egy további külső ellenállást telepítünk, amelynek ellenállása 1 5 kOhm-ra (fogyasztás szempontjából kritikus esetekben értéke 20-30 kOhm-ra növelhető). Például, ha a bemenetre egy külső gombot csatlakoztat két érintkezővel, amely földre van kapcsolva, vagy a láb a távoli eszközökkel „közös buszon” működik (egy másik kártyán van), vagy a láb egy külső megszakítás (lásd alább), akkor ilyen kiegészítő ellenállást kell csatlakoztatni.

A bemeneti állapotban lévő port érintkezőjének szintjének leolvasásának eljárása nem teljesen triviális. Nagy a kísértés, hogy adatokat olvassunk ki a portx adatregiszterből, de ezzel nem lesz semmi – csak azt fogja olvasni, amit korábban oda írt. És a bemeneten (közvetlenül a mikroáramkör kimenetén) ténylegesen elérhető olvasáshoz egy másik lehetőség is biztosított. Ehhez el kell érni valamilyen tömböt, amelyet pinx jelöl. A hozzáférés ugyanúgy történik, mint a hagyományos RVV-k egyes bitjei (lásd a 19. fejezetet\, de a pinx nem regiszter, egyszerűen csak egy bizonyos címtartomány, amelynek olvasása hozzáférést biztosít a port bemenetén lévő pufferelemekből származó információkhoz. Írjon valamit a piNx címekre, természetesen nem lehetséges.

Megszakítja

A PC-khez hasonlóan a mikrokontrollerekben is kétféle megszakítás létezik. De ha egy PC-ben a megszakításokat hardverre (például időzítőből vagy billentyűzetből) és szoftverre osztják (valójában nem megszakításokra, hanem a BIOS-ba írt szubrutinokra - a Windows elterjedésével ez a fogalom szinte eltűnt a programozói gyakorlatból), akkor az MK-ban természetesen minden megszakítás hardver, és belsőre és külsőre vannak osztva. Bármilyen megszakítás külön-külön, valamint előfordulásuk lehetősége általában előzetes külön engedélyt igényel.

Határozottan meg kell érteni, hogy bármilyen megszakítás inicializálásához négy dolgot kell tennie a programban: általában engedélyezni kell a megszakításokat (alapértelmezés szerint le vannak tiltva), majd engedélyezni kell ezt a megszakítást, beállítani az egyik elérhető módot, és végül , állítsa be a megszakítási vektort: ​​pointer to label -re, amely mentén a megszakításkezelő szubrutin eljárás található. És természetesen ezek után meg kell írni magát a kezelőt, különben mindez hiába történik. Erről részletesebben a 19. fejezetben lesz szó.

Belső megszakítások származhatnak bármely olyan eszközből, amely a rendszermagon kívül van - időzítőkből, analóg komparátorból, soros portból stb. A belső megszakítás olyan esemény, amely a rendszerben történik, és megszakítja a fő program végrehajtását. Az AVR belső megszakítási rendszere meglehetősen kiterjedt, és az eszközök és a rendszermag közötti interakció fő rendszerét jelenti, és erre a kérdésre még többször visszatérünk.

Az AVR MK-nak legalább két külső megszakítása van, INTO, INT1 (a legtöbb Megában van egy harmadik - ICHT2). A külső megszakítás olyan esemény, amely akkor következik be, amikor a kifejezetten erre a célra kialakított bemenetek valamelyikén jel jelenik meg. Háromféle esemény okoz megszakítást, és ezek szoftveresen állíthatók be: ez lehet egy alacsony feszültségszint, vagy egy pozitív vagy negatív él a megfelelő érintkezőn. Érdekes módon az összes ilyen esemény megszakítása akkor is végrehajtódik, ha a megfelelő port érintkezője kimenetként van konfigurálva.

Nézzük meg röviden ezen módok használatának jellemzőit. Alacsony szintű megszakítás (a mód alapértelmezés szerint be van állítva, inicializálásához csak engedélyezze a megfelelő megszakítást) akkor fordul elő, amikor a megfelelő bemenet alacsony. A „minden alkalommal” azt jelenti, hogy valóban minden alkalommal, vagyis ha egy negatív impulzus egy ideig tart, akkor a megszakítás-feldolgozási eljárás, miután véget ért, újra és újra megismétlődik, megakadályozva a főprogram működését. Ezért ennek a külső megszakítási módnak a használatának szokásos sémája az, hogy előfordulásakor azonnal letiltják (a feldolgozási folyamat, ha egyszer elindult, egyszer befejeződik), és csak akkor engedélyezi újra, ha a külső hatásnak már véget kellett vetnie (például ha egy gombnyomásról van szó, majd egy-két másodperc múlva az időzítőnek újra engedélyeznie kell).

Ezzel szemben a növekvő vagy csökkenő megszakítások egyszer végrehajtásra kerülnek. Természetesen nincs és nem is lehet védelem az érintkezés visszapattanása ellen, mert az MK nem képes megkülönböztetni a visszapattanást a rövid impulzusok sorozatától. Ha ez kritikus, akkor vagy külső intézkedéseket kell tennie a visszapattanás elleni védelem érdekében, vagy ugyanazt a módszert kell alkalmaznia, mint a szintmegszakításnál - a megszakításkezelő eljáráson belül magát a megszakítást kell letiltani az első paranccsal, majd egy idő után egy másik eljárásban ( időzítővel vagy más esemény által), hogy újra megoldja (a „visszapattanás elleni” módszer valójában megegyezik az egyszeri eszköz használatával, lásd a 15. fejezetet).

Részletek

A figyelmes olvasónak jogos a kérdése - miért van egyáltalán szükségünk külső szintű megszakítási módra? Az a tény, hogy minden modellben aszinkron módon hajtják végre - abban a pillanatban, amikor alacsony szint jelenik meg az MK kimeneten. Természetesen a megszakítás észlelése csak az aktuális utasítás végén történhet, így nagyon rövid impulzusok elveszhetnek. De az INTO és INT1 megszakítások az élvezérlési módban a legtöbb modellnél fordítva vannak meghatározva, csak szinkronban - a vezérlő órajelének szintkülönbség pillanatában, tehát időtartamuk nem lehet rövidebb egy órajel periódusnál. . De nem ez a legfontosabb: összességében nem lenne különbség ezekben a módokban, ha nem az a tény, hogy a szinkron mód minden bizonnyal éppen ennek az órajelnek a meglétét igényli. Ezért egy aszinkron külső megszakítás ennek megfelelően „felébresztheti” az egyik mélyenergia-takarékos üzemmódban lévő vezérlőt, amikor az órajelgenerátor nem működik, de a szinkron nem. A közönséges MCU-kat pedig, mint például a Classic család AT90S8515-je (de nem a megaanalógja!), csak külső szintű megszakítással lehet felébreszteni a mély „alvásból”, ami nem mindig kényelmes a használata. A Meda család legtöbb modellje (a fiatalabb modellek közül - az ATmegaS kivételével) rendelkezik egy másik megszakítással, az INT2-vel, amely csak a széleken fordul elő (szintenként nem), de az INTO-tól és az INT1-től eltérően aszinkron módon. Az ATtiny2313-ban (de nem a „klasszikus” analógjában!) ilyen aszinkron megszakítás előfordulhat a B port 8 érintkezőjének bármelyikéből érkező jel hatására. Ez jelentősen megnöveli a vezérlő használhatóságát energiatakarékos módban.

Időzítők-számlálók

A legtöbb AVR MK két vagy három időzítő számlálóval rendelkezik, amelyek közül az egyik 16 bites, a többi 8 bites (a régebbi Mega modellekben a számlálók száma összesen legfeljebb 6 lehet). Minden számláló képes előtölteni értékeket, és közvetlenül a processzor órajel-frekvenciájáról (SC) vagy abból 8, 64, 256 vagy 1024 (egyes esetekben 16 és 32) osztva, valamint egy külső jel. Általánosságban elmondható, hogy az MK-ban az időzítők kialakítása, mint mondtuk, hasonló az 561HEU/14 számlálókhoz (lásd a 15. fejezetet), csak a funkcionalitásuk jelentősen bővül.

Az AVR architektúrában a 8 bites számláló időzítőkhöz O és 2, a 16 bitesekhez pedig 1, 3 és így tovább. Egyes 8 bites számlálók (általában a 2. időzítő, ha kettő van belőlük) aszinkron üzemmódban működhetnek egy külön órajelgenerátorról, és akkor is működnek, ha az MCU többi része „alvó” állapotban van, ami lehetővé teszi számukra. valós idejű óraként használható.

Ha az időzítőket a külső impulzusok szokásos számlálójaként használjuk (és az impulzus esésénél és szélén is lehetséges a reakció), a számlált impulzusok frekvenciája nem haladhatja meg az MK órajelgenerátor frekvenciájának felét (és egy aszimmetrikus külső meander, az utasítások a határfrekvencia még alacsonyabb értékét javasolják - 0,4 az órajeltől). Ez annak a ténynek köszönhető, hogy a külső impulzusok számlálása során azok éleit szinkronban (az órajel pozitív élének pillanataiban) érzékeli. Ezenkívül érdemes figyelembe venni, hogy a számlálótartalom frissítésének késleltetése a külső impulzus megérkezése után akár 2,5 órajel periódus is lehet.

Ezek meglehetősen erős korlátok, ezért például egy MK-t univerzális frekvenciamérőként használni nem túl kényelmes - jobb, ha nagy sebességű áramköröket tervezünk megfelelő kombinációs logikával vagy FPGA-kkal (programozható logikai integrált áramkörök).

Számláló túlcsordulás esetén olyan esemény következik be, amely megfelelő megszakítást válthat ki. A 8 bites Timer O számlálót ez a funkció bizonyos esetekben korlátozza. A 2. időzítő, ha van, megszakítást is kiválthat, ha a számlált érték egyezik valamilyen előre meghatározott értékkel. A 16 bites számlálók „fejlettebbek” és megszakításokat okozhatnak, ha két egymástól függetlenül meghatározott A és B számmal esnek egybe. Ebben az esetben a számlálók nullázhatók, vagy folytatható a számlálás, és speciális lábakon impulzusok generálhatók (pl. hardver, program részvétel nélkül).

Ezen túlmenően, a 16 bites számlálók képesek „elfogni” a külső egyedi impulzusokat egy speciális tűn. Ebben az esetben egy megszakítás hívható, és a számláló tartalma egy bizonyos regiszterbe kerül. Maga a számláló nullázható, és újrakezdhető a számlálás, vagy egyszerűen folytathatja a számlálást. Ez a mód kényelmesen használható külső jel periódusának mérésére vagy bizonyos szabálytalan események (például részecskék áthaladása a Geiger-számlálóban) számlálására. Fontos, hogy az ilyen események forrása egy beépített analóg komparátor is lehet, amelyet ezután impulzusformálóként használnak.

Minden számláló időzítő működhet az ún. PWM módok, azaz 8-, 9-, 10- vagy 16-bites impulzusszélesség-modulátorként (PWM), és egymástól függetlenül, ami lehetővé teszi a többcsatornás PWM megvalósítását. A műszaki dokumentációban sok oldalt szentelnek ezeknek a módoknak, bonyolultságuk, sokoldalúságuk és nehézkességük miatt. Ezeknek a módoknak a legegyszerűbb hanglejátszási lehetőségét a 22. fejezetben tárgyaljuk röviden a hangjelzéssel kapcsolatban. Ne feledje, hogy a hangszintézis nem az egyetlen, sőt nem is a legfontosabb célja a PWM módoknak, hanem teljesítmény vagy áram szabályozására (például akkumulátorok töltésekor), motorok vezérlésére, jelek egyenirányítására és digitális-analóg átalakításra is használhatók. .

Az időzítő számlálók mellett kivétel nélkül minden AVR vezérlő rendelkezik Watchdog időzítővel. Főleg az MK energiatakarékos üzemmódból való eltávolítására szolgál egy bizonyos időintervallum után, de használható az MK vészhelyzeti újraindítására is. Például, ha a program működése függ a külső jelek érkezésétől, akkor azok elvesztése esetén (pl. vonalszakadás miatt) az MK „lefagyhat”, és a Watchdog időzítő kihozza. ebből az állapotból.

Soros portok

A külső eszközökkel történő adatcserére szolgáló soros portok minden MK legfontosabb összetevője, nélkülük a külvilággal való „kommunikációja” élesen korlátozott. Szekvenciálisnak nevezik őket, mert egyszerre csak egy bit kerül továbbításra (bizonyos esetekben lehetséges az egyidejű adás és vétel, de egyszerre csak egy bit). A soros portok legfontosabb előnye a párhuzamos portokkal szemben (amikor egész bájtokat vagy tetrad nibble-eket cserélünk egyszerre) a kapcsolatok számának csökkenése. De nem ez az egyetlen: paradox módon a soros interfészek jelentős előnyt jelentenek a nagy sebességű párhuzamosak számára, amikor a vonalak késései kezdik befolyásolni az átviteli sebességet. Ez utóbbit nem lehet szigorúan azonossá tenni, és ez az egyik oka annak, hogy mostanra a soros interfészek kezdenek dominálni (tipikus példa erre a COM helyett az USB és a FireWire, az LPT és SCSI, vagy az IDE helyett a Serial ATA).

Az adatmennyiségünkkel rendelkező mikrokontrollereknél természetesen az átviteli sebesség másodlagosan érint minket, de a csatlakozó vezetékek száma nagyon kritikus tényező. Ezért minden külső eszköz, amellyel ebben a könyvben foglalkozunk, soros interfésszel rendelkezik.

Szinte minden soros port szimulálható szoftverben, hagyományos MK tűkkel. Valamikor ezt még a legnépszerűbb noptoB - UART - esetében is megtették. Azóta azonban az MK-k hardveres soros portokat szereztek be, ami azonban nem jelenti azok abszolút használatának szükségességét. További előnyt jelent a soros portok szoftveres szimulációjának egyszerűsége.

Az AVR MCU-ban esetlegesen előforduló portok közül különös figyelmet fordítunk az UART-Universal Asynchronous Receiver-Transmitterre, az „univerzális aszinkron adó-vevőre”. Az UART minden olyan eszköz fő része, amely támogatja az RS-232 protokollt, de nem csak az (nem hiába "univerzális") - például az RS-485 és RS-422 ipari szabványok is UART-on keresztül valósulnak meg. , mivel az RS-232-től csak az elektromos paraméterek és a megengedett sebességek különböznek, és nem az általános felépítési logika. A személyi számítógépek COM porttal rendelkeznek, amely ugyanazt az RS-232 protokollt használja, és az UART csomópont is ennek az alapvető része.

Ezért az UART az MK és a számítógép közötti adatcsere fő módja. Megjegyzendő, hogy a legtöbb modern PC-modellben nem akadály a COM-port hiánya: ehhez vannak USB-COM-adapterek, az asztali modellbe pedig egy további kártya COM-portokkal is behelyezhető.

Megjegyzések a margókon

Miért olyan fontos ez nekünk? A helyzet az, hogy az eszköz elrendezést számítógéphez csatlakoztatva, még ha az adatcserét nem is biztosítja az eszköz funkcionalitása, sokkal könnyebb a program hibakeresése, egyszerűen csak ideiglenesen beillesztjük a program megfelelő helyeire a küldés műveletét. az érintett regiszterek értékeit a PC-re és valós időben fogadja valamilyen - vagy terminál emulátor programmal. Ez sokkal kényelmesebb, mint a terjedelmes AVR Stúdió elsajátítása, és még egy drága hibakereső táblával is együtt jár. Ezért azt tanácsolom, hogy azonnal készítsen magának egy programozó csatlakozót (lásd a következő fejezetet) tartalmazó hibakereső kártyát és egy UART/RS-232 szintátalakítót nullmodem kábel csatlakoztatására szolgáló csatlakozóval (lásd 21. fejezet).

Az UART gyakorlati használatáról a 21. fejezetben olvashat. Az UART mellett szinte minden AVR MCU tartalmazza a legegyszerűbb soros portot - SPI-t (Serial Peripheral Interface). Az SPI-eszköz elvét a 16. fejezetben említettük. Alapvető egyszerűsége részben rossz szerepet játszott: nehéz találni két olyan eszközt, ahol az SPI-protokollok teljesen megegyeznek, általában az ezen a porton keresztüli cserét kíséri egyik vagy másik „ harangok és sípok". Meg kell jegyezni, hogy az AVR programozása is SPI-n keresztül történik, azonban általában ez az interfész és az adatcserére szolgáló SPI különböző dolgok, bár a legtöbb esetben ugyanazok a tűk.

De ebben a könyvben, a 21. fejezetben megvizsgáljuk a bonyolultabb, bár lassabb I^C interfészt, amelyre gyakrabban van szükség, mivel oly sok periféria dolgozik rajta.

A konkrét áramkörök bemutatásakor figyelembe vesszük az AVR család MK-jának néhány más alkatrészét (például ADC-ket) - ez egyértelműbb lesz. Itt befejezzük a mikrokontrollerrel kapcsolatos hosszas bemutatkozásunkat, és továbbtérünk a programozás kérdésére.

Ma megpróbálunk egy egyszerűbb mikrokontrollert használni ATtiny2313és csatlakoztasson hozzá egy karakteres LCD kijelzőt, amely két 16 karakteres sort tartalmaz.

A kijelzőt a szabványos 4 bites módon fogjuk csatlakoztatni.

Először is kezdjük természetesen a mikrokontrollerrel, hiszen a kijelzőt már nagyon jól ismerjük az előző leckékből.

Nyissuk meg a vezérlő adatlapot ATtiny2313és lássuk a kivezetését

Azt látjuk, hogy ez a vezérlő kétféle esetben létezik, de mivel DIP-csomagban kaptam, ezért ezt a házváltozatot fogjuk figyelembe venni, és elvileg nem sokban térnek el egymástól, kivéve a megjelenést, tehát hogyan a szám a lábak azonosak - egyenként 20.

Mivel az ATMega8 vezérlő 28 lábához képest 20 láb van, amin mindvégig dolgoztunk és a továbbiakban is fogunk dolgozni, így ennek megfelelően a lehetőség is kevesebb lesz.

Elvileg itt van minden, ami az ATmega8-ban volt, csak az a baj, hogy kevesebb a porta köröm. De mivel az előttünk álló feladat az, hogy az SPI buszon keresztül próbáljuk meg összekapcsolni egy másik vezérlővel, ez nem nagyon nyomaszt bennünket.

Vannak más eltérések is, de ezek csekélyek, és szükség szerint megismerjük őket.

Állítsunk össze egy ilyen áramkört (a képre kattintva a kép nagyítható)

A kijelző a D port érintkezőihez csatlakozik. A PD1 és PD2 a vezérlő bemenetekhez, a többi pedig a D4-D7 kijelző modul érintkezőihez csatlakozik.

Hozzunk létre egy projektet TINY2313_LCD néven, vigyünk át bele mindent, kivéve a projekt fő modulját, amely a kijelzőt Atmega8-hoz köti.

Természetesen néhány dolgot át kell alakítani. Ehhez alaposan meg kell tanulmányoznia, hogy melyik láb melyikhez kapcsolódik. A kijelző E busza a PD2-re, az RS busz pedig a PD1-re csatlakozik, így módosítsuk a fájlt lcd.h

#definee1PORTD|=0b0000 01 00 // állítsa az E sort 1-re

#definee0PORTD&=0b1111 10 11 // állítsa az E sort 0-ra

#definers1PORTD|=0b00000 01 0 // az RS sort 1-re állítja (adatok)

#definers0PORTD&=0b11111 10 1 // az RS sort állítsa 0-ra (parancs)

Ahogy a félkövér betűtípusból is látszik, ilyen drasztikus változások még nem történtek.

Most információbevitel. Itt a PD3-PD6 lábakat használjuk, azaz 1 ponttal eltolódnak az Atmega8-hoz képest, tehát valamit javítunk is a fájlban lcd.c funkcióban Sendhalfbyte

PORTD&=0b 1 0000 111; // törli az információkat a DB4-DB7 bemenetekről, a többit hagyja békén

De ez még nem minden. Korábban 4-gyel eltoltuk a továbbított adatokat, de most a fenti változtatások miatt csak 3-mal kell eltolni. Ezért ugyanabban a függvényben a legelső sort is javítjuk

c<<=3 ;

Ennyi a változás. Egyetértek, nem olyan nagyszerűek! Ezt úgy érjük el, hogy mindig igyekszünk univerzális kódot írni, és makróhelyettesítéseket alkalmazunk. Ha nem fordítottunk volna erre egyszerre időt, akkor könyvtárunk szinte minden funkciójában ki kellett volna javítanunk a kódot.

A fő modulban nem érintjük a D port inicializálását, hagyjuk, hogy az egész modul kimeneti állapotba kerüljön, mint a 12. leckében.

Próbáljuk meg összerakni a projektet, és először a Proteusban lássuk az eredményt, mivel én is készítettem hozzá egy projektet, ami szintén a mellékelt archívumban lesz az Atmel Studio projektjével

Nálunk minden remekül működik! Így készíthet gyorsan egy projektet az egyik vezérlőhöz a másikhoz.

A Proteus nagyon jó, de mindig jobb a valódi részleteket nézni. Az egész áramkört egy kenyérlapra szerelték össze, mivel ehhez a vezérlőhöz nem készítettem és nem állítottam össze hibakereső kártyát. A programozót egy ilyen szabványos csatlakozón keresztül csatlakoztatjuk

Itt a teljes diagram

Itt minden szabvány. Felhúzó ellenállás RESET-hez stb.

Most, mielőtt a vezérlőt avrdude-ban villogtatnánk, ki kell választanunk a vezérlőt és be kell olvasnunk a flash memóriáját

Ezután lépjen a BIZTOSÍTÉKOK fülre, és állítsa be megfelelően a biztosítékokat. Mivel nincs kvarc rezonátorunk, a biztosítékokat így szereljük be

LED csatlakoztatása egy I/O port vonalhoz

Ennek az anyagnak a tanulmányozása után, amelyben mindent részletesen leírnak számos példával, könnyedén elsajátíthatja és programozhatja az AVR mikrokontrollerek bemeneti / kimeneti portjait.

  • 2. rész A LED csatlakoztatása az I/O port vonalához
  • 3. rész A tranzisztor csatlakoztatása az I/O port vonalához
Nézzünk egy példát egy mikrokontrollerre ATMega8 .

Megírjuk a programot Atmel Studio 6.0 .

Emulálni fogjuk az áramkört Proteus 7 Professional .

A mikrokontrollerek tanulmányozásának első példája a LED csatlakoztatása és vezérlése; ez a legegyszerűbb és legkézenfekvőbb példa. Ez a példa klasszikussá vált a mikrokontrollerek tanulmányozásában, mint például a „Hello World!” program. más programozási nyelvek tanulása során.
Az egyes I/O portokon áthaladó maximális áramerősség 40 mA.
Az egyes I/O portok maximális áramerőssége 20 mA.
Mielőtt terhelést csatlakoztatna az I/O port vonalaihoz, beleértve a LED-et is, tudnia kell, hogy az I/O port vonalán megengedett terhelés túllépésével a mikrokontroller elégetheti.
A mikrokontroller I/O portvonalain átfolyó áram korlátozásához ki kell számítania és csatlakoztatnia kell egy ellenállást.

ábra: LED kivezetés.

ábra: A LED anód csatlakoztatása a mikrokontrollerhez.

ábra: A LED katód csatlakoztatása a mikrokontrollerhez.

A bemeneti/kimeneti portok vonalaihoz csatlakoztatott áramkorlátozó ellenállás ellenállása LED csatlakoztatásakor a következő képlettel számítható ki:

Ahol:
- vs- tápfeszültség;
- Vsp- feszültségesés az I/O port vonalán;
- Vd- közvetlen feszültségesés a LED-en;
- ID- egyenáram a LED-en;
- Kn- LED megbízhatósági együttható;

Példa:
- tápfeszültség - 5V;
- közvetlen feszültségesés a LED-en 2B ;
10mA (Adatlapról LED-re átvéve);
- LED-es robotok megbízhatósági együtthatója 75% (Adatlapról LED-re átvéve);
- feszültségesés az I/O port vonalán - 0,5V (Az adatlapról a mikrokontrollerre átvéve: Vol (kimeneti alacsony feszültség) - ha áram folyik be, és Voh (kimeneti magas feszültség) - ha áram folyik ki);

Így az ellenállás értéke R = 166,66 Ohm, a legközelebbi nagyobb ellenállásérték kerül kiválasztásra.

Ha a LED előremenő feszültsége nem ismert, az ellenállás kiszámítható Ohm törvénye alapján.

Ahol:
- U- az áramkör egy szakaszára adott feszültség;
- én

Példa:
4,5V;
- az I/O port vonal névleges árama - 20mA.

Miután meghatározta az ellenállás értékét R, ki kell számítani a teljesítményt P, wattban mérve, amely hő formájában szabadul fel az ellenállásban, amikor áram folyik az áramkörben.

Ahol:
- U– feszültség az áramkör egy szakaszára;
- én- az I/O port vonal névleges árama.

Példa:
- feszültség az áramkör egy szakaszára - 4,5V;
- előremenő áram a LED-en - 20mA.

Az ellenálláshoz kiosztott teljesítmény kiszámítása után kiválasztjuk az ellenállás teljesítményének legközelebbi magasabb értékét. Ha az ellenállás teljesítményvesztesége nem elegendő, meghibásodhat.

- kis teljesítményű LED anód csatlakoztatása az I/O port vonalához:

#beleértve // Fő program int main(void) ( // A bemeneti/kimeneti portok konfigurálása DDRC = 0b11111111; // Konfigurálja a C port összes bitjét "Output" módra PORTC = 0b11111111; // A C port összes bitjének beállítása naplózásra "1" (A port kimeneti feszültsége egyenlő Vcc) // Örök hurok, míg (1) ( ) )

- kis teljesítményű LED katód csatlakoztatása az I/O port vonalához:

// Külső könyvtárak felvétele #include #beleértve // Fő program int main(void) ( // A bemeneti/kimeneti portok konfigurálása DDRC = 0b11111111; // A C port összes bitjének beállítása "Output" módra PORTC = 0b00000000; // A C port összes bitjének beállítása naplózásra "0" (A port kimenetén a feszültség egyenlő a GND-vel) // Örök hurok, míg (1) ( ) )

- kis teljesítményű, anóddal és katóddal ellátott LED csatlakoztatása az I/O port vonalához:

// Külső könyvtárak felvétele #include #beleértve // Fő program int main(void) ( // A bemeneti/kimeneti portok konfigurálása DDRD = 0b11111111; // A D port összes bitjének beállítása "Output" módra PORTD = 0b11111111; // A D port összes bitjének beállítása naplózásra "1" (A port kimenetén a feszültség egyenlő a Vcc-vel) DDRC = 0b11111111; //A C port összes bitjét állítsa „Output” módba PORTC = 0b00000000; //A C port összes bitjét állítsa logikai „0” értékre (A port kimenetén a feszültség egyenlő a GND-vel) / / Örök hurok, míg (1) ( ) )