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í 

AVR GCC: čtení stavu PINu portu v subr. ext. přerušení INT4
Jdi na stránku Předchozí  1, 2
 
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
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: út březen 29 2016, 21:32    Předmět: Citovat

Přerušení se nevnořují do sebe. Po vstupu do přerušení se uloží obsah PC do SP, ten se sníží. SREG se automaticky neukládá (proto již vzpomínané volatile). Je zakázáno globální přerušení. Po návratu (RETI) se vyzvedne PC a globální přerušení se povolí. Zkontrolují se příznaky přerušení a případně se obslouží dle priority. Příznaky přerušení se dají (ovšem ne všechny) vymazat zápisem jedničky do příslušného bitu.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
lesana87



Založen: Sep 20, 2014
Příspěvky: 3330

PříspěvekZaslal: st březen 30 2016, 16:36    Předmět: Citovat

frpr666 napsal(a):
@lesana87
s tím vnořováním samo do sebe nesouhlasím. Myslím, že tam bylo něco jako že se z ISR vrátí řízení zpět, provede se alespoň jedna instrukce a pak se zase (případně) zavolá ISR.

FHonza napsal(a):
Přerušení se nevnořují do sebe...Je zakázáno globální přerušení.

Ale on hned třetím příkazem v obsluze přerušení povoluje globální přerušení, takže když na vstupu přerušení INT4 vznikne zákmit dřív, než se dokončí obsluha, přerušení se vyvolá znovu a vnoří se do nedokončené obsluhy.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
frpr666



Založen: Dec 28, 2009
Příspěvky: 1051

PříspěvekZaslal: st březen 30 2016, 17:28    Předmět: Citovat

@lesana87
aha, to je pravda, to je pravda. Pokud si explicitně povolí přerušení během ISR a je nahozený flag, tak nastane rekurze ISR (a přetečení zásobníka...).
kód:
ISR(INT4_vect)
{
 //...
 sei(); // fail, tohleto zpusobi vecnou rekurzi ISR.
 //...
}

Tak takhle tedy NE!
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
lesana87



Založen: Sep 20, 2014
Příspěvky: 3330

PříspěvekZaslal: st březen 30 2016, 17:35    Předmět: Citovat

Přerušení se do sebe vnoří maximálně tolikrát, kolik zákmitů vznikne na INT vstupu, takže to zas taková tragedie, jak popisuješ, nebude.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Enkoder



Založen: Mar 29, 2016
Příspěvky: 12

PříspěvekZaslal: st březen 30 2016, 18:32    Předmět: Citovat

Tak už to krásně chodí, děkuju:

ISR(INT4_vect)
{
CLEAR_BIT(EIMSK,INT4); // zakaž přerušení od INT4
unsigned char stavE3=0;
stavE3=CHECK_BIT(PINE,3);
if (stavE3)
{
NastavovanaHodnota++;
}
else
{
NastavovanaHodnota--;
}
_delay_ms(5);

SET_BIT(EIMSK,INT4); // povol přerušení od INT4 a
SET_BIT(EIFR,INTF4); // a smaž logickou jedničkou příznak INT4
}

začíná ale zlobit samotný enkoder, asi ty kondíky nedělají dobrotu, spínač enkoderu je přeci jen zkratuje, nebo je enkoder nekvalitní (testováno na logickém analyzátoru).

Já si myslím, že vnořit se do probíhajícího přerušení může asi jen přerušení s vyšší prioritou. Jedno samo do sebe ne. Přiklánim se k názoru Honzy. A ikdyž se globální INT zakáže a povolí, není to důvod ke znovuvyvolání tohoto přerušení uvnitř probíhajícího. Tak to aspoň bylo při mých dávných pokusech s 8051, Ale nedokážu to plně posoudit na kolik v tom hraje roli to GCC a na kolik je to dáno samotným procesorem.

edit1: to přerušení se může vyvolat hned několikrát za sebou, tím, že se příznak přerušení během probíhajícího přerušení znovunastaví, ale asi ne, že by došlo ke vnoření
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
lesana87



Založen: Sep 20, 2014
Příspěvky: 3330

PříspěvekZaslal: st březen 30 2016, 18:47    Předmět: Citovat

A jak tedy vysvětlíš to, že se ti najednou přestalo připočítávat po dvou? Po sobě se ti ta přerušení mohou vyvolávat i teď, jediné co jsi odstranil, že se ti nemůžou vyvolávat přes sebe. A proč tam to přerušení od INT4 zakazuješ, když se podle tebe nemůžou do sebe vnořovat? Smile

Kondenzátorama přímo na kontaktech enkodéru ho pošleš hodně rychle do kytek.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Enkoder



Založen: Mar 29, 2016
Příspěvky: 12

PříspěvekZaslal: st březen 30 2016, 19:56    Předmět: Citovat

to lesana:

(ty globální přerušení jsem smazal už dřív skákalo to ještě po větších skocích s malou pauzou)

Odpověď proč to počítalo dvakrát:
Bylo to asi proto, že se zareaguje na první vzestupnou hranu - spustí se poprvé ISR (INT4_vect) , vzápětí vzniknou zákmity, při těchto zákmitech se znovu nastaví příznak pro obsloužení přerušení, ale podprogram běží dál pauzou, kde se se to časově přenese do doby kdy už žádné zákmity nejsou. Zůstal tam ale požadavek na to přerušení, který se obsloužil tím, že se podprogram přerušení spustil podruhé, proto to počítalo po dvou.
Novou úpravou - zakázáním INT4 po dobu podprogramu přerušení a hlavně shozením požadavku EIFR INTF4 na přerušení, jsem ten druhý požadavek na obsloužení zrušil. (čert ví, proč to nefunguje bez součinnosti s EIMSK - vidíš, mohl bych ještě vyzkoušet)

mohl bych se Tě zeptat, proč to neskákalo po třech Smile

spíš by mě zajímalo, zda je třeba to chování hledat v céčku, nebo na straně hardware. Spíš bych řekl, že tomu diktuje hardware

ošetření zákmitů na spínači se řeší jeho překlenutím kondíkem, otázka je, jak velkým, ale i malý vyvíjí destrukční proud... vybíjí se přeci jen okamžitě z 5 Volt na nulu
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Enkoder



Založen: Mar 29, 2016
Příspěvky: 12

PříspěvekZaslal: st březen 30 2016, 21:41    Předmět: Citovat

tak jsem vyzkoušel odebrat
na začátku:
CLEAR_BIT(EIMSK,INT4); // zakaž přerušení od INT4
a na konci :
SET_BIT(EIMSK,INT4); // povol přerušení od INT4
a chodí to taky
(občas vynechá enkodér jednu polohu, nebude moc kvalitní)

Hlavní nedostatek byl pravděpodobně v tom, že jsem požadavek na druhé přerušení nenuloval jedničkou takto:
SET_BIT(EIFR,INTF4); // smaž logickou jedničkou příznak INTF4
(jak na to upozornil Honza)
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
FHonza



Založen: Nov 20, 2012
Příspěvky: 1453
Bydliště: Praha

PříspěvekZaslal: čt březen 31 2016, 9:20    Předmět: Citovat

Zakazovat a poté povolovat přerušení v obsluze přerušení je zbytečné. Při vstupu do obsluhy přerušení je automaticky zakázáno, při návratu povoleno. Jediné co má smysl je mazat požadavek na další přerušení.

Doslova:
The I-bit is cleared by hardware after an interrupt has occurred, and is set by
the RETI instruction to enable subsequent interrupts.
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 březen 31 2016, 15:04    Předmět: Citovat

Enkoder napsal(a):
ošetření zákmitů na spínači se řeší jeho překlenutím kondíkem ...

To je sice také možné, ale ne dost dobré. Ošetření zákmitů se dělá tak, že se v přerušení poznačí nová úroveň na vstupu a spustí se časovač, dejme tomu 3 ms. Po jeho vypršení se zkontroluje, jestli úroveň na daném vstupu zůstala zachována a když ano, vezme se signál na vstupu jako platný. Když ne, byl to planý impuls. Přijde-li tedy na vstup série zákmitů, časovač se opakovaně restartuje, naposledy s poslední hranou. Po 3 ms se pak přečte výsledná úroveň.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
frpr666



Založen: Dec 28, 2009
Příspěvky: 1051

PříspěvekZaslal: čt březen 31 2016, 20:15    Předmět: Citovat

Enkoder s potlačením rušení pomocí časovače:
kód:

// file: main.c
//* chip: attiny13a

#include <avr/interrupt.h>
#include <avr/io.h>

#define BCLR(n,bit) (n)&=~(_BV(bit))
#define BSET(n,bit) (n)|=(_BV(bit))

// Disable INT0 interrupt
#define INT0_STOP {\
 BCLR(GIMSK,INT0);\
}

// Enable INT0 interrupt
#define INT0_START {\
 BSET(GIFR,INTF0);\
 BSET(GIMSK,INT0);\
}

// Start timer, preset 100 ticks
#define TIM_START {\
 TCNT0=(256-100);\
 TCCR0B=_BV(CS00);\
}

// Stop timer
#define TIM_STOP {\
 TCCR0B=0;\
}

//-------------------------
volatile uint16_t enc_value;
uint16_t enc_print;

//-------------------------
ISR(INT0_vect) //PB1
{
  if(bit_is_set(PINB, 0)) // PB0
  {
    enc_value++;
  }
  else
  {
    if(enc_value > 0)
    {
      enc_value--;
    }
  }
  INT0_STOP;
  TIM_START;
}

//-------------------------
ISR(TIM0_OVF_vect)
{
  TIM_STOP;
  INT0_START;
}

//-------------------------
void setup( void)
{
// The low level selected for INT0_vect
  MCUCR = 0x00;

// Enable TIM0_OVF interrupt
  BSET(TIMSK0, TOIE0);
  TIM_START;
  sei();
}

//-------------------------
void loop( void)
{
  cli();
  enc_print = enc_value;
  sei();
  // ...
  // print(enc_print);
  // ...
}

//-------------------------
int main( void)
{
  setup();
  for(;;)
  {
    loop();
  }
}
//-------------------------
//EOF


Mimo to: hardwarově se přidává RC článek na každý vstup: http://www.electroschematics.com/wp-content/uploads/2015/06/rotary-encoder-arduino-wiring.png
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Enkoder



Založen: Mar 29, 2016
Příspěvky: 12

PříspěvekZaslal: ne duben 03 2016, 14:19    Předmět: Citovat

díky, RC článek se zdá být na ochranu kontaktů dobrý nápad, a co na to logický obvod TTL nebo procesor, který nemá rád otálení zakázaném pásmu logických úrovní - nejspíš to bude vyžadovat navíc smittův klopný obvod..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
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 Předchozí  1, 2
Strana 2 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.15 sekund