Potřeboval bych poradit, naprogramoval jsem si asynchronní přenos dat, přidal jsem k procesoru krystal 11.592MHz, program mi fungoval, ale všiml jsem si že sem nenastavil programové propojky, takže jsem měl vnitřní oscilátor 1MHz, který mi dělal problém při přenosu na větší vzdálenost. Teď mám nastavený krystal, ale mám problém že mě to všechno vysílá tak rychle, že mi to přeskočí některé vyslané bity, přitom sem to nastavil tak abych zachoval přenosovou rychlou 9600bd. Př.: posílám do kamery instrukci o přiblížení a po uvolnění tlačítka se vyšle instrukce STOP, jenže někdy se ta instukce neodešle(přeskočí) a přibližuje to až do maxima. Vše se mi teď provádí v programu moc rychle, dá se někde nastavit pro to nějaká dělička, aby mi celý cyklus zpomalila nazpět, jako když jsem měl krystal 1MHz stím, že chci zachovat stejnou přenosovou rychlost? nebo se to řeší zpožděním u každé vysílané instrukce?
Fórum › Mikrokontroléry
ATmega16 UART
Pokud odvozuješ časy z počtu oběhů a délky cyklu, je to nešťastné řešení. Jakékoliv intervaly je vhodnější odvodit z časovače. Při čekání je vhodné použít Idle Mode, ušetří to příkon procesoru a v programu jednu smyčku. Dále je důležité mít dobře ošetřené vstupy od tlačítek - při přepnutí kontakty rychle zakmitávají, tyto přechodné děje jsou velice rychlé, tlačítko je takto schopné "generovat" impulzy různé šířky, ty nejužší jen několik desítek mikrosekund. A do třetice: RS232 je vhodná pro přenos do cca 9m, záleží na baudrate, kvalitě kabelu a intenzitě rušení. Jinak by bylo asi dobré vidět zdroják.
hu
Tlačítka mám ošetřené, nebo alespoň sem měl, dával jsem zpoždení 50 milisekund kvůly nežádoucím zákmitům.Ale to stejně by nemělo vadit protože po uvolnění tlačítka se musí vyslat STOP, takže ať se to samo zmáčkne sebevíckrát, tak by se to mělo potom vždy zastavit. Pro přenos používám RS485, abych mohl ovládat kamery ve vzdálenosti 120m, když jsem porovnával oba programy (jeden s rystale, druhý bez), tak nastavení inicializace, testování tlačítek na hranu a odeslání 6 bajtů, trvalo v obou případech stejně, takže v debuggru se to jevilo stejně rychlé, ale realita potom byla jiná. Třeba u tlačítka " MENU" sem měl nastavené zpoždění tak, abych ho nemohl zanou nebo vypnout po 0,5s po zmáčknutí. Jenže teď zmáčknu na MENU a než to pustím,tak se to třeba 2x zapne a 3x vypne, takže ve finále sem se nedostal do menu. S časovači pracovat neumím, ale pokud to vyřeší tento problém, tak to zkusím, ale nenapadá mě jak bych to uplatnil na celý program a abych ho moc nezvětšil, protože mám omezenej program.
je spousta věcí, které v reálu nefungují, byť na simulátoru fungují bez chyby. Právě softwarové ošetření tlačítka jde dělat časovačem, přesněji všech tlačítek. Časovač necháš "tiknout" každou ms, při obsluze jeho přerušení přečteš stav tlačítek. Je-li tlačítko v klidu, int hodnotu dekrementuješ o 1, je-li stisknuté, inkrementuješ tu samou int hodnotu o 1. Pokud hodnota klesla na 0, vyhodnotíš tlačítko jako uvolněné, pokud dosáhla max hodnotu, vyhodnotíš tlačítko jako stisknuté. Max hodnotu doporučuji asi 300. Chová se to jako integrační člen RC. Tento postup jsem použil na vzorkování 5 vstupů u ATTINY26 s 2kB paměti programu, využívám asi polovinu a to je tam ještě stavový automat, který řídí servo.
Nejlepší je ošetření tlačítka hardwarově pomocí klopného obvodu R-S, tlačítko musí mít přepínací kontakt.
Časovače nastuduj z datasheetu a Application Notes, Atmel má plno ukázkových programů a návodů na svých stránkách.
Odhaduji, že dochází k protichůdným požadavkům na vysílání povelu a tím dojde k odeslání paskvilu, na který kamera nereaguje. Stačí si udělat pomůcku do COM portu a dění na RS485 sledovat a ukládat do souboru, tam si pak přečteš, co jsi odeslal.
Kamera pravděpodobně pošle potvrzení, že vykonala požadavek. Je vhodné vysílat další až potom, co kamera požadavek vykonala, možná má předepsanou dobu klidu na sběrnici mezi jednotlivými relacemi, pak je nutné dodržet tuto prodlevu.
hu
Ukázka programu ( Assembler- WinAVR)
nastavení počtu bitů, stopbitů, přenosová rychlost atd.
LDI R16, 0B00000010
OUT UCSRA, R16
LDI R16, 0B00001000
OUT UCSRB, R16
LDI R16, 0B10001110
OUT UCSRC, R16
LDI R16, LO(143)
OUT UBRRL, R16
LDI R16, HI(143)
OUT UBRRH, R16
;Skok na funkci, odesílání bitů
SBIS PIN(TLA3)
RJMP PRIBLIZ
;test na zmáčklé tlač., jsou tam ještě 3
LDI R16, 0B11000101
OUT UDR, R16
PRIBLIZ1: SBIS UCSRA, TXC ;čekání na příznak vyslání celého bytu
RJMP PRIBLIZ1
SBI UCSRA, TXC ;nulujeme příznak nastavením do log1 ? !!!!!!!!!!
LDI R16, 0B01011111
OUT UDR, R16
PRIBLIZ2: SBIS UCSRA, TXC ;čekání na příznak vyslání celého bytu
RJMP PRIBLIZ2
;další 4 baty, ale to je stejné
SBI UCSRA, TXC
DELMS 10
SBIS PIN(TLA3)
RJMP PRIBLIZ ; pokud je zmáčklé, opakuje se to
RJMP STOP ; když pustím tlač. tak STOP
; u STOP stejné odesílání jako u PŘIBLIŽ, akorát jiná kombinace bitů.
RJMP MAIN ;začnou se zas testovat tlačítka
Kamera mi v reálu fungovala tak jak měla, přepinácí tláčítka tam dávat nemůžu, protože se jedná o růmyslovou kameru, která se ovládá z řídící místnosti, takže když vydí že se na kameře něco děje, tak přidrží tlačítko a tak dlouho jak ho drží se vysílá příkaz, náhrada za (joystik), jakmile tlačítko pustí vyšle se STOP. Kamera odpovídá, ale až se dokoná tu funkci PŘIBLIŽ+STOP, takže není možné, aby se proti sobě poslali data, takže s tím, co mi odesílá kamera už nijak nepracuju. Zmáčknutí tlačítka řeším programově, kdy program pořád pracuje a kontroluje stav jednotlivých pinů(nepoužívám inkrementaci, ale SBIS, pokud je na pinu jednička pokračuju v instrukci, za ní už mám skok na patřičná místa, jinak ji přeskočím). Jakmile zjistí, že na nějakém pinu je zmáčklé tlačítko, tak si tam skočím a začínám vykonávat danou funkci, kde zas vysílám bity a kontrolu jestli se poslali všechny, pak vyšlu další bity atd. nakonec kontroluju jestli se vyslalo všech 6 bajtů a jestli je tlačítko stále zmáčklé(celé to trvá jen mikrosekundy), když je zmáčklé opakuji celou ředešlou akci, pokud ne, tak skočím na STOP, kde dělám to stejné a skočím na začátek programu kde testuji 5 tlačítek.
přepínací kontakt tlačítka použít lze, navenek je uživateli jedno, zda mačká přepínací nebo spínací kontakt. Co je uvnitř krabičky je uživateli taky jedno.
HW ošetření s klopným obvodem R-S se zapojuje takto: NC kontakt tlačítka na Reset vstup KO, NO kontakt tlačítka na Set vstup KO. COM tlačítka na GND, vstupy KO ještě připojíš přes odpory na +5V. Výstup Q pak má High při stisknutém a Low při uvolněném tlačítku bez jakýchkoli zákmitů - to pošleš do MCU, který jen reaguje na stav. Lze použít např. pin change interrupt. Výhoda je jednoduchost software. Popsané funguje např. s 74LS74 nebo s obvodem R-S poskládaným z NAND hradel (74LS00). U jiných klopných obvodů je třeba si dát pozor na aktivní úroveň vstupů.
U softwarového řešení pro vyhodnocení stavu tlačítka potřebuješ řadu vzorků. Tu "zintegruješ" zjednodušeným algoritmem ,který napodobuje integrační člen RC s komparátorem. K pravidelnému vzorkování použiješ časovač. Za jednoduchost hardware "zaplatíš" na úrovni software vyšší pracností, velikostí programu, ztrátou části výkonu MCU - v tomto případě je asi nejvíce kritická pracnost.
hu
Ale předtím mi to fungovalo tak jak mělo i bez klopných obvodů, jen sem prostě porovnal stav tlačítek instrukcí SBIS a vše mi pracovalo tak jak mělo do té doby, než jsem změnil frekvenci z 1MHz na 11MHz. Je možné, že kdybych za instrukci STOP dal ještě jednu instrukci STOP (což májí programovací jazyky pro kamery Pelco-d), tak bych tím možná vyřešil problém? Protože mám zákmit a asise mi přeskočí část instrukce STOP, která se nevykoná ale na konci mě udělá skok zas na začátek, kde začne porovnávat tlačítka, jenže se to neukončilo, takže to sice kontroluje tlačítka ale stále to vysílá.
je to špatným návrhem. Vyšším taktováním procesoru se zkrátila doba provádění instrukce (asi na 90 ns). To vede k jiným časovým vztahům. Zatímco na 1 MHz procesor mohl některé věci jednoduše "prošvihnout", na 11 MHz už je stihne vnímat. Jde to i bez klopných obvodů, ale musíš tlačítko vzorkovat a stav vyhodnocovat ze série vzorků podstatně složitějším algoritmem, než to děláš. Podmíněný skok proběhne bez jakékoliv analýzy předchozích stavů vstupu, takže může reagovat na nahodilý impulz nebo i na sérii impulzů - opakovaná odezva pak vede ke zmatkům. V tomto případě chybné vyhodnocení vstupů vede k chybnému vysílání povelů. Důležité je řešit příčinu, s odstraněním příčiny zmizí i následky.
Ještě jedna poznámka: Funkci USART lze řídit také přerušením. Takže z hlavního programu odpadne spousta podmínek.
S přihlédnutím k tvým dovednostem bych zvolil HW ošetření tlačítek a MCU použil jen jako "inteligentí" USART pro vysílání povelů. Nebál bych se přerušení, obsluha tlačítek a USART se tím do značné míry vyčlení mimo hlavní smyčku programu, ta se takto zjednoduší. Hlavní smyčka programu by pak fungovala jako jednoduchý stavový automat.
hu
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Atmega16 uart — založil jur3c
Problémy s UART — založil marpit
Uart buffer — založil davixxx
Uart příjem z AVR — založil Ghulas
MEGA8 UART prerušení — založil johnny
Moderátoři diskuze