ATTiny náhodné chování přerušení u rot. enkodéru

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
Darthy
Příspěvky: 187
Registrován: 15 led 2008, 01:00
Bydliště: Olomouc

ATTiny náhodné chování přerušení u rot. enkodéru

#1 Příspěvek od Darthy »

Snažím se rozchodit enkodér na ATTiny84. Jelikož má pouze jeden INT pin, jsem nucen použít PCINT a tím jsem ochuzen o nastavení podmínky pro vyvolání přerušení a o rozpoznání který pin přerušení spustil. Používám tenhle enkodér zapojený dle datasheetu (zkoušel jsem i opačné zapojení aby impulsy byly 1, ne 0). Výstupy enkodéru na osciloskopu jsou v příloze. Podle chování bych předpokládal, že ISR() bude zavoláno 4x, při každé změně. A port PINB na který je enkodér připojen bude vypadat cca takto

Kód: Vybrat vše

// otočka doleva, PINB0 a PINB1 jsou připojeny k enkoderu
PINB = 0010
PINB = 0000
PINB = 0001
PINB = 0011

// otočka doprava
PINB = 0001
PINB = 0000
PINB = 0010
PINB = 0011
Jenomže ISR() je zavoláno pouze 3x a někdy dokonce jen 2x. Zdá se jakoby některé změny/přerušení vynechával. Výstup je obvykle takovýto

Kód: Vybrat vše

// doleva
PINB = 0010   nebo  PINB = 0010
PINB = 0000         PINB = 0011
PINB = 0011

// doprava
PINB = 0001   nebo  PINB = 0001
PINB = 0010         PINB = 0011
PINB = 0011
Frekvenci jsem používal 1MHz interní a teď mám 4MHz interní (8MHz s děličkou). Tady je nastavení přerušení

Kód: Vybrat vše

void _initInterrupt() {
  DDRB |= (1 << PB2);

  DDRB &= ~(1 << PINB0) | ~(1 << PINB1) | ~(1 << PINB2);

  GIMSK |= (1 << PCIE1);
  GIFR |= (1 << PCIF1);
  PCMSK1 |= (1 << PCINT8) | (1 << PCINT9) | (1 << PCINT10);

  sei();
}

ISR(PCINT1_vect){ }
Zapomněl jsem na něco, nebo kde může být chyba? Je možné že ATTiny nestíhá zachytit změny signálu při rychlejších otočkách? Protože většinou dvě přerušení jsou po opakovaných otočení. Naneštěstí je to náhodné, někdy dvě pak tři, pak několikrát zase dvě a tím pak nejsem schopný vyhodnotit jestli jde o levou nebo pravou otočku.
Přílohy
Otočka doprava
Otočka doprava
Otočka doleva
Otočka doleva

Uživatelský avatar
radek89
Příspěvky: 135
Registrován: 25 říj 2009, 02:00
Bydliště: Mor. Nová Ves, Břeclav
Kontaktovat uživatele:

#2 Příspěvek od radek89 »

Na enkodér ti stačí jeden pin reagující na externí přerušení (PB2), teprve v jeho vektoru dle úrovně na dalším pinu zjišťuješ směr pootočení.
Mimochodem proč máš PB2 jako výstupní, ovládáš jím něco?
Mohlo by to vypadat např. takhle nějak:

Kód: Vybrat vše

ISR( INT0_vect)
{
	if( PINA & (1<<PA7))	// Smer doleva
	{
		.....
	}
	else			// Smer doprava
	{
		.....
	}
}
Samozřejmě z toho pak plyne správné nastavení pro přerušení v registrech GIMSK a GIFR.

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#3 Příspěvek od lesana87 »

Záleží, co v tom přerušení děláš, jak dlouho trvá.

Uživatelský avatar
Darthy
Příspěvky: 187
Registrován: 15 led 2008, 01:00
Bydliště: Olomouc

#4 Příspěvek od Darthy »

Na PB2 jsem měl LED na testování, ještě předtím, než jsem tam přiojil tlačítko enkodéru. Vypadá to, že jsem zapomněl ten řádek umazat, na dalším řádku totiž nastavuji stejně vstup na PINB2.
radek89 píše: Na enkodér ti stačí jeden pin reagující na externí přerušení (PB2)
Ach, chápu co tím myslíš. Takhle jsem nad tím nepřemýšlel, nicméně já potřebuji přerušení i na tlačítko na enkodéru, nejsem si teď jistý jestli můžu využít vektor INT na vektoru B a zároveň PCINT na vektoru A? S tím, že použiji dvakrát rutinu ISR() s jiným vektorem.
lesana87 píše:Záleží, co v tom přerušení děláš, jak dlouho trvá.

Pouze jsem vyhodnocoval bity jednotlivých pinů, případně výsledek posílal na display, nebo posílal na seriový výstup, možná to je příčina, ale to by nevysvětlilo proč to bylo náhodné.

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#5 Příspěvek od lesana87 »

Přerušení je asynchronní, v tom samotným už je notná dávka náhodnosti. V přerušení se nemá dělat nic, co trvá dlouho, žádný čekání na displej nebo na vyprázdnění bufferu USARTu. Blokujou se tím další přerušení.
A generovat od tlačítka přerušení je taky cesta do pekel. Reakční doba člověka je řádově 100ms, tak proč honit nějaký us. Takový tlačítko zvládne vygenerovat hezkých pár zákmitů po sobě a už tu máme kupu (úplně zbytečných) přerušení. Tlačítko (klávesnici) stačí číst periodicky třeba 20x za sekundu, snadno se pak ošetří i ty zákmity, dlouhé stisky, autorepeat...

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“