TWI master-master, alebo softwarovy UART

potrebujem spravit komunikaciu medzi atmega16 a atemga168, obojsmernu. SPI pouzit nemozem, UART mozem pouzit len u jedneho mcu, ale oba mcu musia byt schopne prijat spravu od druheho mcu vo vopred nedefinovanom case. proste ked to pride, musi to mcu vediet prijat. Takze uvazujem o pouziti master-master TWI komunikacii, ale nenasiel som ziaden priklad, len diskusie. Neviem ci sa to pouziva a ci to bude spolahlivo fungovat. Druha moznost ma napada softwarovy UART s vyuzitim nejakeho externeho prerusenia alebo vyuzitim PCINT atmegy168 pre RX, pretoze nemozem stale len cakat na spravu. Nasiel som len kody pre arduino, a neviem ako spolahlive a tusim ani RX nefunguje cez prerusenie. Ak by mi poradil niekto, ktorou cestou sa vydat, budem vdacny. Pripadne overene postupy :slight_smile:

Sbernice TWI je totéž co sbernice I2C, jejíž autorem je firma Philips, dnešní NXP. Proto bych hledal informace u tohoto výrobce. Mám ješte staré katalogy Philips, kde je popsána sběrnice I2C v režimu multimaster. Moc se to nepoužívá a nejsem si jist, že je toho schopna TWI v AVRkách. Ani nevím k čemu by to bylo dobré. Když chce slave vyslat data k masteru, vyvolá přerušení na dalším drátu a master si je pak přečte. Naprogramovat SW master není problém, naprgramovat SW slave je velký problém.

Vytvořit SW UART transmitter jde docela dobře, pokud nejde o vysoké rychlosti. SW UART receiver je dosti značný problém. Kromě přerušení je zapotřebí timer. Pro velké rychlosti to není. Odhaduji tak do 9600b/s.

Místo ATmega16 mužeš použít ATmega164, který má 2 UARTy. Nebo můžeš použít USATR v režimu SPI na jedné straně a SPI na druhé, ale to z nějakého důvodu zavrhuješ.

dik za reakciu.
To ze aj slave moze iniciovat komunikaciu, tak to ma nenapadlo, resp. som o tom nevedel. Takze ani neviem ako to rozchodit. Komunikaciu TWI master-slave mam rozchodenu, popravde naucil som sa s tym robyt len 2 dni dozadu, ale mam to rozchodene len tak, ze master si pyta udaje. No ja potrebujem aby aj slave vedel poslat udaje bez toho aby si ich master pytal. Master ich potom posle dalej cez UART.

SPI som zavrhol, pretoze tie dva MCU neviem prepojit, nemam k pinom SPI pristup. to s cim pracujem su totizto MCU uzavrete v krabickach, a pristup mam len k niektorym pinom.

Tak asi ostanem pri TWI, a teraz musim vydumat, ako iniciovat komunikaciu zo stravy slejva, ale uz neviem kde hladat, lebo som popozeral kopec prikladov na TWI komunikaciu, no nic take som nevidel.

Ahoj…rád bych doplnil tento odhad o přesnější údaje, ke kterým jsem dospěl s vlastní konstrukcí.

SW UART dokáže na AVR-ku běhat na mnohem vyšší rychlosti…
ATMEGA88 s interním 8Mhz RC obvodem na 19200Bd
s externím 14MHz krystalem 38400Bd

I když jsem nezkoušl vyšší rychlosti jsem přesvědčen, že i 57600Bd to zvládne a to i bez použití rutin assembleru.

TWI by som sa nebal.

Nastavis najprv oba ako SLAVE. Ked nieco pride, tak sa to spracuje. Ak nie, tak nic :slight_smile:
Ak ma niekto potrebu vysielat, tak si prepne TWI na mastra a vysiela. Druha strana prijem poziadavku a reaguje na nu.

Ak by nahodou zacali obaja vysielat ako MASTER, arbiter Ti to nastavenim prislusneho bitu oznami. V takom pripade mcu z “nizsou prioritou” zacne drzat hubu a krok. Ked prijme spravu od Mastra, odvysiela svoju poziadavku. V celku velice jednoduche. Ak master nedostane ACK do stanoveneho casu, moze zacat vysielat odznova. Tento cas by mal byt samozrejme mensi ako cas drzania huby slejvom.

Vyhoda multimastra s AVR je prave v tom, ze bitiky TWI Ti vedia na hw urovni povedat, ze nastala kolizia na zbernici. K nicomu inemu to nie je.
Pricom ten master, ktory oslovuje slave z nizsou adresou sa presadi a “nevsimne si”, ze vysielal sucasne s inym mastrom. Ten master, ktory chce mat v nejakom okamiho na linke log. 1 a je tam log.0, predpokalda sa, ze ju tam presadil iny master, tak sa vysielanie prveho mastra prerusi a program je o tom informovany. Vsetko ostatne je potrebne osetrit softverovo. Obdobne funguje aj CAN, len tusim ze tam je vsetko osetrovane uz na hw urovni prislusnej periferie. Ale nemam osobne skusenosti, tak pisem len co viem zo studia literatury.

Kludne mozes pouzivat multimastra aj na UARTE. Tam sa akurat jednoducho nedozvies, ze Ti do vysielania zhodou okolnosti niekto kibicuje a “pokazit” sa mozu vysialania vsetkych v jednom case zucastnenych mastrov. V TWI sa aspon jeden prekomunikuje. Teoreticky sa moze prekomunikovat viac mastrov sucastne, ak by napriklad presne v jednom okamihu zatuzili po obsahu tych istych pamatovych buniek napr. z EEPROM a mali presne tu istu taktovaciu frekvenciu. Vsetky komunikacie by korektne presli. Samozrejme s rovnakymi datami :slight_smile:

Ak potrebujes vymienat udaje iba medzi mcu, pre vacsinu aplikacii plne vyhovuje system Master-Slave. MAster sa moze neustale dotazovat jednym bajtikom: “chces nieco?”, alebo sofistikovanejsie “co mas nove?”

Zdrzanie komunikacie v pripade dokolecka dotazovania je prakticky minimalne, komunikacia je presne deterministicka a netreba ladit zaludnosti typu “obcas to blbne, asi koliziami ale mozno aj nie”.

System master-slave je dobre otestovatelny a spolahlivy bez straty casu riesenim kolizii a v nasledku toho potreby opakovania spravy. Pri opakovani spravy kvoli kolizii dojde k zdrzaniu prenosu informacii, ktore ti nemozu vadit, lebo sa jedna o standartny mozny stav. Cas na opakovanie vsak moze byt dlhsi, ako odvysielanie bajtika s vyznamom “chces nieco?”. Pre rychlejsie odozvy je kvoli deterministike aj tak siahnut po inych metodach priameho pristupu.

Pouzivat extra pin na info “nieco chcem, komunikuj som nou” je zbytocne a komplikovane. Na vyzvu mastra “chces nieco?” moze naraz odpovedat viac slejvov a “zvitazi” ten, kto bude mat viac nul v odpovedi. Respektive moze odvisielat svoju adresu a na zaklade toho master vie s kym sa ma cielene bavit. Tak sa da elegantne vyriesit aj komunikacna priorita riesenia poziadaviek.

Při této rychlosti trvá 1 bit 17,4 us. Zhruba 1us spotřebuje MCU na vlatní přerušení (volání int. , jmp, mov SREG, push, …, pop, mov SREG, reti), ve kterém se ještě nevykoná nic. K tomu je nutné připočítat vlastní algoritmus tohoto přerušení. Doba vykonávání je také závislá na tom, kolik registrů MCU z 32 mohu vyhradit jen pro toto přerušení, abych nemusel pushovat nebo ukládat do SRAM. Nejkritičtější bude na začátku, tj. start a v polovině start bitu kontrola úrovně Low, a potom na konci, při stop bitu, kdy je zapotřebí zkontrolovat úroveň high a zároveň uložit data.

Vzorkování jednotlivých bitů by mělo být uprostřed, což je velký problém toho dosáhnout, existují-li ještě další přerušení, která mohou trvat i více než 17 us. V takovém případě dojde k chybnému načtení bitu. K tomu je nutné počítat se vzájemnou tolerancí clocků. 1% číní 1.4 us.

Kdyby SW UART exitoval v MCU sám a to jenom jako přijímač, možná že by to šlo udělat i na rychlosti 115200b/s. Ale k čemu by to bylo, když k němu potřebuju i SW vysílač, který se bez přerušní neobejde a navíc proč by to někdo dělal, když v MCU 1 HW UART je. A když je použit, jistě využívá přerušení, potom MCU už má minimálně 3 přerušení a ty mohou nastat i v jediném okamžiku. 17,4us je potom příliš krátká doba na vyřízení 3 přerušení, aby okamžik čtení bitu u SW UARTu byl uprostřed v rámci povolených tolerancí.

Připomínám, že HW UART provádí čtení každého bitu 16x a pro výsledek je rozhodující 7.,8. a 9. vzorek. Tohoto komfortu by jsme se museli zříci.