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!