Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

přerušení vyvolané usartem
Jdi na stránku 1, 2  Další
 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
hajs



Založen: May 28, 2007
Příspěvky: 31

PříspěvekZaslal: st únor 13 2013, 21:45    Předmět: přerušení vyvolané usartem Citovat

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í



test-1.txt
 Komentář:

Stáhnout
 Soubor:  test-1.txt
 Velikost:  2.78 kB
 Staženo:  89 krát

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
bohumilfulin



Založen: Jan 12, 2010
Příspěvky: 109

PříspěvekZaslal: st únor 13 2013, 22:16    Předmět: Citovat

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.

Staci takto?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jenda_KL



Založen: Sep 10, 2008
Příspěvky: 1173
Bydliště: Kadaň

PříspěvekZaslal: čt únor 14 2013, 0:10    Předmět: Citovat

V tom Cčku to je fakt šílenost.
Musí se nastavit UCSRB.RXCIE , SREG.I a rutina pro obsluhu se dá na specifickou adresu, DS ví víc a přesnějc.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
AB1



Založen: Nov 23, 2009
Příspěvky: 312

PříspěvekZaslal: čt únor 14 2013, 10:44    Předmět: Citovat

Jde to i bez přerušení, pro jednobajtové povely třeba takto (vytvoř si funkce pro krok)

kód:
uint8_t mot_pause = 60;   // pausa mezi kroky motoru
char rec_byte;            // bajt přijatý z UART
uint8_t j;             

   while(1)
   {
   rec_byte = 0;
      if(bit_is_set(UCSRA, RXC))  // přišel bajt?
      {
         rec_byte = UDR;
     
            if(rec_byte == '+')
               for(j=0;j<5;j++)  krok_plus(); // 5 kroků směrem +
   
            if(rec_byte == '-')   
               for(j=0;j<5;j++) krok_minus();
           
            if(rec_byte == '1') mot_pause = 30;    // motor rychle
            if(rec_byte == '0') mot_pause = 60;    // motor pomalu
       
            if(rec_byte == 'L' || rec_byte == 'l')
               while(2)                            // motor se točí doleva
               {
                  krok_minus();
                  if(bit_is_set(UCSRA, RXC)) break; // vystup z while(2)
               }

            if(rec_byte == 'R' || rec_byte == 'r')
               while(3)                             // motor se točí doprava
               {
                  krok_plus();
                  if(bit_is_set(UCSRA, RXC)) break; // vystup z while(3)
               }
         }//if(bit_is_set
   }//while(1) 
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Jenda_KL



Založen: Sep 10, 2008
Příspěvky: 1173
Bydliště: Kadaň

PříspěvekZaslal: čt únor 14 2013, 12:17    Předmět: Citovat

Je požadováno zpracovat vícebajtový řetězec a to se při běžícím jiném programu dá jen dalším procesorem nebo přerušením.
---
minimum pro Mega64
kód:

.cseg
.org $0     RJMP INIT
.org $024   RJMP USART_REC
.org $034   RETI

USART_REC:
  push r21
  in r21,sreg
  // tady rutina pro prijem
  out sreg,r21
  pop r21
RETI

INIT:
; config StackPointer
ldi r16,low(RAMEND)
out SPL,r16
ldi r16,high(RAMEND)
out SPH,r16

; config USART
ldi r16,25      ; Set BR
ldi r17,0
sts UBRR0H, r17
out UBRR0L, r16
ldi r16, 0b10001110 ;URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
sts UCSR0C,r16
ldi r16, 0b10011000   ;RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8
out UCSR0B,r16

; IntEn
sei

LOOP:
  //tady main prog
RJMP LOOP

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: čt únor 14 2013, 16:31    Předmět: Citovat

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[?
]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
AB1



Založen: Nov 23, 2009
Příspěvky: 312

PříspěvekZaslal: čt únor 14 2013, 16:58    Předmět: Citovat

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í..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: čt únor 14 2013, 17:14    Předmět: Citovat

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.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Jenda_KL



Založen: Sep 10, 2008
Příspěvky: 1173
Bydliště: Kadaň

PříspěvekZaslal: pá únor 15 2013, 2:43    Předmět: Citovat

AB1 napsal(a):
Při jakém "jiném běžícím programu"?
hlavním běžícím programu "obsluha krokového motoru".
Tu by bylo dobré dát do INT od časovače a zbytek propojit v mainu, jak popsal mtajovsky.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
hajs



Založen: May 28, 2007
Příspěvky: 31

PříspěvekZaslal: pá únor 15 2013, 7:54    Předmět: Citovat

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.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
mtajovsky



Založen: Sep 19, 2007
Příspěvky: 3698
Bydliště: Praha

PříspěvekZaslal: pá únor 15 2013, 11:11    Předmět: Citovat

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
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: pá únor 15 2013, 23:04    Předmět: Citovat

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[?
]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
hajs



Založen: May 28, 2007
Příspěvky: 31

PříspěvekZaslal: pá únor 15 2013, 23:15    Předmět: Citovat

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 Smile Je to vůbec možné?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ZdenekHQ
Administrátor


Založen: Jul 21, 2006
Příspěvky: 25741
Bydliště: skoro Brno

PříspěvekZaslal: so únor 16 2013, 1:13    Předmět: Citovat

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[?
]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
Panda38



Založen: Nov 21, 2012
Příspěvky: 717
Bydliště: Most, Praha, Lanžhot

PříspěvekZaslal: so únor 16 2013, 9:14    Předmět: Citovat

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 ....
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Programování PIC, ATMEL, EEPROM a dalších obvodů Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
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

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

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.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.31 sekund