Zaslal: st únor 13 2013, 21:45 Předmět: přerušení vyvolané usartem
Ahoj, potřeboval bych prosím poradit, nebo aspon nasměrovat správným směrem.
Ovládám přes seriovou linku a tiny2313 krokový motor. Řízení probíhá tak že odešlu řetězec a atmel ho vyhodnotí a otáčí motorem bud doleva/doprava určený čas. Ale ted bych potřeboval aby se motor točil do té doby něž přijde nový příkaz, a podle vyhodnocení se bud točil dál nebo stál. K tomu je potřeba vyvolat přerušení , pokud se nepletu..
Ale nedaří se mi přijít na to jak správně nastavit přerušení na příchozí data, ty přijmout a pak přes switch zpracovat.
V příloze mám aktualní kod bez přerušení
Musis si vytvorit komunikacni protokol. Uroven slozitosti necham na tobe. U primitivnich veci muze postacovat STARTBYTE + Commandbyte nebo jenom jednobytovy prikaz. U slozitejsich to muzes vysperkovat o CRC atd, atd.
Vychazejme z verze STARTBYTE + COMMANDBYTE. Prvni znak co prijde testujes zda je to STARTBYTE pokud ano, spustis casove omezeni prijmu a cekas na dalsi prijem znaku (preruseni od seriove linky). Kdyz prijde otestujes zda tomuto bytu predchazel Startbyte a zda je v casovem intervalu. Pokud ano vezmes jej a vyhodnotis (az do teto doby je platny predchozi prikaz nebo stav po resetu). Po vyhodnoceni zastavis casove omezeni a vse znovu. To casove omezeni je tam dulezite aby se ti linka nezustala viset treba kvuli ruseni co se nachomitne na linku.
Založen: Jul 21, 2006 Příspěvky: 25741 Bydliště: skoro Brno
Zaslal: čt únor 14 2013, 16:31 Předmět:
Taková komunikace se dělá celá v přerušení - po příjmu znaku se uloží data do nějakého bufferu s tím, že se vyhodnocuje čas do příjmu dalšího znaku (překročení se bere jako povel pro vyhodnocení), počet znaků, crc atd. a pokud vše sedí, teprve potom si to převezme hlavní program, buffer se smaže, vynulují čítače času atd. _________________ Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
Při jakém "jiném běžícím programu"?
Bavíme se o zadání z původního příspěvku.
Tam to jde bez přerušení i kdyby příkaz byl vícebajtový.
Ale nevidím žádnou výhodu v použití příkazů ":1" , ":2" proti "1" , "2".
Proč označovat začátek jednobajtového příkazu?
Říkám jenom, že to v tomto jednoduchém případě jde, ne že je to nejlepší řešení..
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: čt únor 14 2013, 17:14 Předmět:
Základní vám popsal bohumilfulin. Pokud budete muset reagovat na vícero reálných asynchronních událostí, tak zde je několik zásad asynchronního programování:
- datový rámec přenosového protokolu by měl někde na začátku v hlavičce obsahovat délku dat (případně i verzi protokolu). Vyhnete se tak na vrstvě obslužné rutiny přerušení od příjmu dat analýze jestli je už přijato všechno. Rutina jen bude skládat data do bufferu a po každém znaku nastaví událost příjmu znaku. Tuto událost pak zpracovává centrální automat a až teprve ten rozhoduje, jestli je už přijato všechno nebo ne a co dál s přijatým povelem.
- vyhněte se jakýmkoliv čekacím smyčkám v přerušovacích rutinách a nejlépe úplně všude.
- pokud chcete zpracovávat nějaký časový interval, třeba hlídat dobu příjmu rámce protokolu, nebo jen počkat nějakou dobu, tak si udělejte obsluhu přerušení od časovače, která dekrementuje nějaký čítač, nebo i více čítačů. Můžete zpracovávat i mnoho různých časových intervalů současně. Časovač se nahodí nastavením čítače na nějakou hodnotu a od tohoto okamžiku se začne odměřovat čas. Pokud se některý čítač dostane v přerušovací rutině od HW časovače na nulu, došlo k vypršení daného času a nastavte příznak vzniku příslušné události.
- hlavní smyčka programu bude testovat výskyt událostí, které mohou třeba reprezentovány nastavováním nějakých bitů. Jakmile se detekuje, že někdo nastavil událost, třeba rutina příjmu znaku nastavila událost, že přišel znak, zavolá se centrální automat, který v sobě spustí příslušnou rutinu zpracování této události, ale, pozor, pro svůj aktuální stav. Zpracování stejné události se bude obecně lišit pro různé stavy. Dokonce, mnoho kombinací stavů a událostí bude vyloučených, například událost vypršení časovače, když nebyl nastaven a takto se dají detekovat různé bugy v kódu. Nakonec se nuluje příznak události.
- v centrálním automatu vznikne matice rutin, kde například řádek je dán aktuálním stavem a sloupec událostí. Většinou jsou tyto matice hodně řídké a jen několik rutin je třeba skutečně naprogramovat. Ostatní buď nic nedělají (return), nebo jejich vyvolání je chyba.
- dobře si rozmyslete stavy a události automatu. To je dáno konkrétní úlohou, kterou děláte.
Ač se to celé zdá jako velký orloj, tak s mírnou nadsázkou je to naprogramovat jednodušší než popsat. Při dodržení těchto zásad není pak problém systém rozšiřovat o další zpracovávané události z okolního světa a to pořád stejným způsobem. Hranicí je pak jen výkonnost procesoru. Takový způsobem je možno například simultánně třeba generovat řídící impulsy pro motor, přijímat data ze sériové linky a obsluhovat klávesnici.
diky za pomoc ale jsem naprostý začátečník takže bych spíš potřeboval, příklad kodu v C jak nastavit správně přerušení a přijmout celý řetězec.
Protokol kterým se to bude řídit je pevně daný , je to LX200 protokol pro řízení zařízení od Meade (astronomické dalekohledy), Já z toho budu používat pouze sadu pro ostření což jsou příkazy :F+#; :F-# ; :FF#; :FS#; :FQ#.
Nejraději bych v rámci přerušení přijmul celý řetězec do pole, a s tím bych pak dál pracoval. Např ve smyčce kdy se motor točí dopředu , bych ještě znova testoval zdali se nezměnil příkaz, vlivem přerušení, pokud ano, tak ukončit a vybrat přes case odpovídající ukon.
Založen: Sep 19, 2007 Příspěvky: 3698 Bydliště: Praha
Zaslal: pá únor 15 2013, 11:11 Předmět:
hajs napsal(a):
Např ve smyčce kdy se motor točí dopředu , bych ještě znova testoval zdali se nezměnil příkaz, ...
Nejsem si jist, že jsem dobře porozuměl, ale pokud chcete mít speciální smyčku pro pohyb motoru dopředu a v té něco testovat, aby se to nepropáslo, tak to bych udělal jinak. Smyčka detekce událostí má být jen jedna pro všechno a to, že se motor točí dopředu by mělo být poznamenáno stavem. Uvedu příklad pro běžný ss motor. Pokud například přijde příkaz k zastavení motoru a stav je "TOCENI_VPRED" nebo vzad, provede se sekvence:
- vypnutí napětí do motoru
- nahození časovače na skutečné zastavení
- přepnutí do stavu "CEKANI_NA_ZASTAVENI"
Ve stavu čekání není možno zpracovávat další příkaz pro motor. Pokud by v tomto stavu byl zkompletován nový příkaz, tak příslušná rutina reakce na událost zkompletování tohoto příkazu jej jen uloží. Naopak, ve stavu "ZASTAVENO" by příkaz ihned vykonala.
Po vypršení časovače se provede:
- kontrola, že jsme ve stavu čekání, protože vypršení časovače zastavování v jiném stavu je bugem programu. (Tato kontrola obvykle vznikne automaticky voláním různých rutin na událost podle stavu.)
- přepnutí do stavu "ZASTAVENO"
- kontrola, jestli po dobu čekání nepřišel další příkaz a jeho případné spuštění s nastavením patřičného stavu a případně i čekáním na rozběh podobně, jako při zastavování.
Byl-li příkaz k reverzaci motoru tak se pokračuje spuštěním v opačném směru. Časovač se může pro malé motorky vynechat, ale jeho použití způsobí šetrnější ovládání motoru. Pro krokový motor se časovače vynechají, namísto toho bude v činnosti časovač odměřující krokování motoru. Naznačeným způsobem je třeba správně reagovat na povely v daných stavech a také pomocí přepínání stavu udržovat povědomí programu o tom, v jaké fázi ovládání motoru právě jsme.
http://cs.wikipedia.org/wiki/Mealyho_automat
Založen: Jul 21, 2006 Příspěvky: 25741 Bydliště: skoro Brno
Zaslal: pá únor 15 2013, 23:04 Předmět:
Obávám se, že teorie někdy příliš složitě popisuje praxi. Dobrá věc na doktorát, ale příliš složitá pro praxi.
Spoustu podmínek lze ošetřit jen tím, že doba mezi příkazy bude vždy delší než potřebný čas na vykonání nejdelšího příkazu, t.j v tomto případě reverzace.
K té komunikaci - obecně v rámci alespoň nejjednoduššího zabezpečení proti rušení bych doporučil posílat přímou a následně negovanou hodnotu příkazu, v lepší případě i nějaký kontrolní součet. Nutný je naopak nějaký time-out časovač komunikace, jinak je to nepoužitelný. _________________ Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
4 řídící příkazy mám pevně dané (:F+#; :F-# ; :FF#; :FS#; :FQ#) s tím nemohu nic měnit, takže pokud znam predem 3znaky ze 4 tak je ošetřena částečně i chybovost. Potřebuju jen v rámci přerušení přijmout celý řetězec, ukončit přerušení, a vrátit se. A pak přijatý řetězec porovnat s aktualnim stavem. Nic víc Je to vůbec možné?
Založen: Jul 21, 2006 Příspěvky: 25741 Bydliště: skoro Brno
Zaslal: so únor 16 2013, 1:13 Předmět:
V rámci přerušení se jen pasivně přijímají znaky do bufferu, hlavní program dělá zbytek. Dokud není v rámci určitého časového rámce přijat celý smysluplný příkaz, hlavní program provádí poslední příkaz a buffer se maže.
Pokud jde o reverzaci, pokud přichází protichůdně požadavky v rámci brždění, hlavní program prostě jen brzdí a čeká, to je věc jednoho stavového bitu.
Vážně se to hůř popisuje než programuje. _________________ Pro moje oslovení klidně použijte jméno Zdeněk
Správně navržené zapojení je jako recept na dobré jídlo.
Můžete vynechat půlku ingrediencí, nebo přidat jiné,
ale jste si jistí, že vám to bude chutnat[?]
Založen: Nov 21, 2012 Příspěvky: 719 Bydliště: Most, Praha, Lanžhot
Zaslal: so únor 16 2013, 9:14 Předmět:
Pokud je takhle přesně daný rámec paketů a liší se jen commandem, tak pak je lepší jen počítat bajty a vyhodnocovat strukturu paketu už v přerušení (v hlavní smyčce rozlišovat jen command):
kód:
char Cmd;
bool CmdOK = False;
char PktLen = 0;
...v přerušení (mimo jiné):
char znak = UDR;
switch (PktLen)
{
case 0:
if (znak == ':') PktLen = 1;
break;
case 1:
PktLen = (znak == 'F') ? 2 : 0;
break;
case 2:
Cmd = znak;
PktLen = 3;
break;
default:
PktLen = 0;
CmdOK = (znak == '#');
}
...v hlavní smyčce:
if (CmdOK)
{
CmdOK = False;
switch (Cmd)
{
case ....
Časy uváděny v GMT + 1 hodina Jdi na stránku 1, 2Další
Strana 1 z 2
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.