Vymyslel jsem elektroniku k servu , kterým se dá ovadat přestavník nebo jiné podobné polohovací zařízení. Chtěl bych popsat zařízení, které je mnohem lepší než klasické modelářské servo, teda aspoň pro železniční modeláře, kteří nejsou spokojeni s původním výrobkem a mají k němu nedůvěru. Ona ta nedůvěra je celkem oprávněná, protože modelářské servo má pro nás spoustu nevýhod. Jako třeba, chvění při nestabilitě napájení, zakmitnutí při zapnutí napájení, obrovská síla, velká rychlost přestavení, citlivost na okolní rušení a ještě pár maličkostí, na které si teď nemůžu vzpomenout. Celkově se jedná o velmi jednoduchý výrobek a tak ho zkusím prezentovat jako stavební návod
Zatím jsem to vymyslel pro obycejné soucástky, ale myslím, že se casem najde nekdo, kdo to prekope na SMD a potom by se to dalo zabudovat prímo do serva a vycnívaly by jen ty dva napájecí kablíky pro DCC. Ono se vlastne nic nezmení, programové vybavení a soucástky zustanou typove stejné, jen to bude v SMD. Já už na to proste nemám oci. Ale i tak jsem to udelal dost malické, 46 x 25 x 11 mm.
Schéma:
Je to vlastne “skoro“ lokomotivní dekodér bez funkcí, pro které nemá Tiny 85 místo.
Zkusím to popsat :
Vstup DCC je na Graetz mostík, kde se DCC usmerní a na stabilizátoru se nastaví napájení, na 5V. Taky je tam odbocka na procesor, který precte a vyhodnotí signál DCC. Na základe prijmutého príkazu, procesor posle príkaz na prestavení serva. Ochranné diody na výstupu výkonového operacního zesilovace chrání pred napetovými špickami a odpor mezi výstupy zmenšuje zákmity , které vznikají pri ovládání indukcní záteže, taky slouží jako zátež pro ACK pri odpojeni motorku. Odpory 3j3 slouží na ochranu proti chodu nakrátko, kdy zabrání vypálení operacního zesilovace. Je nutno osadit takovou hodnotu, aby se neprekrocila hodnota 1.5 A, která je pro zesilovac fatální. Pokud je po usmernení napájení 13V, tak 13 / 6,6 + 3 = 1.5 A. Odpory trošku omezují výkon a rychlost, ale to nám až tak nevadí, protože to potrebujeme. Je nutné použít odpory na aspon 0,6W, kdy pretížení po dobu prestavování naprosto nevadí.
Vývod 1 je RESET a muže být nezapojen, ale pokud bychom chteli další pin, tak je možné ho naprogramovat, ale má to jeden hácek, potom se nedá nic zmenit nebo upgradovat. Zvlášt u SMD je to dost velký problém.
Servo samotné se musí upravit a to tak, že se odstraní elektronika a vyvede se 5 drátu , 2 napájení od motorku a 3 od potenciometru. Zarízení jsem navrhnul tak, aby vubec nezáleželo na hodnote potenciometru.
Výstup bežce potenciometru je priveden na pin PB2 (ADC1) , kde se vyhodnotí uhel natocení. Další dva vývody potenciometru se pripojí na +5V a „zem“ napájení. Vývody motorku se pripojí na JP5, kde je výstup PWM výkonového zesilovace.
Výstup jediného volného pinu je na relé, které prepíná srdcovku a které má navíc jeden prepínací trojpin, treba na indikaci polohy nebo muže prepínat návestidlo mezi dvema polohami. Protože cesticka medi je tenoucká, doporucuji, pripájet drátek 0,5mm po cele délce od výstupu relé, po konektor. Samozrejme, pokud tam zapojíme LEDku, tak je to zbytecné.
Pri zapojení na programovací kolej MUSÍ být odpojen motorek, stací odpojit jeden drát. Odpoved ACK impulsem zabezpecí odpor 270O na výstupu L272. V prípade, že necháte zapojen motorek, muže odejít koncový stupen v ctecce DCC.
Princip a popis funkce:
Signál DCC obsahuje informaci o adrese a príkaz. Po prijmutí správné adresy se vykoná príkaz, který je v bitu.0 , druhého bajtu. Je to tzv párové rízení které nepotrebuje bit.3 druhého bajtu, protože zarízení se vypíná samo. Zarízení umí prijmout príkaz a podle adresy prestaví pomocí PWM servo a vypne ho na základe ctení ADC, kde se vyhodnotí úhel natocení serva.
Jak to funguje :
Na tomto jednoduchém zarízení se dá celkem snadno popsat principy ovládáni DCC a taky trošku okolo programování. Snad to nekoho chytí a bude pokracovat. Není celkem pravda, že všechno už bylo vymyšlené, vývoj jde neustále dopredu a co si sami vyrobíme nebo vymyslíme, to už nám nikdo nevezme. Problém ovšem bude, pokud nepoznáte napríklad binární matematiku a spoustu dalšího. Taky se nebudu zabývat nejnižší vrstvou, jak jsou tvoreny bity „1“ a „0“. Pokud nevíte, treba dostudovat normy NMRA a všelico jiné. To platí pro ty, kterí nechtejí být odkázáni na komercní veci a ostatní nech si to koupí hotové. ;-)
Paket DCC pro príslušenství vypadá takto : {preamble} 0 10AAAAAA 0 1aaaCDDD 0 EEEEEEEE 1
Preambule je indikátor zacátku paketu, protože práve u sériových signálu je problém urcit , kdy vlastne prenos zacíná. Proto musí být na zacátku aspon 10 bitu v hodnote „1“. Pak následuje START bit, který musí být v hodnote „0“. Následuje adresový byte, kde je zapsána adresa s bity A0 až A5.
Ono je to trošku zavádející nepravda, ale za to nemohu, je to bordel zvaný „zpetná kompatibilita“ a nebude to jediné, na co budete, pri prípadném navrhování, nadávat. Takových vecí je tam spousta a nejsou zrovna dobre popsány.
Pak následuje zase START bit v hodnote „0“ a potom datový byte, kde je zbytek adresy A6 – A9, které jsou ovšem invertovány, aby to nebylo až tak jednoduché. Tato vyšší adresa je na pozici b.4 – b.6, v datovém byte. Nižší bity se delí na tzv párové rízení, které je pozustatek na doby minule, teda magnetické prestavníky, které potrebovaly dva rozdílné príkazy na ovládání a ješte navíc casove posunuté zapnutí a vypnutí proudu do jednotlivých vinutí prestavníku. Je to navrhnuté tak, že bit.0 ovládá príkaz, teda hodnota znamená bud rovno „0“ nebo do odbocky „1“. Toto je vlastne jediný bit, který je skutecne príkazový a urcuje, co se má vykonat. Další dva bity urcují, která ze ctyr vyhybek (nebo neco jiné), se vybere pro vykonání príkazu. Jsou to vlastne adresy, které se pridávají pred ty predchozí. Teda jako -1, -2, -3, -4. Nebo se to muže celé posunout a potom je adresový prostor A0 až A10. Já používám tento zpusob a vetšina programátoru asi taky. A ješte navíc jsou invertovány bity A0,A1,a D, kdy hodnota “000“ znamená adresa “7 a odbocení “ a hodnota “111“ znamená adresa “0 a rovno“. Takže je to celkem dobre zamotané a zacátecník se muže picnout. To aby bylo jasné, proc jsem psal, ze to je zavádející nepravda.
---
Takže ve skutecnosti vypadá paket DCC pro príslušenství významove takto :
{>10 x 1} <0> ; <1, 0, A7 , A6 , A5 , A4 , A3 , A2 > ; <0>; < 1 , /A10, , /A9 , /A8 , 1 ,/A1, /A0 , /D> ; <0> ;
Je to porádný zmatek, ale nám už to tak neprijde, naucili jsme se. Ale pokud to zacnu nekomu vysvetlovat, tak mne asi po deseti minutách virtuálne opluje a zmizne. Zvlášt, když je binární matematika pro nej absolutne neznámá a tak se nemá ceho chytit.
Paket DCC, který má stejnou adresu jako má ovladac, zpusobí, že se servo zacne prestavovat príslušným smerem a rychlostí, podle bitu.0 v druhém bajtu. Soucasne se zacne natácet potenciometr a tím se mení napetí na vstupu ADC prevodníku. Pokud napetí dosáhne správné hodnoty, servo se zastaví.
Všechny údaje jsou uloženy v EEPROM pameti, které se porovnávají s príchozím paketem a reálným stavem.
Použité soucástky :
Servo je klícová soucástka a opravdu nedoporucuji použít to nejmenší a nejlacinejší. Hlavne z toho duvodu, ze tam jsou montovány motorky s velmi nízkým odporem (2 - 4O), které mají obrovský startovací proud a celkem bežne si potáhnou 2A. Vetší serva mají motorky s odporem nad 4O a nejsou až tak kriticky nenažraná. Tyto malé serva lze použít, ale doporucuji osadit ochranné odpory o 2 - 4 O vetší, aby se ochránil zesilovac.
L2722 DIP8 je klasicky (ne MOSFET) výkonový operacní zesilovac, který je celkem vhodný na toto použití. Existují sice jiné H-Bridge zesilovace, ale ty jsou asi 2x dražší a neprinášejí výraznou pridanou hodnotu. Je tu jedna výnimka a to SN754410, který obsahuje dva zesilovace za srovnatelnou cenu, ale zas je 2x vetší.
Atmel Atiny25/45/85 je mikropocítac, který je na toto vynikající, i když pár vývodu mu urcite chybí ;-). Opravdu by mu stacilo jen dva vývody pridat a byl by to super obvod. Je až s podivem, co se do tak malého obvodu dá narvat. Je to silný stroj a dobre se s ním pracuje. Odpory a kondenzátory jsou standard a nepotrebují komentovat, krome vyhlazovacího kondíku za Graetzom, který musí mít kapacitu aspon 330nF. Nedoporucuji tantal nebo elektrolyt, nejlepší je keramika. Odpory jsou 0.4W, krome výstupu na motorek, kde jsou 0.6W.
Relé je 5V obycejné (180 O), nedoporucuji bistabilní, protože potom není možné udržet soulad mezi príkazem a realitou. Pridávám do série odpor 12 - 33O z duvodu ochrany a zmenšení odberu. Treba odzkoušet, kdy relé ješte spolehlive spíná.
Plošný spoj je navrhnutý systémem delících car, protože je odolnejší na pájení a je urcen na vyšší proudy.
Pridal jsem i kresbu v systému spojovacích car, ale tu moc nedoporucuji.
Tyto obrázky jsou pouze informativní a nejsou vhodné na kopírování. Pokud si to nekdo bude chtít postavit, pošlu mu návrhy prímo v EAGLE programu, nebo samotný plošný spoj.
Ty dvojtecky jsou urceny na pripájení prívodních drátu, kdy se zakroutí drát do ocka a vývody se zasunou do dírek a pripájejí. Má to dve výhody, nenicí se plošný spoj pri opakovaném pájeni a zároven nemusíte otácet plošný spoj a používat odsávacku. Pásky po bocích jsou urceny na montážní otvory. Konektory pro servo jsou otoceny o 90st. , teda vycnívají do boku.
Skládání a oživování :
Je nutné dukladne zkontrolovat plošný spoj, aby tam nebyly mostíky medi a je celkem vhodné plošný spoj vyleštit do zrcadla. Lépe se s tím potom pracuje a oživuje. Vyvrtají se dírky 0,8mm vrtákem a zacne se osazovat nejnižšími soucástkami. To proto, ze nám nebudou vypadávat pri otocení a pájení. Takže diody, odpory, objímky, Graetz, kondíky a nakonec stabilizátor. Je celkem vhodné použít mikropájku, ale šikovní to dokážou pistolovkou. Kdo není šikovný, tak na to rychle prijde. ;-)
Pred osazením zesilovace a uP durazne doporucuji pripojit DCC a zmerit napájení na stabilizátoru a neuškodí ani pár jiných bodu otestovat, ci tam je to, co tam má být. Já jsem starý profík a nepodcenuji to. I mne se obcas podarí studený spoj nebo zapomenu zaspájkovat vývod.
Pokud jste pracovali peclive, tak obvod pracuje na první zapojení. Jediné, co se muže stát, je opacný chod oproti snímání ADC, takže pokud se servo samo nevypne, je nutné prohodit bud vývody motorku nebo +/- potenciometru a to podle toho, co je snazší.
Cena ovladace komplet se servem :
Tiny85 = 1.7
L2722 = 1.7
Relé = 2.1
78L05 = 1.5
B80 = 1.5
Objímky = 1.5
Servo = 4.0
Dioda 5x = 0.9
Odpory = 0.6
Kondíky = 0,6
Plošák = 2.0
Kablíky = 0,9
------------------------
Cena = 19 Eur bez práce a energií ;-)
Pokud by byl zájem, zkusil bych kompletovat stavebnice soucástek za 20 Eur a poštovné. Pokud uvážíte, že cena treba jen prestavníku Tillig je 15 Eur bez žádné elektroniky, je to na pouvažování. Želva stojí taky 16 Eur bez niceho.
Mechanika :
Problém je mechanické zabudování, ale to musíte rešit tak-nejak všude. Uvažuji o bowdenu a lanku, kde na strane serva stací pripájet bowden a na druhé strane lustr svorka na nejaké podložce. Taky není problém ovládat vyhybku prímo ramenem serva, ovladac je naprosto stabilní a bez príkazu se nepohne. Jinak nápadu na mechanické provedení je spousta. Treba na modely.biz.
http://www.navestidla.cz/news/motoricky-prestavnik/ a další.
Jsem elektronik a nereším mechanické veci, Ale myslím si, že každý trošku schopný modelár si poradí, jak to osadit.
Výrobek predstavuje ovladac na digitální provoz pres DCC s malým odberem a vynikající stabilitou.
Vyrobil jsem asi 6 ruzných verzí, než jsem se dostal na to, co mi vyhovuje a myslím, že to bude dobré.
Nejlepší verze je úplne naspodu a vedle je položená 5-cent mince na porovnání velikosti.
Programové vybavení:
Napsání programu a odvšivení bylo celkem jednoduché, až na použití TIMER1, který je dost jiný, jako u jiných procesoru a tak jsem musel nastudovat datasheet, než jsem to zprovoznil k obrazu svému. ;-)
Dost jsem se obával prevodu ADC, ale hned první nápad se osvedcil a tak to bylo celkem jednoduché. Použití reference AVCC má výhodu v tom, že vubec nezáleží na napájení, protože jakákoli zmena se objevuje všude a tak se výsledek prevodu nemení. Jinak napsané, výsledek prevodu je imunní na kolísání napájení. Taky to má výhodu v tom, že je úplne jedno, jakou hodnotu má potenciometr, zapojený v servu. Teda predpokládám, ze nebudete potenciometr vymenovat a necháte tam puvodní, které mají rozsah od 5k do 22k.
Hodnoty v EEPROM :
0 = nedoporucuje se používat
1 = Adresa LOW – 7 bitu
2 = rychlost pohybu serva 5 - 80
7 = home-made -13
8 = verze -01
9 = adresa HIGH -7 bitu
10= levý doraz serva 20
11= pravý doraz serva 120
12= prepnutí srdcovky, polovicka mezi CV10 a CV11
29= univerzální dekodér na programovací koleji -128
Dávám zdrojový kód, upozornuji, že jakákoli zmena muže být fatální.
Program BascomBasic od http://www.mcselec.com/index.php?option=com_docman&task=cat_view&gid=99&Itemid=54
'------------------------------------------------------------------------------ '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ '------------------------------------------------------------------------------ 'program na obsluhu modelarskeho serva trochu jinak. Ridici signal je DCC a 'servo ma jen dve koncove polohy, ktera jsou definovana poteciometrem v servu 'a hodnotami v EEPROM 'Dalsi podrobnosti jsou uvedeny u kazdeho prikazu. '********* platne ***************** $regfile = "attiny25.dat" 'chip = 1E930B $crystal = 8000000 $hwstack = 40 $swstack = 40 $framesize = 28 'rozmisteni pinu: 'portb.0 = prijem DCC, portb.1 = rele, portb.2 = vstup potenciometru 'portb.3 = vystup PWM, portb.4 = vystup PWM Portb = &B00010 Ddrb = &B11010 Dim Dcc(6) As Byte 'prijem DCC, az 6-byte paket Dim Acc As Byte 'vseobecne Dim Chk As Byte 'kontrolni soucet pro prijem Dim Pream As Byte 'hodnota preambule Dim Longpr As Byte 'hodnota dlouhe prambule Dim Rada As Byte 'ukazovatko pro cteni DCC Dim Druh As Byte 'druh paketu 3,4,5,6 byte v paketu Dim Work As Byte 'vseobecny Dim Bcc As Byte 'vseobecny Dim Ccc As Byte 'vseobecny Dim Adral As Byte 'buffer pro servo Dim Adrah As Byte 'buffer pro servo Dim Aadc As Byte 'ulozeni hodnoty z ADC Dim Respak As Byte 'pocet reset-paketu Dim Nc As Eram Byte 'nedoporuceno pouzivat Dim Adrl As Eram Byte At 1 'LOW adresa, podle normy NMRA Dim Rych As Eram Byte At 2 'rychlost pohybu serva Dim Adrh As Eram Byte At 9 'HIGH adresa, podle normy NMRA Dim Dor1 As Eram Byte At 11 'levy doraz serva Dim Dor2 As Eram Byte At 12 'pravy doraz serva Dim Dor3 As Eram Byte At 13 'prepnuti rele, polovice mezi Dor1,2 Dim Voln As Eram Byte At 14 'volne Dim Po15 As Eram Byte At 15 'povoleni zapisu Dim Po16 As Eram Byte At 16 'pevna hodnota pro povoleni zapisu Dim Knf As Eram Byte At 29 'univerzalni dekoder = 128 'prijem DCC pres preruseni PCINT na pinb.0 On Pcint0 Hrana , Nosave Pcmsk = 1 Enable Pcint0 'nastaveni ADC pro cteni polohy pot. v servu pres pinb.2 Config Adc = Free , Prescaler = 128 , Reference = Avcc On Adc Zmerat Nosave Set Admux.5 Set Admux.0 Set Didr0.3 Enable Adc Start Adc 'pocitadlo casu pro DCC, pokud pretece, restart nacitavani DCC Config Timer0 = Timer , Prescale = 64 On Ovf0 Moc Nosave Enable Ovf0 'ovladani PWM pro motorek serva. 125nS x 65536 = 122Hz je kmitocet PWM Config Timer1 = Timer , Prescale = 256 On Ovf1 Casa Nosave On Oc1b Casb Nosave Ocr1b = Rych Enable Ovf1 Enable Oc1b 'ulozeni dorazu do bafru Adral = Adrl Adrah = Adrh Enable Interrupts 'gpior0.0 = priznak hotoveho paketu 'gpior0.1 = NC 'gpior0.2 = pohyb serva doleva 'gpior0.3 = pohyb serva doprava 'gpior1.0 = priznak pulbit "0" 'gpior1.1 = priznak pulbit "1" '------------------------------------------------------------------------------ '------ hlavni program -------------------------------------------------------- '------------------------------------------------------------------------------ Do 'zpracovani paketu DCC sbic gpior0,0 rcall prijmi 'vypinani pohybu serva je automaticke, dosazenim nastavene krajni polohy If Aadc > Dor2 Then Reset Gpior0.3 End If If Aadc < Dor1 Then Reset Gpior0.2 End If 'prepinani srdcovky a zpetneho hlaseni pres rele, pomoci Dor3,ktere by melo 'byt nastavene na polovicku mezi Dor1 a DOR2. If Aadc > Dor3 Then Set Portb.1 Else Reset Portb.1 End If Loop '------------------------------------------------------------------------------ '----- podprogramy ------------------------------------------------------------ '------------------------------------------------------------------------------ '--------------------------------- Prijmi: 'nulovani priznaku hotoveho paketu Reset Gpior0.0 'kontrola CHEKSUM pomoci EXOR celeho paketu DCC, 'v DRUH je pocet bajtu v paketu. Paket muze byt 3-6 bajtovy Chk = 0 For Acc = 1 To Druh Chk = Chk Xor Dcc(acc) Next Acc If Chk <> 0 Then Return 'vysledek musi byt 0 'pocitani reset paketu, pokud jiny paket, respak = 0 If Dcc(1) = 0 Then If Dcc(2) = 0 Then Incr Respak Return End If End If 'zpracovani paketu podle jeho delky, ktera je ulozena v promenne DRUH Select Case Druh Case 3 : Gosub Troj Case 4 : Gosub Ctyr Case 5 : Gosub Pet Case 6 : Gosub Sest End Select Druh = 0 'nulovani druhu paketu Respak = 0 Return '----------------- 'preamble 0 10AAAAAA 0 1AAACDDD 0 EEEEEEEE 1 'testovani adresy a porovnani s EEPROM na pozici 1 a 9 'testuje se cely bajt i s prednastavenymi bity. Troj: 'kontrola adresy A0-A5 If Dcc(1) <> Adral Then Return 'kontrola adresy A6 az A8 + parove rizeni Work = Adrah And 254 Acc = Dcc(2) And 254 If Work <> Acc Then Return '------------------------------ 'zapnuti PWM na pohyb vpravo a vlevo. 'Je pouzite PWM trosku jinak, nez je zvykem. Zakladni stav je "0" na obou 'vystupech pro L272. Cas Oc0b nahazuje prislusny port a Ovf0 ho shazuje. 'Proto nemusim prepocitavat hodnotu PWM pro kazdy chod, oba jsou stejne. 'Nahazujem / shazujem oba smery,protoze neni zarucene,ze prijde, za chodu, opacny prikaz Work = Dcc(2) If Work.0 = 0 Then Set Gpior0.3 Reset Gpior0.2 Else Reset Gpior0.3 Set Gpior0.2 End If Return '--------------------------------- 'Long-preamble 0 0111CCAA 0 AAAAAAAA 0 DDDDDDDD 0 EEEEEEEE 1 'je to bezadresovy prikaz, pokud prijde, musi se vykonat. 'Je to na programovaci koleji. '--------------- Ctyr: 'musi byt dlouha preambule If Longpr < 20 Then Return 'musi byt aspon tri reset pakety If Respak < 3 Then Return Respak = 0 'zde se to rozdeli podle bitu CC v prvnim byte Acc = Dcc(1) And &B1111_1100 'maska na bity A9,A8 If Acc = 116 Then Gosub Verify '0111_0100 = 116 If Acc = 120 Then Gosub Bitmani '0111_1000 = 120 If Acc = 124 Then Gosub Writes '0111_1100 = 124 Return '----------------- 'tu se verifikuje jeden byte EEPROM Verify: Gosub Tiny25 Readeeprom Work , Acc If Work <> Dcc(3) Then Return 'nezhoda, konec 'odpovida impulsem >60mA po dobu 6mS Odpoved: Set Portb.3 Waitms 6 'ACK Reset Portb.3 Return '----------------- Writes: 'zapis do EEPROM Gosub Tiny25 Writeeeprom Dcc(3) , Acc Goto Odpoved '----------------- Bitmani: 'pouzivam pouze verify bit, zapis jde pres write byte 'Long-preamble 0 011110AA 0 AAAAAAAA 0 1110dDDD 0 EEEEEEEE 1 Gosub Tiny25 Readeeprom Work , Acc 'vytahnuti dat z EEPROM Bcc = Dcc(3) And 7 'poradi bitu v bajtu Acc.0 = Work.bcc 'vycte bit Ccc = Dcc(3) If Ccc.3 = Acc.0 Then Gosub Odpoved Return '----------------------------- 'Tiny25 ma jen 128 byte EEPROM, pokud pouzijete vyssi typ,treba to zaREMovat Tiny25: Acc = Dcc(2) And 127 Return '---------------------------- 'preamble 0 0aaa_aaaa 0 1110CCVV 0 VVVVVVVV 0 DDDDDDDD 0 EEEEEEEE 1 '10AAAAAA + 1AAACDDD Pet: Acc = Adrl Bcc = Adrh Shift Acc , Left , 2 Acc.0 = Bcc.1 Acc.1 = Bcc.2 Reset Acc.7 If Dcc(1) <> Acc Then Return Return '---------------------------- 'pream 0 11aa_aaaa 0 aaaa_aaaa 0 1110CCVV 0 VVVVVVVV 0 DDDDDDDD 0 EEEEEEEE 1 Sest: 'neaplikovane Return '------------------------------------------------------------------------------ '------ podprogramy od preruseni ---------------------------------------------- '------------------------------------------------------------------------------ 'zmerilo hodnotu na PINB.2 a prevede na binární cislo a zapise do "Aadc" Zmerat: push r20 in r20,adch sts {aadc},r20 pop r20 reti '----------------- 'podle priznaku se nahazuje PWM Casa: sbic gpior0,2 sbi portb,3 sbic gpior0,3 sbi portb,4 Return '----------------- 'zde se zhazuje PWM. Casb: cbi portb,3 cbi portb,4 Return '----------------- 'pokud pretece TIMER0, tak je to brutal chyba. Neni asi DCC nebo je analog. Moc: push r20 ldi r20,0 'nemeni SREG sts {rada},r20 'zruseni nacitavani paketu DCC sts {pream},r20 pop r20 reti '----------------- 'obsluha prijmu DCC paketu 'nejdelsi prubeh trva 8uS Hrana: push r20 in r20,sreg push r20 push r21 push r22 push r23 'vytahneme hodnoty TIMER0 do r20 a nasledne vynulujeme TIMER0 in r20,tcnt0 ldi r22,0 'nova hodnota TIMER0 !out tcnt0,r22 'hodnoty z TIMER0 testujeme na "< 40uS < 70uS < 100uS < 3,2mS <" 'hodnoty 40uS - 70uS jsou pulbit "1" a hodnoty 100uS - 3,2mS jsou pulbit "0" 'hodnota nad 3,2mS je zakazana cpi r20,6 'test mensi nez 48uS brsh vetsi40 'vetsi nez 48uS !out tcnt0,r20 rjmp konec Vetsi40: cpi r20,9 'test vetsi nez 72uS brsh vetsi70 'vetsi nez 72uS rjmp puljedna 'pul bit "1" Vetsi70: cpi r20,12 'test na vetsi nez 96uS brsh pulnula 'pulbit "0" !out tcnt0,r20 rjmp konec 'mensi nez 96uS, pryc 'zde se zpracuji pulbity "0" Pulnula: sbic gpior1,0 rjmp nula cbi gpior1,1 'vynulovani protibitu "1" sbi gpior1,0 'nastaveni na druhy pulbit "0" rjmp konec 'zde se zpracuji pulbity "1" Puljedna: sbic gpior1,1 rjmp jedna cbi gpior1,0 sbi gpior1,1 rjmp konec 'zde se prijme "1" a rozdeli na prislusne byte anebo se pricte bit preambule Jedna: cbi gpior1,1 ldi r22,1 '"1"pro prenos bitu do bajtu lds r20,{rada} cpi r20,0 brne zpracuj lds r21,{pream} inc r21 sts {pream},r21 rjmp konec 'zde se prijme "0" a rozdeli se na byte nebo se zkontroluje prambule a pokud 'je delsi nez 10 bitu, tak se zapne nacitavani dalsich byte paketu DC 'je to vlastne START bit, pokud nasleduje za preambuli Nula: cbi gpior1,0 ldi r22,0 '"0"pro prenos bitu do bajtu lds r20,{rada} cpi r20,0 'test tvoreni paketu DCC brne zpracuj 'skok na tvoreni paketu DCC lds r21,{pream} 'nacteni preambule cpi r21,10 'test preambule na vetsi nez 10 "1" brlo spatne1 'je mene nez 10, chyba Sts {longpr},r21 'zapis preambule na dalsi pouziti >20 ldi r20,1 'jdeme na tvoreni paketu DCC sts {rada},r20 clr r20 sts {pream},r20 rjmp konec 'zde se skladaji jednotlive byte z osmi bitu. Mezi nimi je START bit, ktery 'musi byt "0". Pokud neni, je to chyba a cely paket se zahodi. 'protoze neexistuje pole bitu, musi se pouzit promenna RADA, ktera presne 'urcuje, kam se prijaty bit zaradi. Zpracuj: inc r20 sts {rada},r20 cpi r20,10 '2 az 9 = 8 bitu v prvnim byte brsh start1 'zde se zarotuje do byte DCC(1) prijaty bit lds r21,{dcc} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry rol r21 'zasunuti Carry do r21.7 sts {dcc},r21 'zapsani DCC do pameti rjmp konec Spatne1: rjmp spatne 'zde se vyhodnoti START bit mezi prvnim a druhym byte, musi byt "0" Start1: 'start bit mezi prvnim a druhym byte brne byte2 'pokud neni r22="0", neni to START bit cpi r22,0 'test prijateho bitu na "0" brne spatne1 'pokud neni "0", restart paketu rjmp konec 'v poradku, jdeme na dalsi bajt Byte2: cpi r20,19 '11 az 18 = 8 bitu v druhem bajtu brsh start2 'zde se zarotuje do byte DCC(2) prijaty bit lds r21,{dcc+1} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry rol r21 'zasunuti Carry do r21.0 sts {dcc+1},r21 'zapsani DCC do pameti rjmp konec 'zde se vyhodnoti START bit mezi druhym a tretim byte, musi byt "0" Start2: brne byte3 cpi r22,0 'test prijateho bitu na "0" brne spatne 'pokud neni "0", restart paketu rjmp konec 'v poradku, jdeme na dalsi bajt Byte3: cpi r20,28 '20 az 27 = 8 bitu v tretim bajtu brsh start3 'zde se zarotuje do byte DCC(3) prijaty bit lds r21,{dcc+2} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry Rol r21 'zasunuti Carry do r21.0 sts {dcc+2},r21 'zapsani DCC do pameti rjmp konec 'tady je to slozitejsi, prijaty bit "1" znamena konec trojpaketu a pokud je "0" 'tak se pokracuje na dalsi byte Start3: brne byte4 ldi r23,3 'trojpaket cpi r22,1 'test na START nebo STOP bit breq dobre 'test konce paketu rjmp konec 'neni to konec, jedeme na dalsi byte Byte4: cpi r20,37 '28 az 36 = 8 bitu v ctvrtem bajtu brsh start4 'zde se zarotuje do byte DCC(4) prijaty bit lds r21,{dcc+3} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry Rol r21 'zasunuti Carry do r21.0 sts {dcc+3},r21 'zapsani DCC do pameti rjmp konec 'tady je to slozitejsi,prijaty bit "1" znamena konec ctvorpaketu a pokud je "0" 'tak se pokracuje na dalsi byte Start4: brne byte5 ldi r23,4 'ctvorpaket cpi r22,1 'test na START nebo STOP bit breq dobre 'test konce paketu rjmp konec 'neni to konec, jedeme na dalsi byte Byte5: cpi r20,46 '37 az 45 = 8 bitu v patem bajtu brsh start5 'zde se zarotuje do byte DCC(5) prijaty bit lds r21,{dcc+4} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry Rol r21 'zasunuti Carry do r21.0 sts {dcc+4},r21 'zapsani DCC do pameti rjmp konec 'tady je to slozitejsi,prijaty bit "1" znamena konec petpaketu Start5: brne byte6 ldi r23,5 'petipaket cpi r22,1 'test na START nebo STOP bit breq dobre 'test konce paketu rjmp konec Byte6: cpi r20,55 brsh start6 'zde se zarotuje do byte DCC(6) prijaty bit lds r21,{dcc+5} 'nacteni byte DCC z pameti lsr r22 'vysunuti bit.0 z r22 do Carry rol r21 'zasunuti Carry do r21.0 sts {dcc+5},r21 'zapsani DCC do pameti rjmp konec Start6: ldi r23,6 Dobre: sbi gpior0,0 'konec paketu, nastaven priznak sts {druh},r23 'zapis druhu paketu do DRUH Spatne: clr r20 sts {rada},r20 'zruseni nacitavani paketu DCC sts {pream},r20 Konec: pop r23 pop r22 pop r21 pop r20 !out sreg,r20 pop r20 Return '------------------------------------------------------------------------------ $eepromhex $eeprom Data 0 ' adrl rych home ver adrh Data &H81 , 40 , 0 , 0 , 0 , 0 , 13 , 1 , &HF8 , 0 ' ld pd pr 15 16 Data 60 , 180 , 120 , 1 , 1 , 0 , 0 , 0 , 0 , 0 ' knf Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 128 , 0 $data
K tomuto článku nebol doposiaľ priradený žiadny komentár!