forum.mcontrollers.com - hlavní stránka forum.mcontrollers.com - fórum

 

.: fórum - hlavní stránka :.
Technology Stronghold by Rudolf Vesely
How to build Microsoft System Center hosted cloud series
FAQFAQ HledatHledat Seznam uživatelůSeznam uživatelů Uživatelské skupinyUživatelské skupiny RegistraceRegistrace
ProfilProfil StatistikaStatistika Soukromé zprávySoukromé zprávy PřihlášeníPřihlášení

 
Osetreni zakmitu tlacitka na ext preruseni

 
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> AVR
 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 01 květen 2013, 13:45    Předmět: Osetreni zakmitu tlacitka na ext preruseni Citovat

Prosim o radu jak korektne osetrit zakmit tlacitka pro externi preruseni. Napsal jsem tohle, ale nepomaha :
kód:


ISR ( INT4_vect )
{   

   _delay_ms(30);

    if (bit_is_clear(PINE,4)){
    .
    .
    .
    }

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

 
alien
Účastník
Účastník


Založen: 23.6.2012
Příspěvky: 14
Bydliště: Zubří

PříspěvekZaslal: 01 květen 2013, 18:16    Předmět: Citovat

V C moc nedělám, nicméně strkat do přerušení zpožďovací smyčku není moc dobré řešení. U ext. přerušení je lepší odstranit zákmity hardwarově. Můžeš skusit na konci obsluhy přerušení vynulovat příznak vnějšího přerušení. Zákmity trvají kolem 10ms záleží na typu tlačítka. Pokud trváš na funkci delay v obsluze zkus ji dát nakonec obsluhy a za ní ještě natvrdo nulování toho příznaku. Ono jev možné že první hrana vyvolá přerušení, ale již během obsluhy přerušení příjde další která opět nastaví příznak a po skočení první oblsuhy se obsluha zavolá znova. Proto nakonci nuluj příznak. Ale jak jsem již napsal není to úplně správné řešení.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
Balů
Profesionál
Profesionál


Založen: 29.10.2012
Příspěvky: 753

PříspěvekZaslal: 01 květen 2013, 22:59    Předmět: Citovat

Do přerušení nemůžeš strkat dlouhý čekání. 30ms je pro mcu věčnost. Pokud chceš řešit tlačítko pomocí externího přerušení, je nejrozumnější řešit to na HW úrovni (viz. příloha). Používám externí přerušení pro rotační kodér a funguje to spolehlivě. Kondenzátory dávám 100n a odpory 100R a funguje to spolehlivě. Tlačítko tady nemá HW řešené zákmity a odpor je tam jenom proto, že je to vytažené ze schématu, kde používám stejný pin mcu pro tlačítko do mcu a pro data SPI z mcu. Jinak odpor k tlačítkům nedávám. Zapnuté interní pull-up rezistory jsou předpokladem.


Osetreni_zakmitu.png
 Komentář:
 Velikost:  4.95 kB
 Zobrazeno:  6372 krát

Osetreni_zakmitu.png


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

 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 01 květen 2013, 23:52    Předmět: Citovat

Dekuji, zkusim tedy kondik Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
Panda38
Profesionál
Profesionál


Založen: 18.9.2012
Příspěvky: 398
Bydliště: Praha, Most

PříspěvekZaslal: 02 květen 2013, 5:37    Předmět: Citovat

Zákmit není problém řešit i jen softwarově - jen je potřeba použít ještě přerušení od časovače. Přerušení od tlačítka nastaví proměnnou s čítačem necitlivosti, přerušení od hodin proměnnou dekrementuje (je-li != 0). Přerušení od tlačítka nahodí flag stisku tlačítka pouze v případě, že proměnná je nula, tj. uplynul dostatečný čas od minulého přerušení. (prodlevu do přerušení rozhodně nedávat!)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
 

 
Balů
Profesionál
Profesionál


Založen: 29.10.2012
Příspěvky: 753

PříspěvekZaslal: 02 květen 2013, 7:02    Předmět: Citovat

Ještě doplním ke svému příspěvku: Ke tlačítkům odpor nedávám v případě, že řeším zákmity pomocí SW a pin mcu slouží pouze pro snímání toho tlačítka. V tomto přípdadě pin slouží jako vstup tlačítka a zároveň jako výstup dat pro SPI komunikaci a odpor tam zajišťuje, aby se data neuzemnila tlačítkem, pokud je stisknuté. V tomto případě je vhodné použít odpor alespoň 1k. Pokud u tlačítek řeším zákmity na úrovni HW, pak tam samozřejmě ten odpor dávám také. A když tak na to koukám, tak si nejsem jistý, jestli jsem se nespletl u hodnoty toho kondíku. Jestli tam nemá být jen 10n. Odpoledne to ověřím a dám Ti sem ještě vědět.

Jinak samozřejmě i při použití externího přerušení pro tlačítka lze řešit zákmity pomocí SW, jak psal Panda38.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
Balů
Profesionál
Profesionál


Založen: 29.10.2012
Příspěvky: 753

PříspěvekZaslal: 02 květen 2013, 21:18    Předmět: Citovat

K hodnotám kondenzátorů : pro odstranění zákmitů u rotačního kodéru používám kondenzátory 10n a odpory 68 nebo 100 ohmů. Podle toho, co bylo po ruce.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 02 květen 2013, 22:50    Předmět: Citovat

Bezva prcnu tam 10n, ted tam mam 100n a neni to uplne idealni, diky Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 28 květen 2013, 9:04    Předmět: Citovat

kód:
//interupt na PE4 - tlacitko pro zapnuti vystupu - zelena LED, je-li zapnut prenos nemuze generovat

ISR ( INT4_vect )
{   
// spusti casovac         
   
   TIMSK = (1 << OCIE1A);
   TCCR1A = (0<<WGM11)|(0 << WGM10);
   TCCR1B = (0<<WGM13)|(1<<WGM12);
   TCCR1B |= (1<<CS12)|(0<<CS11)|(1<<CS10);
   TCCR1C = 0;
   OCR1A = 200;      

}


ISR ( TIMER1_COMPA_vect )
{

         if (zmacknuto_prenos == false){
            if (zmacknuto_gen){
              zmacknuto_gen = false;
              PORTE &= ~(_BV(7));         //vynuluje, zhasne cervenou LED na PE7
              lcd_clrscr();
              menu_start();
              vrstva_menu = 0;
            }         
            else{               
              zmacknuto_gen = true;
              PORTE |= _BV(7);         //nastavi, rozne LED   
              lcd_clrscr();
              lcd_gotoxy(1,1);      
              lcd_puts("PROBIHA GENEROVANI");
            }
         }
}


Bylo to mysleno takto Panda38?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

 
Panda38
Profesionál
Profesionál


Založen: 18.9.2012
Příspěvky: 398
Bydliště: Praha, Most

PříspěvekZaslal: 28 květen 2013, 9:50    Předmět: Citovat

sw ošetření zákmitů tlačítka? Ne, nějak takhle (program jen symbolicky). Časovač běží neustále, stejně je často potřeba pro měření intervalů, může čítat např. po 1 milisekundě. Reakce na tlačítka by měla být v hlavním programu a ne v přerušení, protože může být potřeba volat jiné funkce, některé i s prodlevami, to by se mohlo z přerušení špatně používat. A také by hrozila kolize kdyby k zařízením chtěl přistupovat hlavní program. Proto je vhodnější aby přerušení předávalo jen flagy a bylo co nejkratší.
kód:
volatile char btn1_byl_stisk = 0;      // priznak, ze byl stisk tlacitka btn1
char btn1_citac = 0;               // citac doby po kterou tlacitko nereaguje na novy stisk
volatile unsigned short citac_casu = 0; // citac casu po 1 ms (není potreba pro tlacitka)

ISR ( preruseni od tlacitka )
{
   if (btn1_citac == 0) btn1_byl_stisk = 1;
   btn1_citac = 200;
}

ISR ( preruseni casovace 1 ms )
{
   if (btn1_citac != 0) btn1_citac--;
   citac_casu++;
}

char StiskBtn1(void) // byl stisk tlacitka btn1 ?
{
   char ok = btn1_byl_stisk;
   btn1_byl_stisk = 0;
   return ok;
}

int main(void)
{
   while(1)
   {
      if (StiskBtn1())
      {
         // .... tady je nejaka akce na stisk tlacitka Btn1
      }
   }
}

Doplňkově příklad použití měření času čítačem:
kód:
unsigned short CasMs(void) // dej aktualni cas v ms (pozor - povoli preruseni!)
{
   unsigned short cas;
   cli();
   cas = citac_casu;
   sei();
   return cas;
}

// presne cekani po dany pocet ms (pozor - povoli preruseni!)
// jen na ukazku pouziti mereni casu, spis se pouzije podobne
// v programu paralelne s jinymi procesy, napr. pro mereni time-outu

void CekejMs(unsigned short ms)
{
   unsigned short stary_cas = CasMs();
   while(CasMs() - stary_cas < ms) {}
}

// nebo v programu:
unsigned short ubehly_cas;
unsigned short stary_cas = CasMs();
while (1)
{
   if (... nejaka udalost)
   {
      ubehly_cas = CasMs() - stary_cas;
      stary_cas += ubehly_cas; // posun casove znacky pro pristi test
   }

   // nebo pro zjisteni timeoutu udalosti, napr. vypadek spojeni:
   if (CasMs() - stary_cas >= TIMEOUT)
   {
      // obsluha timeoutu udalosti
   }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovy WWW stránky
 

 
juraw
Profesionál
Profesionál


Založen: 24.9.2012
Příspěvky: 47

PříspěvekZaslal: 28 květen 2013, 22:19    Předmět: Citovat

dekuji, aplikuji
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
 

Zobrazit příspěvky z předchozích:   
Zobrazit předchozí téma :: Zobrazit následující téma  
Přidat nové téma   Zaslat odpověď    Obsah fóra mcontrollers.com -> AVR Časy uváděny v GMT + 2 hodiny
 
Strana 1 z 1
Přejdi na:  
Můžete přidat nové téma do tohoto fóra.
Můž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.
Můžete k příspěvkům připojovat soubory
Můžete stahovat a prohlížet přiložené soubory
 



Num Lock Holder - app to hold Numlock
Copyright © 2018 Rudolf Veselý, mcontrollers.com.
Je zakázáno používat části tohoto webu bez souhlasu autora. || Powered by phpBB © 2001, 2002 phpBB Group - with RedSquare DoubleJ(Jan Jaap)