Postup programování mikrokontrolérů avr. Rady pro začínající programátory mikrokontrolérů. Požadovaná sada programů

Takže jsme vyřešili práci jádra ohledně přechodů a adresování. Je čas obrátit naši pozornost k jiné oblasti – paměti.

Existují dva typy (EEPROM se nepočítá, protože je to obecně periferie, ale o tom později):

  • RAM - RAM
  • ROM - ROM, aka flash, aka programová paměť

Protože naše architektura je Harvard, operátor má své vlastní adresování a flash má své vlastní. V datovém listu můžete vidět strukturu adresování RAM.

Okamžitě věnujte pozornost adresám! RON a periferní registry, stejně jako RAM jsou umístěny ve stejném adresovém prostoru. Tito. adresy od 0000 do 001F obsazují naše registry, dále až do adresy 005F jsou I/O buňky - porty. Prostřednictvím portů se konfiguruje vše, co je na desce ovladače. A teprve potom z adresy 0060 přichází naše RAM, kterou můžeme použít k zamýšlenému účelu.

Navíc mějte na paměti, že I/O registry mají také své vlastní adresování - adresní prostor I/O registrů (od 00 do 3F), je vyznačen na levé straně obrázku. IO/Register Block Toto adresování funguje POUZE v instrukcích OUT a IN.To vede k zajímavé funkci.

K periferním registrům lze přistupovat dvěma různými způsoby:

  • Prostřednictvím příkazů IN/OUT na krátké adrese v prostoru adres I/O
  • Prostřednictvím skupiny příkazů LOAD/STORE na úplné adrese v adresním prostoru RAM

Příklad. Vezměme vstupní registr asynchronního transceiveru UDR, má adresu 0x0C (0x2C), adresa v obecném adresovém prostoru je uvedena v závorkách.

LDI R18,10; Do registru R18 jsme nahráli číslo 10. Stejně tak OUT UDR,R18 ; Odvozeno prvním způsobem, samotný kompilátor; Nahradí hodnotu 0x0C místo UDR STS 0x2C,R18 ; Vyvedli mě druhou cestou. Prostřednictvím příkazu Store; Přímým zadáním adresy.

Obě metody poskytují stejné výsledky. ALE! Ty, které fungují pomocí adresování ve vstupním/výstupním prostoru (OUT/IN), jsou o dva bajty kratší. Je to pochopitelné – nepotřebují ukládat dvoubajtovou adresu libovolné paměťové buňky a krátká adresa vstupně-výstupního prostoru se vejde do dvoubajtového kódu instrukce.

Pravda, je tu další vtip. Faktem je, že každým rokem se kamenů od AVR objevuje stále více a je v nich stále více masa. A každé praskání potřebuje své periferní I/O registry. A nyní jsme dospěli k závěru, že ATMega88 (která nahradila Mega8) má již tolik periferií, že se jeho I/O registry již nevejdou do limitu 3F adresního prostoru.

Jejda, dorazili. A to je místo, kde ti, kteří přecházejí ze starých kamenů na nové, začínají vyjadřovat zmatené výrazy - proč příkazy OUT/IN fungují na některých periferních registrech, ale ne na jiných?

A je to jednoduché - nebyla dostatečná bitová kapacita.

Ale jádro je jedno, to už nejde předělat. A zde si lidé z ATMELu počínali lstivě – zavedli tzv. paměťově mapované registry. Tito. všechny ty registry, které se nevešly do limitu 3F, jsou nyní dostupné pouze jedním způsobem - přes Load/Store.

To je ale vtip. Pokud otevřete nějaký m88def.inc, můžete vidět, které z I/O registrů jsou „správné“ a které jsou namapovány na paměť.

Bude tam něco takového:

; ***** DEFINICE I/O REGISTRACE ********************************************* ******** * ; POZNÁMKA: ; Definice označené "MEMORY MAPPED" jsou rozšířené I/O porty; a nelze je použít s instrukcemi IN/OUT .equ UDR0 = 0xc6 ; MEMORY MAPPED .equ UBRR0L = 0xc4 ; MEMORY MAPPED .equ UBRR0H = 0xc5 ; MEMORY MAPPED .equ UCSR0C = 0xc2 ; MEMORY MAPPED .equ UCSR0B = 0xc1 ; MEMORY MAPPED .equ UCSR0A = 0xc0 ; MAPOVANÁ PAMĚŤ bla bla bla a mnohem více.equ OSCCAL = 0x66 ; MEMORY MAPPED .equ PRR = 0x64 ; MEMORY MAPPED .equ CLKPR = 0x61 ; MEMORY MAPPED .equ WDTCSR = 0x60 ; MEMORY MAPPED .equ SREG = 0x3f ;<------ А тут пошли обычные.equ SPL = 0x3d .equ SPH = 0x3e .equ SPMCSR = 0x37 .equ MCUCR = 0x35 .equ MCUSR = 0x34 .equ SMCR = 0x33 .equ ACSR = 0x30

Tohle jsou koláče.

A v této oblasti chápete, že velké chlupaté varhany letí směrem ke křížové kompatibilitě kódu sestavy s cílem je těsně zakrýt. Ostatně jedna věc je opravit nejrůznější makro definice a definice, které popisují registry, a druhá věc je sedět a jako Popelka oddělovat správné porty od těch špatných.

Existuje však řešení. Makrojazyk! Nelíbí se vám systém příkazů? Vytvořte si vlastní s blackjackem a děvkami!
Postavme si vlastní tým UOUT, jako univerzální OUT

Podobně pro příkaz IN Obecně platí, že s takovými makry můžete VELMI značně diverzifikovat assembler a udělat z něj výkonný programovací jazyk, který dokáže roztrhat všechny druhy C a Pascal jako hadr.

No, o čem to mluvím... o RAM.

Takže jsme vyřešili oslovování. Nyní víte, kde hledat adresy paměti, kde začínají uživatelské buňky RAM – v datovém listu, sekce Memory Map. Ale tam pro odkaz vědět.

A v našem kódu RAM začíná direktivou.DSEG Pamatujete si naši šablonu?

Zahrnout "m16def.inc" ; Používáme ATMega16 ;= Start macro.inc =============================== ; Makra zde;= Konec macro.inc ================================== ; RAM ==================================================== ============ .DSEG ; segment RAM; FLASH =================================================== ========== .CSEG ; Segment kódu; EEPROM =================================================== ======== .ESEG ; Segment EEPROM

Po .DSEG můžeme nastavit naše proměnné. A tady máme prostě výbuch buněk – obsadit kteroukoli. Zadejte adresu a buďte šťastní. Ale proč počítat adresy ručně? Tady ať přemýšlí kompilátor.

Proto vezmeme a nastavíme štítek

0x0060 ## ;Proměnné 0x0061 ## 0x0062 ## 0x0063 ## ;Proměnné2 0x0064 ## 0x0065 ## ;Proměnné4 by mohly začít zde

Jako ## libovolný bajt. Ve výchozím nastavení FF. O nějakém typování proměnných, prvotní inicializaci, kontrole přetečení a dalších buržoazních radostech se samozřejmě netřeba bavit. Tohle je Sparta! Tedy assembler. Vše ručně.
Pokud nakreslíme analogii s C, pak je to jako pracovat s pamětí pouze pomocí prázdných ukazatelů. Sishniks pochopí. Pochopí a budou zděšeni. Protože tento svět je krutý a zrádný. Trochu jsem špatně vypočítal index a ztratil další data. A sakra, zachytíte tuto chybu, pokud se okamžitě nezobrazí.

Takže pozor, pozor a ještě jednou pozornost. Všechny operace s pamětí provádíme prostřednictvím trasování a nic se nezdaří ani nepřeteče.

V datovém segmentu funguje i direktiva .ORG, která funguje úplně stejně - přenáší adresy, v tomto případě značky, odsud na konec paměti. Jen jedna jemnost - ORG 0000 nám poskytne úplný začátek RAM, a to je R0 a další registry. A nula kilometru RAM s použitím Mega16 jako příkladu dá ORG 0x0060. A v jiných ovladačích je nějaká jiná hodnota. Je líné pokaždé procházet datasheet, takže existuje taková definice makra jako SRAM_START, která označuje začátek RAM pro konkrétní MK.

Pokud tedy chceme, aby začátek paměti RAM, řekněme 100 bajtů, zůstal pod nějakým odpadním bufferem, uděláme tento trik.

1 2 3 4 .DSEG .ORG SRAM_START+100 Proměnné: .byte 3

DSEG .ORG SRAM_START+100 Proměnné: .byte 3

Hotovo, vyčistili jsme nárazníkovou zónu od začátku do 100.

Dobře, vyřešili jsme adresování. Jak pracovat s paměťovými buňkami? A pro tyto účely existují dvě skupiny příkazů. LOAD a STORE jsou největší skupinou příkazů.

Faktem je, že s buňkou RAM nelze dělat nic jiného, ​​než do ní načíst bajt z RON, nebo z ní bajt uvolnit do RON.

Příkazy Store (ST**) se zapisují do paměti RAM a příkazy Load (LD**) se čtou.

Čtení jde do registru R16…R31 a adresa buňky se zadává buď přímo v příkazu. Zde je jednoduchý příklad. Existuje tříbajtová proměnná Variables, je třeba ji zvýšit o 1. To znamená. provést operaci Variables++

Proměnné DSEG: .byte 3 Proměnné2: .byte 1 .CSEG ; Proměnná je v paměti; nejprve ji musíte získat. LDS R16, Proměnné ; Přečtěte si první bajt Variables v R16 LDS R17, Variables+1 ; Přečtěte si druhý bajt Variables v R17 LDS R18, Variables+2 ; No, třetí bajt v R18; Nyní k tomu přidáme 1, protože AVR nemůže sčítat s konstantou, pouze; abyste odečetli, musíte zkreslit. Nezpůsobuje však žádné zvláštní problémy. SUBI R16,(-1); obecně je SUBI odčítání, ale -(- dává + SBCI R17,(-1) ; A zde se převod zohledňuje. Ale o tom později. SBCI R18,(-1) ; Matematika v assembleru je jiný příběh Proměnné STS, R16 ; Uložte vše tak, jak bylo. Proměnné STS+1,R17 Proměnné STS+2,R18

Nebo můžete použít jinou metodu. Nepřímý záznam přes indexový registr.

Proměnné DSEG: .byte 3 Proměnné2: .byte 1 .CSEG ; Vezměte adresu naší proměnné LDI YL,nízká(proměnné) LDI YH,vysoká(proměnné) ; Proměnná je v paměti; nejprve ji musíte získat. LD R16, Y+; Přečtěte si první bajt proměnných v R16 LD R17, Y+; Přečtěte si druhý bajt proměnných v R17 LD R18, Y+; No, třetí bajt v R18; Nyní k tomu přidáme 1, protože AVR nemůže sčítat s konstantou, pouze; abyste odečetli, musíte zkreslit. Nezpůsobuje však žádné zvláštní problémy. SUBI R16,(-1); ve skutečnosti je SUBI odčítání, ale -(- dává + SBCI R17,(-1) ; A zde je převod zohledněn. Ale o tom později. SBCI R18,(-1) ; Matematika v assembleru je jiný příběh ST -Y,R18 ; Necháme vše tak, jak bylo. ST -Y,R17 ; Ale v opačném pořadí ST -Y,R16

Zde se již používají operace s post-inkrementací a pre-decrement. V prvním nejprve přečteme, pak k adrese přidáme 1. Ve druhém nejprve odečteme od adresy 1 a poté uložíme.

Je vhodné použít takové inkrementální příkazy k iteraci přes pole v paměti nebo tabulkách.
A nechybí ani nepřímý relativní zápis/čtení LDD/STD a další možnosti pro všechny tři typy indexů (X,Y,Z). Obecně kouřte datasheet a příkazový systém.

Zásobník
Oh, zásobník je skvělá věc. Co na tom miluji, je to, že narušení zásobníku změní fungující program v úplný nepořádek. Operace se zásobníkem totiž vyžadují zvýšenou pozornost, protože když se někde zásobník rozbije a nemůžete ho hned sledovat, chytíte ho později... Obecně je to krása, ne gýč.

Proč tě miluji? No, pokud je C hloupé řemeslo, rychlé a efektivní, pak montáž je filigránským uměním. Jak maniaci jako Jim nýtují mistrovská díla z papíru a pouze z papíru, ačkoli by se zdálo, že si můžete koupit hotový prefabrikovaný model a lepidlo pro vlastní potěšení. Takže i zde – samotný proces je ohromující. Včetně starostí s laděním :))))

Takže o hromadě. co to je? A toto je oblast paměti. Funguje na principu zásobníku. Tito. Poslední odložil, vzal první.

Zásobník má ukazatel, který ukazuje na vrchol zásobníku. Za ukazatel zásobníku je zodpovědný speciální registr SP, respektive je to dvojice registrů SPL a SPH. Ale v mikrokontrolérech s malým množstvím RAM, například v Tini2313, je pouze SPL

Když se řadič spustí, obvykle první věc, kterou udělají, je inicializovat zásobník a do SP zapsat adresu jeho dna, odkud bude růst. Obvykle je to konec paměti RAM a roste směrem k začátku.

To se provádí takto, na samém začátku programu:

1 2 3 4 5 LDI R16,Nízký (RAMEND) OUT SPL,R16 LDI R16,Vysoký (RAMEND) OUT SPH,R16

LDI R16,Nízký (RAMEND) OUT SPL,R16 LDI R16,Vysoký (RAMEND) OUT SPH,R16

Kde RAMEND je definice makra udávající konec RAM v aktuálním MK.

To je vše, zásobník je připraven k použití. Data jsou do zásobníku vložena pomocí příkazu PUSH Rn a načtena prostřednictvím POP Rn.
Rn je kterékoli z RON.

Se zásobníkem fungují i ​​příkazy CALL, RCALL, ICALL, RET, RETI a volání přerušení, ale o tom později.

Pojďme si hrát s hromádkou, abychom pocítili, jak funguje, abychom pochopili, jak a kam se pohybuje.

Zadejte do studia následující kód:

CSEG; LDI kódový segment R16,Low(RAMEND) ; Inicializace zásobníku OUT SPL,R16 LDI R16,High(RAMEND) OUT SPH,R16 LDI R17,0 ; Hodnoty načítání LDI R18.1 LDI R19.2 LDI R20.3 LDI R21.4 LDI R22.5 LDI R23.6 LDI R24.7 LDI R25.8 LDI R26.9 PUSH R17 ; Hodnoty vložíme na zásobník PUSH R18 PUSH R19 PUSH R20 PUSH R21 PUSH R22 PUSH R23 PUSH R24 PUSH R25 PUSH R26 POP R0 ; Pop hodnoty ze zásobníku POP R1 POP R2 POP R3 POP R4 POP R5 POP R6 POP R7 POP R8 POP R9

Nyní spusťte studio krok za krokem a sledujte, jak se SP mění. Stack Ukazatel lze vidět ve studiu na stejném místě jako Program Counter.

Nejprve inicializujeme zásobník a načteme registry daty. Výsledkem bude následující obrázek:

Dále pomocí příkazu POP načteme data ze zásobníku. Vezměte prosím na vědomí, že nám nezáleží na tom, kam data v zásobníku uložíme a kam je nahrajeme. Hlavní věc je pořadí instalace! Vložíme to z vyšších registrů a dostaneme to do nižších. Tím se zvýší ukazatel zásobníku.

PUSH R16 PUSH R17 POP R16 POP R17

Například už jsem mluvil o omezení nižších RON - neumožňují zapsat číslo přímo do sebe. Pouze přes registry seniorské skupiny. To je ale nepohodlné!

Problém je vyřešen pomocí makra. Nazval jsem to LDIL - LDI low

MACRO LDIL PUSH R17; Uložme hodnotu jednoho z vyšších registrů do zásobníku. LDI R17,1; Načteme do něj naši okamžitou hodnotu MOV @0,R17; Přeneseme hodnotu do registru nízké skupiny. POP R17; Obnovme hodnotu nejvyššího registru ze zásobníku. .ENDM

Nyní můžete snadno použít náš domácí příkaz.

1 LDIL R0,18

Postupem času si soubor s makry osvojí takové domácí příkazy a práce se stává snadnou a příjemnou.

Chyby zásobníku
Zásobník roste směrem k datům a teď si představte, že máme v paměti proměnnou Stav a ta se nachází na adrese například 0x0450. Nebezpečně blízko vrcholu zásobníku. Proměnná ukládá například stav konečného automatu, na kterém závisí další logika programu. Řekněme, že pokud jsou 3, pak uděláme jednu věc, pokud jsou 4, pak něco jiného, ​​pokud je 5, pak něco jiného a tak dále až do 255 stavů. A podle logiky práce by po 3 mělo být 4re, ale ne 10

A pak tam byly 3. A pak, v jeden hrozný okamžik, se podmínky natolik shodovaly, že stack rostl a jeho vrchol dosáhl této proměnné, zadal tam hodnotu, řekněme 20, a pak se chrt propadl zpět. Klasickým příkladem přetečení zásobníku je ponechání mucků. A logika programu se kvůli tomu zcela zhroutila.

Nebo opačný příklad - zásobník byl posunut nahoru k proměnným, ale v tu chvíli se proměnné aktualizovaly a přepsaly data zásobníku. V důsledku toho bylo ze zásobníku odstraněno něco špatného (obvykle křivé zpáteční adresy) a program se zhroutil. Tato možnost je mimochodem mnohem neškodnější, protože... v tomto případě je zárubeň vidět okamžitě a nevyskočí NÁHLE po bůh ví jak dlouho.

Kromě toho se tato chyba může objevit a zmizet. Podle toho, jak program funguje a jak hluboko načítá zásobník. Takový průšvih je však častější, když píšete v C, kde nevidíte, jak aktivně práce se zásobníkem probíhá. Na ASMA je vše mnohem transparentnější. A tady to může nastat kvůli upřímně pokřivenému algoritmu.

Assembleři se často setkávají s dalšími chybami zásobníku. V první řadě zapomnětlivost. Něco jsem vložil a zapomněl to vyndat. Pokud byl problém v podprogramu nebo přerušení, pak je návratová adresa zkreslená (o tom trochu později), zásobník se odtrhne a program se okamžitě zhroutí. Nebo nepozornost – v jedné objednávce jsem data uložil a v jiné zase načetl. Jejda, obsah registrů byl vyměněn.

Abyste se takovým chybám vyhnuli, musíte za prvé sledovat zásobník a za druhé správně naplánovat umístění proměnných v paměti. Uchovávání nejkritičtějších oblastí a proměnných (jako jsou stavové stroje nebo příznaky programové logiky) mimo vrchol zásobníku, blíže k začátku paměti.

Někteří lidé si budou myslet, že mohou vzít zásobník a umístit ho ne na úplný konec paměti RAM, ale někam blíže, takže za ním zůstane kapsa pro důležitá data. To opravdu není dobrý nápad. Faktem je, že zásobník lze posunout jak dolů pomocí příkazu PUSH, tak nahoru pomocí příkazů POP. Druhý, i když se to stává mnohem méně často, protože... To je spíše hřích křivých rukou než těžkopádný algoritmus, ale také se to stává.
Ale hlavní věc je, že samotný zásobník je velmi důležitou strukturou. Na něm spočívá celý mechanismus podprogramů a funkcí. Takže porucha zásobníku je v každém případě nouzová.

Hromadné zvrácenosti
Moje oblíbené téma. =)))) Navzdory tomu, že se samotný ukazatel zásobníku vypočítává během příkazů PUSH a POP, nikdo nám nebrání jej vybrat z SP a použít jeho hodnoty k ručnímu výpočtu adresy dat ležících na zásobník. Nebo opravte data zásobníku, jak chceme.
Proč? No, můžete najít spoustu aplikací, pokud napnete mozek a začnete přemýšlet mimo krabici :))))

Navíc parametry jsou předávány přes zásobník v klasickém C a Pascalu na architektuře x86 a fungují lokální proměnné. Tito. Před voláním funkce se nejprve všechny proměnné vloží do zásobníku a poté, po volání funkce, se do zásobníku vloží bajty budoucích lokálních proměnných.

Potom pomocí SP jako referenčního bodu můžeme s těmito proměnnými zacházet, jak chceme. A když je zásobník uvolněn příkazem POP, jsou zničeny, čímž se uvolní paměť.

V AVR je všechno poněkud jiné (zřejmě kvůli malému množství paměti, kde nemůžete opravdu tlačit do zásobníku, ale je tam hodně RON), ale můžete také zkusit použít tento mechanismus.

Pravda, toto už připomíná neurochirurgii. Udělal jsem drobnou chybu a pacient je mrtvý.

Díky stacku a RAM si vystačíte s pouhými dvěma nebo třemi registry, bez velkého stresu z jejich nedostatku.

Flash paměť

Paměť EEPROM je malá, jen pár bajtů, a někdy je potřeba uložit spoustu dat, například zprávu pro mimozemšťany nebo tabulku sinus, abyste neztráceli čas jejím výpočtem. Nikdy nevíte, co je potřeba předem uložit do paměti. Data tedy mohou být uložena v paměti programu, ve stejných kilobajtech flash, jaké má ovladač na desce.

Zapíšeme si to, ale jak to můžeme získat? Chcete-li to provést, musíte tam nejprve něco vložit.
Přidejte tedy na konec programu v rámci segmentu .CSEG např. data popisek a za něj pomocí operátoru .db zadejte svá data.

Operátor DB znamená, že pro každou konstantu použijeme byte. Existují také operátory, které specifikují dvoubajtové konstanty DW (stejně jako DD a DQ).

1 údaje: .db 12,34,45,23

údaje: .db 12,34,45,23

Nyní datový štítek ukazuje na adresu prvního bajtu pole, zbývající bajty jsou umístěny podle offsetu, jednoduše přidáním jednoho k adrese.

Jednou jemností je, že kompilátor nahradí adresu značky a považuje ji za adresu skoku pro čítač programu. A ten, pokud si vzpomínáte, řeší dvoubajtová slova - koneckonců délka příkazu může být buď 2 nebo 4 byty.

A naše data jsou bajt po bajtu a při přístupu k nim je řadič také řeší bajt po bajtu. Adresa ve slovech je dvakrát menší než adresa v bajtech a s tím je třeba počítat při násobení adresy dvěma.

Pro načtení dat z programové paměti použijte příkaz ze skupiny Načíst programovou paměť

Například LPM Rn,Z

Do registru Rn zapíše číslo z buňky, na kterou ukazuje dvojice registrů Z. Připomínám, že Z jsou dva registry, R30 (ZL) a R31 (ZH). Dolní bajt adresy se zadává do R30 a horní bajt do R31.

V kódu to vypadá takto:

LDI ZL,low(data*2) ; Dolní bajt adresy zadáme do registrového páru Z LDI ZH,high(data*2) ; Vysoký bajt adresy zadáme do registrového páru Z; násobení dvěma je způsobeno tím, že adresa je uvedena v; ve dvoubajtových slovech, ale potřebujeme je v bytech. ; Proto násobíme dvěma; Po načtení adresy můžete načíst číslo z paměti LPM R16, Z; v registru R16 po tomto příkazu bude číslo 12, ; převzato z paměti programu. ; někde na konci programu, ale v datovém segmentu .CSEG: .db 12,34,45,23

Nyní, když jsme již obeznámeni s některými možnostmi a funkcemi mikrokontrolérů, přirozeně vyvstává logická otázka: co je potřeba k programování mikrokontrolérů? Jaké programy a zařízení jsou potřeba a kde je mohu získat?


Aby mikrokontrolér mohl řešit problémy a vykonávat určité funkce, musí být naprogramován, to znamená, že do něj musí být zapsán program nebo programový kód.

Struktura a pořadí psaní programu

Za prvé, než začnete psát jakýkoli program, nebo spíše programový kód, měli byste jasně pochopit, jaké funkce bude mikrokontrolér vykonávat. Proto musíte nejprve určit konečný cíl programu. Když je definován a zcela pochopen, je navržen algoritmus pro program. Algoritmus je posloupnost provádění příkazů. Použití algoritmů umožňuje jasněji strukturovat proces psaní kódu a při psaní složitých programů často umožňuje zkrátit čas strávený jejich vývojem a laděním.

Dalším krokem po kompilaci algoritmu je přímý zápis programového kódu. Programy pro mikrokontroléry jsou napsány v jazyce Si nebo assembler . Only Assembly je spíše sada instrukcí než programovací jazyk a je to nízkoúrovňový jazyk.


Programy budeme psát v C, což je jazyk vysoké úrovně. Programy v C se píší mnohem rychleji ve srovnání s podobnými programy v Assembly. Kromě toho jsou všechny složité programy napsány primárně v C.

Zde nebudeme porovnávat výhody a nevýhody psaní programů v Assembly a C. Postupem času, když jste získali určité zkušenosti s programováním MK, vyvodíte pro sebe užitečné závěry.

Samotný programový kód lze napsat v libovolném standardním textovém editoru, například v programu Poznámkový blok. V praxi však používají pohodlnější editory, o kterých bude řeč níže.

Kompilace programu

C kód, který jsme napsali, ještě není pro mikrokontrolér srozumitelný, protože MK rozumí příkazům pouze v binární (nebo hexadecimální) soustavě, což je množina nul a jedniček. Proto je potřeba kód C převést na nuly a jedničky. K tomuto účelu slouží speciální program, tzv kompilátor a samotný proces transformace kódu se nazývá kompilace.

Chcete-li flashovat firmware MK, zařízení tzv programátor. V závislosti na typu programátoru je jeho vstup připojen k portu COM nebo USB a jeho výstup je připojen k určitým pinům mikrokontroléru.


Existuje široký výběr programátorů a vývojových desek, ale my jsme docela spokojeni s tím nejjednodušším programátor, který v Číně nestojí více než 3 dolary.


Po flashnutí mikrokontroléru se program odladí a otestuje na reálném zařízení nebo, jak se také říká, na hardwaru.

Nyní si shrňme kroky programování mikrokontrolérů.


Při psaní jednoduchých programů se obejdete bez druhého bodu, tedy bez kreslení algoritmu na papír, stačí si ho nechat v hlavě.

Nutno podotknout, že před flashováním firmwaru MK se provádí i ladění a testování programu.

Požadovaná sada programů

Existuje mnoho užitečných a pohodlných programů pro programování MK. Jsou placené i bezplatné. Mezi nimi jsou tři hlavní:

1) Atmel Studio

2) CodeVisionAVR

3) WinAVR

Všechny tyto programy souvisí s IDE integrovaný D rozvoj E nvironment – ​​integrované vývojové prostředí. Můžete v nich psát kód, kompilovat a ladit.

Měli byste věnovat pozornost Code Vision AVR. Toto IDE usnadňuje a urychluje psaní kódu. Program je však placený.

V počáteční fázi programování je lepší psát všechny programy ručně, bez jakýchkoli zjednodušení. To vám pomůže rychle získat potřebné dovednosti a v budoucnu můžete dobře porozumět a upravit kódy napsané někým jiným tak, aby vyhovovaly vašim potřebám. Proto doporučuji používat Atmel Studio. Za prvé je naprosto zdarma a neustále se aktualizuje a za druhé jej vyvinula společnost vyrábějící mikrokontroléry, na kterých se naučíme programovat.

Ladění firmwaru a programů

Budeme flashovat mikrokontroléry pomocí doplňkového programu.

Pokud není k dispozici mikrokontrolér, lze jeho činnost emulovat pomocí programu. Velmi to zjednodušuje proces ladění programu, i když máte mikrokontrolér, takže jej nemusíte často předělávat, protože každý mikrokontrolér má konečný počet přepisů, i když toto číslo je poměrně velké.

Při flashování a ladění MK je vhodné umístit jej na prkénko, ale není to vůbec nutné. Proto se pro větší pohodlí hodí i prkénko. Je velký výběr prkének na krájení, ale doporučuji si vzít tu, která má co nejvíce děr. Jakmile začneme připojovat sedmisegmentové displeje, začnete oceňovat výhody větších prkének na krájení.

Dalším důležitým prvkem, který se nám bude hodit, je technická dokumentace k MK, tzv datový list. Obecně platí, že musíte stáhnout datový list pro mikrokontrolér ATmega8.

Kiselev Roman, květen 2007 Článek aktualizován 26. května 2014

Co je tedy mikrokontrolér (dále jen MK)? Jedná se, relativně vzato, o malý počítač umístěný v jediném integrovaném obvodu. Má procesor (aritmetická logická jednotka nebo ALU), flash paměť, paměť EEPROM, mnoho registrů, I/O porty a také další zvonky a píšťalky, jako jsou časovače, čítače, komparátory, USART atd. Po připojení napájení , mikrokontrolér se spustí a začne spouštět program uložený v jeho flash paměti. Zároveň může ovládat širokou škálu externích zařízení přes I/O porty.

Co to znamená? To znamená, že v MK můžete implementovat jakýkoli logický obvod, který bude vykonávat určité funkce. To znamená, že MK je mikroobvod, jehož vnitřní obsah si ve skutečnosti vytváříme sami. To umožňuje, po zakoupení několika zcela identických MK, sestavit na nich zcela odlišné obvody a zařízení. Pokud budete chtít provést nějaké změny ve fungování elektronického zařízení, nebudete muset používat páječku, budete muset pouze přeprogramovat MK. V tomto případě jej ani nemusíte odstraňovat ze svého zařízení, pokud používáte AVR, protože tyto MK podporují programování v obvodu. Mikrokontroléry tak překlenují mezeru mezi programováním a elektronikou.

AVR jsou 8bitové mikrokontroléry, tj. jejich ALU může provádět jednoduché operace pouze s 8bitovými čísly v jednom hodinovém cyklu. Nyní je čas si promluvit o tom, který MK použijeme. Pracuji s ATMega16 MK. Je to velmi běžné a lze jej zakoupit v téměř každém obchodě s rádiovými díly za asi 100 rublů. Pokud to nenajdete, můžete si koupit jakýkoli jiný MK řady MEGA, ale v tomto případě k němu budete muset hledat dokumentaci, protože stejné „nohy“ různých MK mohou vykonávat různé funkce a, po připojení by se zdálo, že Pokud jsou všechny závěry správné, můžete získat funkční zařízení nebo možná jen oblak páchnoucího kouře. Při nákupu ATMega16 dbejte na to, aby byl dodáván ve velkém 40pinovém DIP balení a také si pro něj kupte patici, do které jej lze zasunout. Chcete-li s ním pracovat, budete také potřebovat další zařízení: LED diody, tlačítka, konektory atd.

ATMega16 má velmi velké množství různých funkcí. Zde jsou některé z jeho charakteristik:

  • Maximální taktovací frekvence – 16 MHz (8 MHz pro ATMega16L)
  • Většina příkazů se provádí v jednom hodinovém cyklu
  • 32 8bitových pracovních registrů
  • 4 plné 8bitové I/O porty
  • dva 8bitové časovače/čítače a jeden 16bitový
  • 10bitový analogově-digitální převodník (ADC)
  • generátor vnitřních hodin na 1 MHz
  • analogový komparátor
  • rozhraní SPI, I2C, TWI, RS-232, JTAG
  • programování v obvodu a samoprogramování
  • modul pulzně šířkové modulace (PWM).

Úplnou charakteristiku tohoto zařízení, stejně jako návod k jeho použití, naleznete v referenční knize (Datasheet) pro tento MK. Pravda, je to v angličtině. Pokud umíte anglicky, určitě si stáhněte tento Datasheet, obsahuje spoustu užitečných informací.

Pojďme konečně k věci. K mikrokontroléru doporučuji vyrobit speciální vývojovou a odlaďovací desku, na kterou bez páječky (nebo téměř bez ní) sestavíte jakýkoliv elektrický obvod s mikrokontrolérem. Použití takové desky značně usnadní práci s MK a urychlí proces učení jejího programování. Vypadá to takto:

Co k tomu budete potřebovat?

Nejprve budete potřebovat samotnou desku. Koupil jsem hotový v obchodě s rádiovými díly za 115 rublů. Poté jsem na něj připájel všechny potřebné díly. Výsledkem je neuvěřitelně pohodlná věc, na kterou můžete během několika minut sestavit jakýkoli elektrický obvod připojením kabelů a instalací mikroobvodů a indikátorů.

Pro připojení obvodových prvků je velmi vhodné použít kabely s konektory na koncích. Tyto konektory jsou umístěny na „nohách“ vyčnívajících vedle každého portu MK. Mikrokontrolér by měl být instalován v patici a neměl by být připájen k desce, jinak bude velmi obtížné jej odstranit, pokud jej náhodou spálíte. Níže je pinout ATMEGA16 MK:

Pojďme si nyní vysvětlit, které nohy nás zajímají.

  • VCC - napájení je zde přiváděno (4,5 - 5,5 V) ze stabilizovaného zdroje
  • GND – zem
  • RESET – reset (při nízkém napětí)
  • XTAL1, XTAL2 – je zde připojen quartzový rezonátor
  • PA, PB, PC, PD – vstupní/výstupní porty (A, B, C a D).

Cokoli, co produkuje 7-11 V DC, může být použito jako zdroj energie. Pro stabilní provoz MK je nutný stabilizovaný napájecí zdroj. Jako stabilizátor lze použít mikroobvody řady 7805. Jedná se o lineární integrované stabilizátory, na jejichž vstup je napájeno 7-11 V stejnosměrného nestabilizovaného proudu a na výstupu je 5 V stabilizovaného proudu. Před a za 7805 je potřeba nainstalovat filtrační kondenzátory (elektrolytické pro filtrování nízkofrekvenčního rušení a keramické pro vysokofrekvenční). Pokud nemůžete najít stabilizátor, pak můžete jako zdroj použít baterii 4,5 V. MK je nutné napájet přímo z ní.

Níže je schéma zapojení MK:

Pojďme nyní zjistit, co je tady.

BQ1 je quartzový rezonátor, který nastavuje pracovní frekvenci MK. Můžete si nastavit libovolné až do 16 MHz, ale protože v budoucnu plánujeme pracovat s COM portem, doporučuji použít rezonátory pro tyto frekvence: 14,7456 MHz, 11,0592 MHz, 7,3725 MHz, 3,6864 MHz nebo 1 ,8432 MHz (později bude jasné proč). Použil jsem 11,0592 MHz. Je jasné, že čím vyšší frekvence, tím vyšší rychlost zařízení.

R1 je pull-up rezistor, který udržuje napětí 5 V na vstupu RESET. Nízká úroveň napětí na tomto vstupu indikuje reset. Po resetu se MK nabootuje (10 - 15 ms) a začne znovu spouštět program. Protože se jedná o vysokoimpedanční vstup, nemůžete jej nechat „houpat ve vzduchu“ - malý snímač na něm povede k neočekávanému resetu MK. Přesně k tomu slouží R1. Pro spolehlivost také doporučuji nainstalovat kondenzátor C6 (ne více než 20 µF).

SB1 – resetovací tlačítko.

Křemenný rezonátor a filtrační kondenzátor C3 by měly být umístěny co nejblíže MK (ne dále než 5-7 cm), protože jinak by mohlo dojít k rušení ve vodičích, což by vedlo k poruchám MK.

Modrý obdélník ve schématu znázorňuje samotný programátor. Je vhodné jej vyrobit ve formě drátu, jehož jeden konec je zapojen do portu LPT a druhý do určitého konektoru vedle MK. Drát by neměl být příliš dlouhý. Pokud se s tímto kabelem vyskytnou problémy (obvykle ne, ale stát se může cokoli), budete muset adaptér Altera ByteBlaster připájet. Jak na to je napsáno v popisu programátoru AVReal.

Nyní, když jsme se zabývali hardwarem, je čas přejít k softwaru.

Existuje několik vývojových prostředí pro programování AVR. Za prvé, toto je AVR Studio - oficiální programovací systém od společnosti Atmel. Umožňuje vám psát v assembleru a ladit programy napsané v assembleru, C a C++. IAR je komerční programovací systém v C, C++ a assembleru. WinAVR je open source kompilátor. AtmanAVR je programovací systém pro AVR s rozhraním téměř stejným jako Visual C++ 6. AtmanAVR také umožňuje ladění programů a obsahuje mnoho pomocných funkcí, které usnadňují psaní kódu. Tento programovací systém je komerční, ale podle licence jej můžete měsíc používat zdarma.

Navrhuji začít pracovat s IAR jako nejtransparentnějším vývojovým prostředím. V IAR je projekt vytvořen zcela ručně, takže po dokončení několika projektů již jasně víte, co každý řádek kódu znamená a co se stane, pokud jej změníte. Při práci s AtmanAVR buď budete muset použít předem vytvořenou šablonu, která je pro člověka bez zkušeností velmi těžkopádná a těžko pochopitelná, nebo budete mít velké problémy s hlavičkovými soubory při sestavování projektu od začátku. Poté, co jsme se zabývali IAR, se následně podíváme na další kompilátory.

Nejprve si tedy pořiďte IAR. Je velmi častý a jeho nalezení by neměl být problém. Po stažení IAR 3.20 odněkud nainstalujte kompilátor/pracovní prostředí a spusťte jej. Poté můžete začít pracovat.

Po spuštění IAR vyberte soubor/nový/pracovní prostor, vyberte cestu k našemu projektu a vytvořte pro něj složku a pojmenujte ji, například „Prog1“. Nyní vytvoříme projekt: Projekt / Vytvořit nový projekt…Říkejme tomu také „Prog1“. Klikněte pravým tlačítkem myši na název projektu ve stromu projektu a vyberte „Možnosti“

Zde nakonfigurujeme kompilátor pro konkrétní MK. Nejprve je třeba vybrat typ procesoru ATMega16 na záložce Target, zaškrtnout políčko Enable bit definitions in I/O-include files na záložce Konfigurace knihovny (aby bylo možné v kódu programu použít názvy bitů různých registrů MK ) a tam vyberte typ knihovny C /EU++. V kategorii ICCAVR je potřeba zaškrtnout políčko Povolit vícebajtovou podporu na záložce Jazyk a vypnout optimalizaci na záložce Optimalizace (jinak to zničí náš první program).

Dále vyberte kategorii XLINK. Zde musíte určit formát kompilovaného souboru. Protože nyní nastavujeme možnosti pro režim ladění, jak je popsáno v nadpisu, potřebujeme jako výstup získat ladicí soubor. Později jej otevřeme v AVR Studiu. Chcete-li to provést, musíte vybrat příponu.cof a typ souboru je ubrof 7.

Nyní klikněte na OK a poté změňte Debug na Release.

Přejděte znovu na Možnosti, kde jsou všechny parametry kromě XLINK nastaveny na stejné. V XLINK změňte příponu na .hex a formát souboru na intel-standard.

To je vše. Nyní můžete začít psát svůj první program. Vytvořte nový zdroj/text a zadejte do něj následující kód:

#zahrnout"iom16.h" zkratka unsigned int i; prázdnota hlavní( prázdnota) (DDRB = 255; PORTB = 0; zatímco(1) { -li(PORTB == 255) PORTB = 0; jiný PORTB++; pro(i=0; i

Ve složce se nachází soubor "iom16.h". (C:\Program Files)\IAR Systems\Embedded Workbench 3.2\avr\inc. Pokud používáte jiný MK, například ATMega64, vyberte soubor „iom64.h“. Tyto hlavičkové soubory ukládají informace o MK: názvy registrů, bity v registrech a názvy přerušení. Každý jednotlivý pin portu A, B, C nebo D může fungovat buď jako vstup, nebo jako výstup. To je určeno registrem směrování dat (DDR). 1 dělá z nohy výstup, 0 vstup. Nastavením např. DDRA = 13 tedy uděláme „nohy“ PB0, PB2, PB3 výstupy, zbytek – vstupy, protože 13 v binární podobě je 00001101.

PORTB je registr, který určuje stav pinů portu. Když tam napíšeme 0, nastavíme napětí na všech výstupech na 0 V. Pak je tu nekonečná smyčka. Při programování MK dělají vždy nekonečnou smyčku, ve které MK provádí nějakou akci, dokud není resetován nebo dokud nedojde k přerušení. V tomto cyklu píší jakoby „kód na pozadí“, který MK provádí jako poslední věc. Může to být například zobrazování informací na displeji. V našem případě se obsah registru PORTB zvětšuje, dokud není plný. Poté vše začíná znovu. Konečně desetitisícový cyklus pro smyčku. Je potřeba vytvořit viditelné zpoždění při přepínání stavu portu B.



Nyní tento soubor uložíme do složky projektu jako Prog1.c, zkopírujeme soubor iom16.h do složky projektu, vybereme Project/Add Files a přidáme „iom16.h“ a „Prog1.c“. Vyberte Release, stiskněte F7, program se zkompiluje a měla by se objevit zpráva:


Celkový počet chyb: 0
Celkový počet varování: 0

Tady je fotka mého programátora:

Stáhněte si programátor AVReal. Zkopírujte jej (AVReal32.exe) do složky Release/exe, kde by se měl nacházet soubor Prog1.hex. Napájíme MK, připojíme programovací kabel. Otevřete Far Manager (nejpohodlnější je flashnout MK), přejděte do této složky, stiskněte Ctrl+O. Jelikož máme úplně nový MK, cpeme

avreal32.exe +MEGA16 -o11.0592MHZ -p1 -fblev=0,jtagen=1,cksel=F,sut=1 –w

Pokud nepoužíváte 11059200 Hz, nezapomeňte zadat správnou frekvenci! Přitom tzv pojistky – registry, které řídí jeho činnost (použití vnitřního generátoru, Jtag apod.). Poté je připraven k příjmu prvního programu. Programátor dostane jako parametry použitý LPT port, frekvenci, název souboru a další (vše je uvedeno v popisu AVReal). Vytočíme:

Avreal32.exe +Mega16 -o11.0592MHz -p1 -e -w -az -% Prog1.hex

Pokud je připojení správné, programátor oznámí úspěšné naprogramování. Neexistuje žádná záruka, že to bude fungovat napoprvé (při prvním zavolání programu). Sám se někdy nechám naprogramovat podruhé. Možná je vadný port LPT nebo dochází k rušení v kabelu. Pokud se vyskytnou problémy, pečlivě zkontrolujte kabel. Z vlastní zkušenosti vím, že 60 % poruch je spojeno s nedostatkem kontaktu na správném místě, 20 % s přítomností nepotřebného a dalších 15 % s chybným připájením špatné věci na nesprávnou věc. Pokud vše ostatní selže, přečtěte si popis programátoru a zkuste sestavit Byte Blaster.

Předpokládejme, že vše funguje pro vás. Pokud nyní připojíte osm LED k portu B MK (proveďte to s vypnutým MK a je vhodné zapojit 300-400 Ohm odpory do série s LED) a připojíte napájení, stane se malý zázrak – „ vlna“ jimi projede!

© Kiselev Roman
května 2007

prosince 2015

1. Výhody navržené metody

Obvody zařízení založené na mikrokontrolérech (MCU) se obvykle vyznačují kombinací dvou obtížně kombinovatelných vlastností: maximální jednoduchosti a vysoké funkčnosti. Funkcionalitu lze navíc v budoucnu měnit a rozšiřovat bez jakýchkoliv změn v obvodu – pouze výměnou programu (blikáním). Tyto vlastnosti jsou vysvětleny skutečností, že tvůrci moderních mikrokontrolérů se snažili umístit na jeden čip vše, co by vývojář elektronického zařízení mohl potřebovat - alespoň co nejvíce. V důsledku toho došlo k přesunu důrazu od obvodů a instalace k softwaru. S použitím MK je nyní méně potřeba „zatěžovat“ obvod součástkami a existuje méně spojení mezi součástmi. To samozřejmě činí obvod atraktivnějším pro opakování pro zkušené i začínající elektrotechniky. Ale jak už to tak bývá, za všechno se musí platit. To se také neobešlo bez potíží. Pokud si koupíte nový MK, nainstalujete jej do obvodu správně sestaveného z opravitelných dílů a připojíte napájení, pak nic nebude fungovat - zařízení nebude fungovat. Mikrokontrolér potřebuje program.

Zdá se, že i s tím je vše jednoduché - na internetu najdete mnoho schémat s bezplatným firmwarem. Ale je tu jeden háček: firmware musí být nějakým způsobem „nahrán“ do mikrokontroléru. Pro někoho, kdo to nikdy předtím nedělal, se takový úkol často stává problémem a hlavním odpudivým faktorem, který ho často nutí opustit potěšení z používání MK a hledat schémata založená na „volné“ a rigidní logice. Vše ale není tak složité, jak by se na první pohled mohlo zdát.

Po analýze publikací na internetu můžete vidět, že tento problém se nejčastěji řeší jedním ze dvou způsobů: nákupem hotového programátoru nebo výrobou domácího. Publikované obvody domácích programátorů jsou přitom velmi často nepřiměřeně složité – mnohem složitější, než je skutečně nutné. Samozřejmě, pokud plánujete flashovat MK každý den, je lepší mít „cool“ programátor. Pokud se však potřeba takového postupu čas od času objeví zřídka, můžete se obejít bez programátora. Ne, samozřejmě, nemluvíme o tom, abychom se to naučili dělat silou myšlenky. To znamená, že pochopením toho, jak programátor interaguje s mikrokontrolérem při zápisu a čtení informací v jeho programovacím režimu, si vystačíme s dostupnými nástroji pro širší účel. Tyto nástroje budou muset nahradit softwarovou i hardwarovou část programátoru. Hardware musí zajistit fyzické připojení k mikroobvodu MK, možnost aplikovat logické úrovně na jeho vstupy a číst data z jeho výstupů. Softwarová část musí zajistit chod algoritmu, který řídí všechny potřebné procesy. Upozorňujeme také, že kvalita záznamu informací v MK nezávisí na tom, jak „v pohodě“ je váš programátor. Neexistuje nic jako „lépe nahrané“ nebo „horší“. Existují pouze dvě možnosti: „registrovaný“ a „neregistrovaný“. To je vysvětleno skutečností, že proces záznamu uvnitř krystalu je přímo řízen samotným MK. Stačí mu poskytnout vysoce kvalitní napájení (žádné rušení nebo zvlnění) a správně uspořádat rozhraní. Pokud výsledky testovacího čtení neodhalí žádné chyby, pak je vše v pořádku - ovladač můžete použít k určenému účelu.

Abychom mohli zapsat program do MK bez programátoru, potřebujeme převodník portů USB-RS232TTL a také. Převodník USB-RS232TTL umožňuje pomocí USB portu vytvořit COM port, který se od „skutečného“ liší pouze tím, že jeho vstupy a výstupy využívají logické úrovně TTL, tedy napětí v rozsahu od 0 do 5 voltů ( více si můžete přečíst v článku " "). V každém případě se takový převodník hodí mít ve své „domácnosti“, takže pokud jej ještě nemáte, rozhodně se vyplatí pořídit. Co se týče logických úrovní, v našem případě je TTL dokonce výhodou oproti běžnému COM portu, protože vstupy a výstupy takového portu lze přímo připojit k libovolnému mikrokontroléru napájenému 5 V včetně ATtiny a ATmega. Nezkoušejte ale použít běžný COM port - používají napětí v rozsahu od -12 do +12 V (nebo -15...+15V). V tomto případě je nepřípustné přímé připojení k mikrokontroléru!!!

Myšlenka vytvořit skript pro program Perpetuum M, který implementuje funkce programátoru, vznikla po přečtení řady publikací na internetu nabízejících určitá řešení pro firmware MK. V každém případě byly zjištěny závažné nedostatky nebo nadměrné potíže. Často jsem narazil na obvody programátorů, které obsahovaly mikrokontrolér, a přitom se docela vážně dostávaly rady typu: „...a k naprogramování mikrokontroléru pro tento programátor budeme potřebovat... je to tak – jiný programátor!“ Dále bylo navrženo jít za přítelem, hledat placenou službu atd. Kvalita softwaru distribuovaného v síti pro tyto účely také nebyla působivá - bylo zaznamenáno mnoho problémů jak s funkčností, tak s „zamračeností“ uživatelského rozhraní. Pochopit, jak program používat, často zabere spoustu času - musí být studován i pro provádění těch nejjednodušších akcí. Jiný program umí něco dělat dlouho a pilně, ale že se do MK nic nezapisuje, se uživatel dozví až po kompletním dokončení celého firmwaru a následném testovacím načtení. Nastává také následující problém: uživatel se snaží vybrat svůj MK ze seznamu podporovaných krystalů, ale není v seznamu. V tomto případě nebudete moci program používat - zařazení do seznamu chybějících MK se zpravidla neposkytuje. Ruční výběr ovladače ze seznamu navíc vypadá zvláštně, vezmeme-li v úvahu, že programátor v mnoha případech dokáže sám určit typ MK. To vše není řečeno proto, abychom házeli blátem na stávající produkty, ale abychom vysvětlili důvod, proč se objevil skript pro program Perpetuum M, popsaný v tomto článku. Problém skutečně existuje a týká se především začátečníků, kterým se ne vždy podaří tuto „zeď“ překonat, aby udělali první krok do světa mikrokontrolérů. Navrhovaný skript zohledňuje nedostatky zjištěné v jiných programech. Byla implementována maximální „transparentnost“ provozu algoritmu, extrémně jednoduché uživatelské rozhraní, které nevyžaduje učení a nenechává žádnou šanci se zmást a „kliknout na špatnou věc“. Pokud požadovaný MK není mezi podporovanými, můžete jeho popis přidat sami, přičemž potřebná data převezmete z dokumentace stažené z webu vývojáře MK. A co je nejdůležitější, skript je otevřený ke studiu a úpravám. Každý si jej může otevřít v textovém editoru, studovat a upravovat podle vlastního uvážení, měnit stávající funkce podle svého vkusu a doplňovat chybějící.

První verze skriptu byla vytvořena v červnu 2015. Tato verze poskytuje podporu pouze pro mikrokontroléry řady ATtiny a ATmega společnosti Atmel s funkcemi pro zápis/čtení flash paměti, nastavení konfiguračních bitů a automatickou detekci typu řadiče Zápis a čtení EEPROM není implementováno Bylo plánováno doplnění funkčnosti skriptu : přidat zápis a čtení EEPROM, implementaci podpory pro řadiče PIC atd. Z tohoto důvodu nebyl skript dosud publikován, ale kvůli nedostatku času se realizace plánu zpozdila, a tak se nestal nejlepší nepřítele dobra, bylo rozhodnuto zveřejnit stávající verzi. Pokud již implementované funkce nebudou stačit, nezlobte se. V tomto případě můžete zkusit požadovanou funkci přidat sami. Nebudu skrývat: myšlenka vytvoření tohoto skriptu má zpočátku také vzdělávací význam. Po pochopení algoritmu a přidání něčeho vlastního do něj budete moci lépe porozumět fungování MK v programovacím režimu, takže v v budoucnu se neocitnete v pozici dívky před rozbitým autem, která se zamyšleně dívá do jeho útrob a nechápe, proč to „nefunguje“.

2. Rozhraní MK v programovacím režimu

Existuje několik různých způsobů, jak uvést regulátor do programovacího režimu a pracovat s ním v tomto režimu. Nejjednodušší implementace pro regulátory řad ATtiny a ATmega je možná SPI. My toho využijeme.

Než však začneme zvažovat signály nezbytné pro generování SPI, učiníme řadu výhrad. Mikrokontrolér má konfigurační bity. Jsou to něco jako páčkové spínače, spínání, které umožňuje měnit některé vlastnosti mikroobvodu v souladu s potřebami projektu. Fyzicky se jedná o energeticky nezávislé paměťové buňky, jako jsou ty, do kterých je zapsán program. Rozdíl je v tom, že je jich velmi málo (až tři bajty pro ATmega) a nejsou součástí adresního prostoru žádné paměti. Zápis a čtení konfiguračních dat se provádí samostatnými příkazy v programovacím režimu MK. Nyní je důležité poznamenat, že některé konfigurační bity ovlivňují samotnou schopnost používat SPI. U některých jejich hodnot se může ukázat, že SPI nelze použít. Pokud narazíte na takový mikrokontrolér, metoda navržená v tomto článku nepomůže. V tomto případě budete muset buď změnit nastavení konfiguračních bitů v programátoru, který podporuje jiný programovací režim, nebo použít jiný mikrokontrolér. Tento problém se však týká pouze použitých MK nebo těch, se kterými si již někdo neúspěšně „pohrál“. Faktem je, že nové MCU přicházejí s nastavením konfiguračních bitů, které nebrání použití SPI. Potvrzují to výsledky testu programátorského skriptu pro program Perpetuum M, během kterého byly úspěšně flashovány čtyři různé MK (ATmega8, ATmega128, ATtiny13, ATtiny44). Všechny byly nové. Počáteční nastavení konfiguračních bitů bylo v souladu s dokumentací a nezasahovalo do použití SPI.

Vzhledem k výše uvedenému byste měli věnovat pozornost následujícím kouskům. Bit SPIEN výslovně povoluje nebo zakazuje použití SPI, proto v našem případě musí být jeho hodnota povolení. Bit RSTDISBL je schopen převést jeden z výstupů mikroobvodu (předem určený) na vstup signálu „reset“ nebo jej neroztočit (v závislosti na hodnotě zapsané do tohoto bitu). V našem případě je nutný vstup „reset“ (pokud chybí, nebude možné přepnout MK do programovacího režimu přes SPI). Existují také bity skupiny CKSEL, které určují zdroj hodinového signálu. Nebrání použití SPI, ale je třeba je mít také na paměti, protože pokud nebudou vůbec žádné hodinové pulsy nebo bude jejich frekvence nižší než přijatelná pro danou rychlost SPI, také se nic dobrého nestane. Typicky mají nové MCU, které mají interní RC oscilátor, bity skupiny CKSEL nakonfigurované tak, aby jej používaly. To nám docela vyhovuje - taktování je zajištěno bez jakéhokoli dalšího úsilí z naší strany. Není potřeba pájet křemenný rezonátor ani připojovat externí generátor. Pokud uvedené bity obsahují jiné nastavení, budete se muset postarat o taktování v souladu s nastavením. V tomto případě může být nutné k MCU připojit quartzový rezonátor nebo externí generátor hodin. Ale v tomto článku nebudeme uvažovat, jak se to dělá. Příklady připojení MK pro programování obsažené v tomto článku jsou navrženy pro nejjednodušší případ.

Rýže. 1. Výměna dat přes SPI v programovacím režimu

Nyní se podívejme na obrázek 1, převzatý z dokumentace k ATmega128A MK. Ukazuje proces přenosu jednoho bajtu do MK a současného příjmu jednoho bajtu z MK. Oba tyto procesy, jak vidíme, využívají stejné hodinové pulsy dodávané z programátoru do mikrokontroléru na jeho SCK vstupu - jednom z pinů mikroobvodu, kterému je taková role přiřazena v programovacím režimu SPI. Dvě další signálové linky zajišťují příjem a přenos dat po jednom bitu na takt. Přes vstup MOSI vstupují data do mikrokontroléru a čtená data se odebírají z výstupu MISO. Všimněte si dvou tečkovaných čar nakreslených od SCK k MISO a MOSI. Ukazují, ve kterém okamžiku mikrokontrolér „spolkne“ datový bit nastavený na vstupu MOSI a ve kterém okamžiku sám nastaví svůj vlastní datový bit na výstup MISO. Všechno je docela jednoduché. Ale pro vstup MK do programovacího režimu potřebujeme ještě signál RESET. Nezapomeňme také na společný vodič GND a napájení VCC. Celkově se ukazuje, že k mikrokontroléru je potřeba připojit pouze 6 vodičů, aby mohl flashovat jeho firmware přes SPI. Níže to rozebereme podrobněji, ale zatím dodáme, že výměna dat s MK v programovacím režimu přes SPI probíhá v paketech po 4 bytech. První bajt každého paketu je v podstatě celý vyhrazen pro kódování instrukce. Druhý bajt, v závislosti na prvním, může být pokračováním kódu příkazu nebo částí adresy, nebo může mít libovolnou hodnotu. Třetí bajt se používá především pro přenos adres, ale v mnoha instrukcích může mít libovolnou hodnotu. Čtvrtý bajt obvykle přenáší data nebo má libovolnou hodnotu. Současně s přenosem čtvrtého bytu přijímají některé příkazy data přicházející z mikrokontroléru. Podrobnosti pro každý příkaz lze nalézt v dokumentaci ovladače v tabulce nazvané "SPI Serial Programming Instruction Set". Prozatím pouze poznamenáváme, že celá výměna s kontrolérem je postavena ze sekvence 32bitových paketů, v každém z nich se nepřenáší více než jeden bajt užitečné informace. To není příliš optimální, ale celkově to funguje dobře.

3. Připojení MK pro programování

Aby bylo zajištěno, že všechny potřebné signály jsou dodávány na vstupy mikrokontroléru pro organizaci SPI rozhraní a čtení dat z jeho MISO výstupu, není nutné vytvářet programátor. To lze snadno provést pomocí nejběžnějšího převodníku USB-RS232TTL.

Na internetu lze často najít informace, že takové převodníky jsou podřadné a že se s nimi nedá nic vážného dělat. Ale s ohledem na většinu modelů převodníků je tento názor mylný. Ano, v prodeji jsou převodníky, které oproti standardnímu COM portu nemají k dispozici všechny vstupy a výstupy (například jen TXD a RXD), přitom mají nerozebíratelné provedení (mikroobvod je vyplněn plastem - je nemožné dosáhnout na jeho kolíky). Ty se ale nevyplatí kupovat. V některých případech můžete chybějící vstupy a výstupy portů získat připájením kabeláže přímo k čipu. Příklad takového „vylepšeného“ převodníku je znázorněn na obrázku 2 (čip PL-2303 – více podrobností o účelu jeho pinů v článku „“). Jedná se o jeden z nejlevnějších modelů, ale při použití v domácích designech má své vlastní výhody. Rozšířené jsou také plnohodnotné adaptérové ​​kabely se standardním devítipinovým konektorem na konci, jako je port COM. Od běžného COM portu se liší pouze úrovněmi TTL a nekompatibilitou se starším softwarem a některým starším hardwarem. Lze také poznamenat, že šňůry na čipu CH34x se v různých extrémních testech ukazují jako mnohem spolehlivější a stabilnější ve srovnání s převodníky na PL-2303. Při běžném používání však rozdíl není patrný.

Při výběru převodníku USB-RS232TTL byste měli věnovat pozornost také kompatibilitě jeho ovladače s verzí operačního systému, který používáte.

Podívejme se blíže na princip propojení mikrokontroléru a převodníku USB-RS232TTL na příkladu čtyř různých modelů MK: ATtiny13, ATtiny44, ATmega8 a ATmega128. Obrázek 3 ukazuje obecné schéma takového zapojení. Možná vás překvapí, že signály RS232 (RTS, TXD, DTR a CTS) jsou používány nevhodně. Ale nebojte se: program Perpetuum M s nimi umí pracovat přímo - nastavovat výstupní hodnoty a číst stavy vstupů. V každém případě hojně používané převodníky USB-RS232TTL na čipech CH34x a PL-2303 tuto schopnost poskytují – to je ověřeno. Problémy by neměly být ani s jinými oblíbenými převodníky, protože pro přístup k portu se používají standardní funkce Windows.

Rezistory zobrazené v obecném schématu nelze v zásadě instalovat, ale přesto je lepší je nainstalovat. Jaký je jejich účel? Pomocí TTL vstupů a výstupů převodníku a pětivoltového napájení mikrokontroléru se tím zbavíme nutnosti koordinovat logické úrovně - vše je již zcela v pořádku. To znamená, že připojení mohou být přímá. Ale během experimentů , stát se může cokoli. Například šroubovák může podle zákona podlosti spadnout právě na místo, kam spadnout nemohl, a zkratovat něco, co by v žádném případě zkratovat nemělo. se ukáže jako „šroubovák". Rezistory v tomto případě někdy snižují následky. jedním z jejich účelů je eliminovat možný konflikt výstupu. Faktem je, že po dokončení programování přejde mikrokontrolér do normálního provozního režimu a může se stane, že jeho pin připojený k výstupu převodníku (RTS, TXD nebo DTR) se podle programu právě zaznamenaného v MK stane také výstupem.V tomto případě bude velmi špatné, když se dva přímo spojené výstupy „pobijí“ - zkuste nastavit různé logické úrovně. V takovém „boji“ může někdo „prohrát“, ale to nechceme.

Hodnoty tří rezistorů jsou zvoleny na úrovni 4,3 KOhm. To platí pro spojení mezi výstupem převodníku a vstupem mikrokontroléru. Na přesnosti rezistorů nezáleží: jejich odpor můžete snížit na 1 KOhm nebo zvýšit na 10 KOhm (ale v druhém případě se zvyšuje riziko rušení při použití dlouhých vodičů na cestě k MK). Pokud jde o propojení mezi vstupem převodníku (CTS) a výstupem mikrokontroléru (MISO), je zde použit odpor 100 Ohm. To je vysvětleno zvláštnostmi vstupu použitého převodníku. Během testů byl na mikroobvodu PL-2303 použit převodník, jehož vstupy jsou zjevně připojeny ke kladnému napájecímu zdroji s relativně nízkým odporem (řádově několik stovek ohmů). Abych „zlomil pull-up“, musel jsem nainstalovat rezistor s tak malým odporem. Nemusíte jej však vůbec instalovat. Na převodníku je to vždy vstup. Nemůže se stát východiskem, což znamená, že v žádném vývoji událostí nedojde ke konfliktu východů.

Pokud má čip samostatný kolík AVCC pro napájení analogově-digitálního převodníku (například ATmega8 nebo ATmega128), měl by být připojen ke společnému napájecímu kolíku VCC. Některé integrované obvody mají více než jeden napájecí kolík VCC nebo více než jeden GND. Například ATmega128 má 3 piny GND a 2 piny VCC. V trvalém provedení je lepší spojovat stejnojmenné piny k sobě. V našem případě můžete při programování použít každý jeden pin VCC a GND.

A takto vypadá připojení ATtiny13. Obrázek ukazuje přiřazení pinů používané při programování přes SPI. U fotky je, jak vypadá dočasné spojení ve skutečnosti.


Někdo může říct, že to není vážné - zapojení na elektroinstalaci. Ale ty a já jsme rozumní lidé. Naším cílem je naprogramovat mikrokontrolér, věnovat tomu minimum času a dalších prostředků a ne se před někým předvádět. Kvalita tím neutrpí. Metoda „na drátech“ je v tomto případě poměrně účinná a oprávněná. Flashnutí firmwaru ovladače je jednorázová procedura, takže nemá smysl to zakrývat kamínky. Pokud je v budoucnu zamýšleno změnit firmware bez vyjmutí regulátoru z okruhu (v hotovém výrobku), pak je to zohledněno při instalaci při výrobě zařízení. Obvykle se pro tento účel instaluje konektor (RESET, SCK, MOSI, MISO, GND) a MK lze flashovat i po instalaci na desku. Ale to jsou kreativní požitky. Zvažujeme nejjednodušší případ.

Nyní přejděme k ATtiny44 MK. Tady je vše v podstatě stejné. Na základě nákresu a fotografie nebude mít ani začátečník žádné potíže s určením spojení. Stejně jako ATtiny44 můžete připojit mikrokontroléry ATtiny24 a ATtiny84 - přiřazení pinů pro tyto tři je stejné.


Dalším příkladem dočasného připojení řadiče pro jeho programování je ATmega8. Je zde více pinů, ale princip je stejný - pár vodičů a nyní je ovladač připraven do něj „vyplnit“ informace. Extra černý drát na fotografii pocházející z kolíku 13 se neúčastní programování. Je navržen tak, aby z něj odstranil zvukový signál poté, co MK opustí režim programování. To je způsobeno skutečností, že během ladění skriptu pro "Perpetuum M" byl program music box stažen do MK.


Často je jeden ovladač k dispozici v různých pouzdrech. V tomto případě je přiřazení pinů pro každý případ rozděleno jinak. Pokud pouzdro vašeho ovladače není podobné tomu, které je znázorněno na obrázku, zkontrolujte účel kolíků v technické dokumentaci, kterou si můžete stáhnout z webu vývojáře MK.

Abychom obrázek dokončili, podívejme se na připojení mikroobvodu MK s velkým počtem "nohami". Účel extra černého drátu na fotce vycházejícího z pinu 15 je úplně stejný jako v případě ATmega8.


Pravděpodobně jste již přesvědčeni, že vše je docela jednoduché. Každý, kdo umí spočítat piny mikroobvodů (od značky v kroužku proti směru hodinových ručiček), na to přijde. A nezapomeňte na přesnost. Mikroobvody milují úhledné lidi a neodpouštějí neopatrné zacházení.

Než přejdete k softwarové části, ujistěte se, že je správně nainstalován ovladač převodníku USB-RS232TTL (zkontrolujte Správce zařízení Windows). Zapamatujte si nebo si zapište číslo virtuálního COM portu, který se objeví po připojení převodníku. Toto číslo bude nutné zadat do textu skriptu, o kterém si můžete přečíst níže.

4. Skript - programátor pro "Perpetuum M"

Přišli jsme na hardwarovou část „programátoru“. To už je polovina bitvy. Nyní zbývá vypořádat se se softwarovou částí. Jeho roli bude plnit program Perpetuum M pod řízením skriptu, který implementuje všechny potřebné funkce pro interakci s mikrokontrolérem.

Archiv se skriptem by měl být rozbalen do stejné složky, kde je umístěn program perpetuum.exe. V tomto případě se při spuštění souboru perpetuum.exe na obrazovce zobrazí nabídka se seznamem nainstalovaných skriptů, mezi nimiž bude řádek „AVR MK Programmer“ (může být jediný). Toto je linie, kterou potřebujeme.

Skript se nachází ve složce PMS v souboru "MK Programmer AVR.pms". Tento soubor lze prohlížet, studovat a v případě potřeby upravovat v běžném textovém editoru, jako je Windows Poznámkový blok. Před použitím skriptu budete s největší pravděpodobností muset provést změny v textu souvisejícím s nastavením portu. Chcete-li to provést, zkontrolujte název portu použitého ve Správci zařízení Windows a v případě potřeby proveďte příslušnou úpravu řádku "PortName="COM4";" - místo čísla 4 může být jiné číslo. Také při použití jiného modelu převodníku USB-RS232TTL může být nutné změnit nastavení inverze signálu (řádky skriptu začínající slovem „High“). Inverzi signálů převodníkem USB-RS232TTL můžete zkontrolovat pomocí některého z příkladů obsažených v návodu k programu Perpetuum M (sekce funkcí pro práci s portem).

Podsložka MK_AVR obsahuje soubory s popisy podporovaných ovladačů. Pokud ovladač, který potřebujete, mezi nimi není, můžete jej přidat sami podle analogie. Vezměte jeden ze souborů jako vzorek a pomocí textového editoru zadejte potřebná data z dokumentace k vašemu mikrokontroléru. Hlavní je dávat pozor, zadávat data bez chyb, jinak se MK nenaprogramuje, nebo bude naprogramován špatně. Původní verze podporuje 6 mikrokontrolérů: ATtiny13, ATtiny24, ATtiny44, ATtiny84, ATmega8 a ATmega128. Skript implementuje automatické rozpoznání připojeného řadiče – není třeba jej zadávat ručně. Pokud identifikátor načtený z MK není mezi dostupnými popisy, zobrazí se zpráva, že ovladač nebyl rozpoznán.

Archiv se skriptem obsahuje i další informace. Složka AVR controller inc files obsahuje velmi užitečnou a rozsáhlou sbírku definičních souborů kontroléru. Tyto soubory se používají při psaní vlastních programů pro MK. Čtyři další složky „MusicBox_...“ obsahují soubory s programem v jazyce Assembly a firmware připravené ke stažení do MK samostatně pro ATtiny13, ATtiny44, ATmega8 a ATmega128. Pokud jste již připojili jeden z těchto MK pro programování, jak je navrženo v tomto článku, můžete jej flashnout hned teď - získáte hudební box. Více o tom níže.

Když v menu skriptu vyberete řádek „MK AVR Programmer“, skript se začne spouštět. Zároveň otevře port, odešle MK příkaz k přepnutí do programovacího režimu, obdrží potvrzení od MK o úspěšném přechodu, vyžádá si identifikátor MK a vyhledá popis tohoto MK podle jeho identifikátoru mezi dostupnými. soubory s popisy. Pokud nenalezne požadovaný popis, zobrazí odpovídající zprávu. Pokud je nalezen popis, otevře se hlavní menu programátoru. Jeho screenshot můžete vidět na obrázku 8. Další pochopení není těžké – menu je velmi jednoduché.

V první verzi skriptu nejsou implementovány některé funkce plnohodnotného programátora. Například neexistuje způsob, jak číst a zapisovat do EEPROM. Pokud ale otevřete skript v textovém editoru, uvidíte, že je velmi malý, a to navzdory skutečnosti, že to hlavní je v něm již implementováno. To naznačuje, že přidání chybějících funkcí není tak obtížné - jazyk je velmi flexibilní, umožňuje implementovat bohatou funkčnost v malém programu. Ale pro většinu případů stačí i stávající funkce.

Některá omezení funkčnosti jsou popsána přímo v textu skriptu:
//implementováno nahrávání pouze z nulové adresy (Extended Segment Address Record je ignorován, LOAD OFFSET - také)
//nekontroluje se pořadí a návaznost záznamů v HEX souboru
//kontrolní součet není zaškrtnutý
To platí pro práci s HEX souborem, ze kterého je převzat firmware kód pro MK. Pokud tento soubor není poškozen, kontrola kontrolního součtu nebude mít žádný účinek. Pokud je zkreslený, nebude možné jej pomocí skriptu detekovat. Zbývající omezení ve většině případů neublíží, ale i tak je třeba je mít na paměti.

5. Hrací skříňka - jednoduché řemeslo pro začátečníky

Pokud máte jeden z těchto mikrokontrolérů: ATtiny13, ATtiny44, ATmega8 nebo ATmega128, můžete jej snadno proměnit v hudební skříňku nebo hudební kartu. K tomu stačí zapsat odpovídající firmware do MK - jeden z těch čtyř, které jsou umístěny ve složkách "MusicBox_..." ve stejném archivu se skriptem. Firmwarové kódy jsou uloženy v souborech s příponou „.hex“. Použití ATmega128 pro takové řemeslo je samozřejmě „mastné“, stejně jako ATmega8. Ale to může být užitečné pro testování nebo experimentování, jinými slovy, pro vzdělávací účely. Připojeny jsou i texty programů v Assembleru. Programy nebyly vytvořeny od nuly - jako základ byl vzat program music box z knihy A.V. Belova „AVR Microcontrollers in Amateur Radio Practice“. Původní program prošel řadou významných změn:
1. přizpůsobené pro každý ze čtyř MK: ATtiny13, ATtiny44, ATmega8 a ATmega128
2. tlačítka byla odstraněna - k ovladači není třeba nic připojovat kromě napájení a zvukového emitoru (melodie se přehrávají jedna za druhou v nekonečné smyčce)
3. trvání každé noty se zkracuje o dobu pauzy mezi notami, aby se eliminovaly poruchy hudebního rytmu
4. je připojena osmá melodie, v knižní verzi se nepoužívá
5. od subjektivního: některá „vylepšení“ pro optimalizaci a usnadnění pochopení algoritmu

V některých melodiích je slyšet faleš a dokonce i hrubé chyby, zejména v „Smile“ - uprostřed. Kódy vyzváněcích tónů byly převzaty z knihy (nebo spíše staženy z webu autora knihy spolu s původním souborem asm) a nebyly upraveny. Zjevně jsou chyby v kódování melodií. To ale není problém – každý, kdo se k hudbě „kamarádí“, na to snadno přijde a vše napraví.

V ATtiny13 kvůli chybějícímu 16bitovému čítači musel být pro reprodukci not použit 8bitový čítač, což vedlo k mírnému poklesu přesnosti not. To je ale sluchem sotva patrné.

O konfiguračních bitech. Jejich nastavení musí odpovídat stavu nového mikrokontroléru. Pokud byl váš MK již někde používán, musíte zkontrolovat stav jeho konfiguračních bitů a případně je uvést do souladu s nastavením nového mikrokontroléru. Stav konfiguračních bitů nového mikrokontroléru zjistíte z dokumentace k tomuto MK (sekce "Pojistkové bity"). Výjimkou je ATmega128. Tento MCU má bit M103C, který umožňuje režim kompatibility se starším ATmega103. Aktivace bitu M103C značně snižuje možnosti ATmega128 a tento bit je aktivní na novém MK. Musíte resetovat M103C do neaktivního stavu. Chcete-li manipulovat s konfiguračními bity, použijte odpovídající část nabídky skriptu programátoru.

Nemá smysl uvádět schéma hrací skříňky: obsahuje pouze mikrokontrolér, napájecí zdroj a piezoelektrický emitor. Napájení je dodáváno přesně stejným způsobem jako při programování MK. Zvukový emitor se zapojuje mezi společný vodič (GND pin ovladače) a jeden z pinů MK, jehož číslo najdete v souboru s kódem programové montáže (*.asm). Na začátku textu programu pro každý MK v komentářích je řádek: „zvukový signál je generován na pinu XX“. Po dokončení skriptu programátoru mikrokontrolér opustí režim programování a přejde do normálního provozu. Přehrávání melodií začne okamžitě. Můžete to zkontrolovat připojením zvukového emitoru. Zvukový emitor můžete při programování krystalu ponechat připojený pouze v případě, že je zvuk přebírán z pinu, který není použit v SPI, jinak může přídavná kapacita na pinu rušit programování.