|
Už od doby, kdy jsem si pořídil ATARI 800XL mne bavilo ho programovat a vůbec nejlepší to bylo v Assembleru procesoru 6502. Například podprogram, který měl vykreslit na portech joysticku naměřené průběhy napětí, pracoval s příkazy PLOT a DRAW pod Basicem skoro minutu. Stejný podprogram "ve strojáku" to vykreslil prakticky okamžitě.
Na škole mne pak něco málo naučili o procesorech 8080 a o něco později jsem vytvořil i poměrně složitou aplikaci s jednočipem 80C552, která nám dodnes řídí doma ústřední vytápění. 80C552 je super procesor a umí toho hrozně moc, ale pro jednoduché aplikace je zbytečně složitý a velký, většinou potřebuje externí ROM a RAM. Jednoduše na drobné věci se nehodí a žádné složité už mne nenapadaly. Proto jsem dlouho s procesory nic nedělal, ale najednou jsem potřeboval vyzkoušet něco s MemPacem a ten obsahuje procesor Atmel ATtiny15L. No a když už jsem ho měl koupený a měl jsem zprovozněný jednoduchý programátor, tak mne to začalo zase na pár měsíců bavit a pak mne to vzhledem k jiným zájmům zase přešlo. Na této stránce jsem dal dohromady vše podstatné co jsem se za tu dobu naučil a i několik drobných konstrukcí, které jsem odladil v rámci "učení se" práce s tímto procesorem. Jde o konstrukce zajímavé pro modeláře. Většina není hardwarově dotažena do konce, ale vždy je součástí mnou vytvořený program a můžete si s tím hrát dál. Jinak předem upozorňuji - je skoro zbytečné se mne na cokoliv ohledně AVR procesorů ptát. Pamatuji si matně jen to, co je napsané na této stránce a pro každou podrobnější věc bych musel studovat katalogové listy a podobně. To po mně prosím nechtějte...
Programování AVR:
Na procesorech se mi vždy líbilo především to, že pokud si navrhnu zapojení a ono pak nedělá přesně to co potřebuji, musel bych u klasických součástek vzít do ruky pájku a zapojení změnit, zatímco u zapojení s procesorem mnohdy stačí jen přepsat program. Například si usmyslím, že LED-ka bude blikat místo aby trvale svítila. Normálně bych smolil nějaký multivibrátor a počítal kondenzátory. Takto jen přepíšu kousek kódu. Výsledkem je mnohdy to, že stejné zapojení může dělat jinou věc než k jaké bylo původně určeno.
V něčem se ale musí program vytvořit. Dnes k tomu většinou slouží PC. Programuje se většinou přímo v Assembleru, případně v C, v Pascalu nebo Basicu. Já programuji většinou v Assembleru. Je to sice nejpracnější, ale kód je nejkratší a mám vše pod kontrolou.
Chod takto navrženého programu je možné kontrolovat přímo v aplikaci po naprogramování procesoru. To je asi nejhorší metoda, protože pokud něco nejede, tak obvykle vůbec a přitom prakticky nejde zjistit proč. Pak jde použít obvodové emulátory. To je zařízení, které zjednodušeně řečeno z PC udělá požadovaný typ mikroprocesoru. Do patice procesoru se místo skutečného procesoru zasune kabel vedoucí z počítače. Aplikace se pak chová jako kdyby skutečný procesor osazen byl a přitom lze na monitoru sledovat co se uvnitř "mikroporcesoru" a celé aplikace děje. Tato varianta je ideální a práce jde velmi rychle od ruky, ale obvodový emulátor je velmi drahá věc. Asi nejvíce používanou možností je použití simulátoru. Chod programu se sleduje na monitoru bez fyzického propojení s aplikací a jeho činnost se dá ovlivnit nastavováním různých příznaků. Například zapíšeme na nožičku log1 a sledujeme co program dělá, pak tam ručně dáme log0 a zase sledujeme co se děje. S trochou nepohodlí tak jde zkontrolovat a odladit prakticky vše podstatné. Na závěr se program vypálí do obvodu a vyzkouší se naostro. Pro procesory AVR Atmel se mi velmi osvědčil simulátor z AVR studia 4.0. AVR studio jde zdarma stáhnout přímo z internetu Atmelu a je v něm velmi obsáhlý help s popisem instrukcí Assembleru, je možné v něm program napsat, přeložit, simulovat a je tam i podpora pro připojení různých originálních obvodových emulátorů a programátorů.
Já jsem žádný originál hardware od Atmelu neměl, takže jsem z AVR studia používal jen překladač a simulátor, ale i tak se dala spousta věcí udělat. Vzniklý kód je pak nutno do obvodu dostat programátorem. Lze použít třeba i AVReal a třeba i s tím nejjednodušším interface. Namaloval jsem pro vás zapojení:
 |
Diody stačí jakékoliv křemíkové, keramický blokovací kondenzátor je vhodný a měl by mít kapacitu 100k. Vodiče mezi LPT portem a paticí pro procesor by neměly být příliš dlouhé. Toto zapojení je samozřejmě použitelné pouze pro 8-mi vývodové procesory AVR. Pro vícevývodové by se muselo předělat, ale princip je stejný. Při programování je nutné použít přepínače -ap -o0. První zajistí, aby programátor na nepoužívané vývody LPT portu přívedl +5V, takže pak není potřebné externí napájení a procesor je napájen přímo z portu. Druhý programátoru oznámí, že není použit krystal a programátor si musí vystačit bez něj. Nikdy mne to nezklamalo, ale přesto jsem si pořídil programátor PonyProg. Práce s ním byla díky mnohem komfortnějšímu obslužnému software přece jen příjemnější a umí toho naprogramovat víc než jen AVR procesory. Pokud vás ale zaujme některá níže popsaná konstrukce a potřebujete si naprogramovat jeden procesor, klidně to udělejte AVRealem. Je zdarma a funkční.
ATtiny15L a jeho kalibrace:
Procesor ATtiny15L je velmi jednoduchý a většinou se u něj nepoužívá pro řízení vnější oscilátor, ale oscilátor vnitřní. Ten ovšem neoplývá zrovna přesností. Protože však mnoho aplikací alespoň trošku přesný kmitočet potřebuje, dá se kmitočet oscilátoru zkalibrovat zapsáním hodnoty do registru OSCCAL. Čím vyšší hodnota se zapíše, tím rychleji oscilátor kmitá. Velmi hrubým měřením jsem zjistil, že při hodnotě 0 kmitá oscilátor na kmitočtu asi 1,2MHz a při hodnotě 255 asi na kmitočtu 2,5MHz. Ovšem hodnoty jsou to jen přibližné a kus od kusu se dost liší. Jak tedy zajistíme, aby oscilátor kmital přesně na jmenovitém kmitočtu 1,6MHz?
Každý ATtiny15L má od výroby zapsánu přesně zjištěnou kalibrační konstantu na třech místech. V posledních dvou Bytech programové paměti, v posledním Byte EEPROM a v "signature adress space". První dvě místa nejsou příliš spolehlivá, protože je můžeme velmi snadno přepsat. "Signature adress space" je však jistota. Tam by kalibrační konstanta měla být k dispozici trvale.
Tuto hodnotu musíme co nejdříve po RESETU přepsat do registru OSCCAL. Problém je, že procesor neumí přímo číst ze "signature adress space". Alespoň jsem nepřišel na to, jak to udělat. Umí však číst z paměti programu. Stačí tedy zajistit, aby na libovolném místě programové paměti byla hodnota stejná, jako zjištěná kalibrační konstanta, a do programu dáme kus kódu, který z tohoto místa hodnotu přečte a zapíše jí do OSCCAL:
Následující kód udělá přesně tuto činnost a předpokládá, že hodnota bude na adrese 0x3FF:
ldi ZH, 0x03 ldi ZL, 0xFF lpm out OSCCAL,r0
Pokud nyní nastavíte programátor tak, aby před vypalováním programu přečetl kalibrační konstantu ze "signature adress space" a zapsal jí do programu na adresu 0x3FF, máte vyhráno. Umí to například PonyProg a já jsem to běžně využíval. Po připojení napájecího napětí se procesor rozjede na kmitočtu asi 1,2MHz a po provedení uvedeného kódu se rozjede kmitočtem 1,6MHz s přesností lepší než 1%.
Pípák:
Pípák mělo být jednoduché zařízení pro dohledání ztraceného modelu. Oproti běžně dostupným zapojením a hotovým výrobkům se však nehlídá pouze ztráta impulsů (tedy vypnutí vysílače), ale i jejich šířka. Pípák je tak možné zapnout na dálku vysílačem třeba i během letu. Pípák je díky tomu použitelný i s přijímačem PCM a navíc jde spolehlivě spustit i při kmitočtové "tlačenici", kdy normální přijímač na vypnutí vysílače zareaguje tím, že se chytne všude přítomného šumu, začne divoce cukat servy a hrozí jejich poškození o dorazy. Obyčejný pípák se v tomto případě nerozeběhne, protože impulsů z přijímače má habaděj. Mimochodem. Vzpomínáte, že v každém návodu k RC soupravě hned na jedné z prvních stran je napsáno, že se má první zapínat vysílač a pak teprve přijímač a při vypínání obráceně? A pak se začnou prodávat věci, které se aktivují vypnutím vysílače při zapnutém přijímači. Trošku paradoxní přístup výrobců ne?
Za řídící obvod jsem zvolil ATtiny15 a protože ten měl spoustu dalších nevyužitých nožiček a obsahuje poměrně přesný analogový komparátor, dodělal jsem i hlídání napájecích zdrojů. Jako zdroj zvuku jsem použil sirénku a protože její zvuk se mi nezdál dostatečně hlasitý, je napájena přes měnič napětí. Díky tomu je zapojení zdánlivě složité, ale opravdu jen zdánlivě. Prototypový kus vypadal takto:
Poslední verze pípáku s programem V1.3 umí následující:
- Po zapnutí krátce pípne a následně blikne LED zeleně a červeně. Počet bliknutí se řídí číslem verze a podverze programu. Například verze V3.5 by blikla 3x zeleně a 5x červeně. Pak dvakrát krátce pípne a nyní se již pípák přepne do normálního pracovního režimu. Celá tato úvodní procedura slouží k otestování základních funkcí zařízení, signalizaci zapnutí přijímače a současně k signalizaci verze software.
- Měří vstupní servo impulsy. Impulsy širší jak 2,2ms a užší jak 0,8ms ignoruje a chová se stejně jako by chyběly. Pokud impulsy chybí nebo je impuls v toleranci, ale je delší jak 1,5ms, sirénka přerušovaně pípá.
- Měří napájecí napětí. Pokud je napětí vyšší jak 4,3+/-0,1V (nebo po proškrábnutí zkratu u odporu R2B 4,6+/-0,1V), svítí LED zeleně. Pokud ja napětí nižší, svítí LED červeně. Pokud je napětí nižší déle jak 4sec, začne sirénka pípat. Pokud je pokles ještě dlouhodobější nebo opakovaný, ale po odlehčení je napětí zase v normě, pak LED zeleně bliká místo aby trvale svítila. Tak signalizuje, že sice právě teď je napětí v pořádku, ale během letu tomu tak nebylo.
Schéma zapojení:
Si můžete prohlédnout tady
Plošný spoj:
Je navržen v Eagle, má průměr 23,5mm a počítá s osazením součástkami SMD. Díky tomu je velikost celého pípáku stejná jako sirénky KPE222, pouze je celek o něco vyšší.
Použité součástky:
IC1 - procesor ATtiny15L s programem D1 - dvoubarevná LED BHG234 D2 - dioda BAS85SMD T1 - tranzistor PNP BC857C R1 - odpor 220R R2A - odpor 3k 1% R2B - odpor 300R R3 - odpor 1k2 1% R4 - odpor 470 C1 - keramický kondenzátor 100n C2 - elektrolytický kondenzátor 1uF/25V L1 - tlumivka 680uH SP1 - sirénka KPE222A Servokáblík
Přibližně v jednom případu z deseti vyjde hranice pro signalizaci nízkého napětí mimo stanovenou toleranci. V tom případě je nutné provést korekci paralelním připojením odporu k R2A nebo R3. Hodnotu těchto korekčních odporů lze získat výpočtem nebo připojením trimru a po nastavení změřením jeho odporu. V praxi pokud je napětí vyšší jak 4,4V stačí připojit paralelně k R2A odpor 47k. Pokud je napětí nižší jak 4,2V, připojíme k R3 odpor 15k.
Kompletní podklady pro výrobu včetně souborů se schématem a plošným spojem pro Eagle a výpisem programu si můžete stáhnout tady
Hotový pípák:
Vzhledem ke značné pozornosti, kterou tato konstrukce vzbudila, jsem ji dotáhl do konce a "prodával". Uvozovky jsou tady záměrně, protože cena 299,-Kč, stačila tak s bídou na pokrytí ceny součástek. Hotových pípáků jsem prodal asi dvě stovky, ale dnes už je nevyrábím. Za uvedenou cenu s tím byla jen spousta práce a za více peněz nebyl zájem.
Pro zajímavost se můžete podívat, jak takové hotové pípáky vypadaly:
A pokud vás to opravdu zajímá, tak tady je ke stažení původní návod
Dvojitý přepínač s pamětí:
Tato ,,konstrukce" je v podstatě jen návrh a vznikla na základě přání kamaráda, který si
ji snad dotáhl do konce. Jde o řídící část přepínače s pamětí ovládaného RC
soupravou. Obsahuje čtyři výstupy. Dva mají paměť. Vychýlením kniplu na jednu
stranu se na příslušném výstupu VxRAM objeví logická nula a vrácením kniplu zpět
a novým vychýlením na stejnou stranu se na stejném výstupu objeví logická
jednička. Totéž dělá druhý výstup, pouze se kniplem hýbe na opačnou stranu. Jako
mez přepnutí je zvolena úroveň asi 80% výchylky. Aby bylo akceptováno další
přepnutí, musí se knipl nejdříve vrátit na úroveň menší jak asi 40% výchylky.
Další dva výstupy nemají paměť. Pokud je výchylka větší jak 80%, příslušný
výstup Vx je v logické nule, jinak v logické jedničce. Možnosti využití jsou
různé, musíte si však vyřešit hardware spínačů a navrhnout plošný spoj. Princip
funkce je velmi jednoduchý a je popsaný přímo ve výpisu programu. V zásadě je
využito externí přerušení, které vzestupnou hranou vstupního signálu spustí
čítač. Sestupná hrana stejného signálu čítač opět zastaví a zjistí, kolik
čítač stihl napočítat. Tuto hodnotu uloží do registru. Pokud čítač přeteče
(což může nastat, pokud příjde vzestupná hrana a sestupná ne), pak se automaticky
zastaví. Jakmile pak sestupná hrana přece jen příjde, pokračuje měření dál.
Poslední naměřená hodnota šířky impulsu je samozřejmě nesmyslná a proto se
ignoruje, stejně jako impulsy širší jak 2,2ms nebo užší jak 0,8ms. Výhodou tohoto
řešení je, že se programátor nemusí o nic starat a stačí pouze v hlavním programu
přečíst registr a na základě hodnoty v něm obsažené se zachovat.
Tady je k dispozici balíček se zdrojovým programem v Assembleru a
přeložený HEX soubor pro programátor.
Schéma zapojení na kterém jsem program zkoušel
je vidět na obrázku a je velmi jednoduché. Abych mohl sledovat
práci spínače, připojil jsem k výstupům katody LED diod a jejich anody jsem přes
odpory 220ohmů zapojil do Ucc. V praktickém použití samozřejmě místo LED zapojíme
tranzistory, spínající požadované obvody:
Neproporcionální servo:
Protože jsem si chtěl vyzkoušet funkci PWM pro
řízení serva, navrhl jsem následující zapojení. Šlo jen o pokus, ale výsledný
"produkt" by v nenáročných případech šlo použít v praxi. Vytvořený
program umožňuje nastavit servo do jedné z asi 20-ti poloh a ovládací impulsy pro
servo se opakují s kmitočtem zhruba 73Hz, tedy znatelně častěji než je běžných
50Hz. Toto malé rozlišení a vyšší kmitočet je daní za jednoduchost programu,
který používá časovač T1 s dělícím kmitočtem CK/64 přepnutý do PWM režimu. Po
každém přetečení časovače nastane přerušení, ve kterém se nastaví obsah I/O
registru OCR1A a tedy žádaná poloha serva. Pokud by měl být kmitočet dodržen a
rozlišení serva by mělo být vyšší, musel by se za chodu programu v přerušeních
nastavovat různý dělící kmitočet časovače, nastavovat předvolby pro čítač a
nahazovat mód PWM podle toho, jestli se zrovna měří šířka impulsu nebo kmitočet.
Pak by ovšem byl program natolik složitý, že by asi bylo lepší použít časovač
jen pro generování kmitočtu 50Hz a impuls pro servo tvořit ručně smyčkou v hlavním
programu. Na celém programu je zajímavé pouze to, že hlavní program tvoří
nekonečná smyčka a nic nedělá. Vše je obslouženo v přerušeních. Řídící
signál z přijímače je čten naprosto stejně jako v dvojitém
přepínači s pamětí nebo pípáku.
Popis funkce:
Program po zapnutí nastaví servo do neutrálu a
pak měří šířku vstupního signálu. Příliš široké nebo úzké impulsy považuje
za rušení a ignoruje je. Pokud je vstupní impuls užší než -80(40)%, přesune servo
do polohy -80(40)%, pokud je širší jak +80(40)%, přesune servo do polohy +80(40)%.
Přepínači je možné ovlivnit chod programu takto:
- přepínačem 1 je možné snížit výchylky serva
asi na polovinu, takže se pak servo přestavuje místo mezi polohami +/-80% jen mezi
polohami +/-40%.
- přepínačem 2 je možné citlivost na vstupní
signál snížit asi na polovinu, takže se jako mez překlopení bere místo +/-80%
výchylky kniplu jen +/-40% výchylky kniplu.
- přepínačem 3 je možné zrušit hlídání polohy
kniplu +80(40)%. Pak je servo trvale v poloze +80(40)% a pouze pokud je vstupní impuls
užší jak -80(40)%, zaujme servo polohu -80(40)%.
Je samozřejmě možné polohy přepínačů
kombinovat. V praxi je možné vynechat přepínače i odpory a podle požadované funkce
příslušné piny procesoru připojit trvale na VCC nebo GND. Je také možné změnou
konstant v programu nastavit jiné polohy serva nebo kniplu. Pak je možné například
přesouvat servo z polohy +60% do polohy +100% na základě polohy kniplu -50% a +70%.
Stačí opravdu jen přepsat konstanty, přeložit program a nahrát ho do procesoru.
Vzhledem k tomu, že procesor není řízený krystalem, ale vnitřním RC oscilátorem,
je toto zapojení citlivé na změnu napájecího napětí. Při změně napájení ze 4
na 5V se poloha serva změnila asi o 2-3%. Ale psal jsem od začátku, že jsem si chtěl
jen něco zkusit a uznejte sami, že je hezčí, když se hýbe servo, než když svítí
LED-ka.
Zdroják programu v assembleru a přeložený HEX
soubor najdete zde. Zdroják nemá žádné komentáře.
|