AVR GCC: čtení stavu PINu portu v subr. ext. přerušení INT4
Moderátor: Moderátoři
AVR GCC: čtení stavu PINu portu v subr. ext. přerušení INT4
mohu chtít v podprogramu ext. přerušení INTn číst stav pinu nějaké brány?
nedaří se mi takový to vstup přečíst.
tohle mi nechodí, ikdyž logický analyzátor ukazuje na PE3 log1, čte se do proměnné stavB pořád jen nula:
#define CHECK_BIT(BYTE,BIT)(BYTE&=(1<<BIT))
unsigned int NastavovanaHodnota=0; // globální proměnné
unsigned char stavB=0, pomocna=0;
ISR(INT4_vect)
{
cli();
stavB= ((PORTE & 0x08)>>3);
//stavB= CHECK_BIT(PORTE,3); // <<< nebo takto taky nechodí
sei();
switch(stavB)
{
case 0: NastavovanaHodnota--; break;
case 1: NastavovanaHodnota++; break;
default: pomocna++; break;
}
}
čtený pin PE3 mám při startu nastavený jako vstup DDRE=0xE7;
Děkuju předem
Hlavní chyba bude ale v tom, že čteš PORTE a ne PINE.
Kód: Vybrat vše
// enkoder demo:
#define CHECK_BIT(BYTE,BIT) ((BYTE)&(1<<(BIT)))
volatile unsigned int NastavovanaHodnota = 0; // globální proměnné
ISR(<TBD>) // tohle je přerušení spouštěné hranou na pinu<>PE3
{
unsigned char stavE3;
stavE3 = CHECK_BIT(PORTE, 3); // PE3?
if (stavE3)
{
NastavovanaHodnota--;
}
else
{
NastavovanaHodnota++;
}
}
CHECK_BIT(BYTE,BIT) vrací 0, pokud je vstup v 0, jinak vrací jakoukoliv nenulovou hodnotu
Myslím že v gcc v avr-libc je už toto makro hotové, stačí jej použít:
Kód: Vybrat vše
sfr_defs.h:#define bit_is_set(sfr, bit) (_SFR_BYTE(sfr) & _BV(bit))Edit1: To je kouzlo jazyka C, x=0 -> false, x<>0 -> true
Edit2: Jo, má tam být PINE. To je pravda...
Tj. definici napiš jako:
Kód: Vybrat vše
volatile unsigned char ...
a ještě mně prosim prozraďte kterej Atmel má PORTE
díky už se to konečně pohlo, směr je je rozpoznán, čítá to ale většinou po dvou, až to poladím, dám vědět.
globální proměnné používám proto, abych je mohl zobrazit na displeji mimo podprogram přerušení.
v podprogramu přerušení po přečtení vstupu nechám čekat 10ms
na konci podprogramu přerušení shazuji bit příznaku pro čekající přerušení (je to tak?) CLEAR_BIT(EIFR,4);
protože další přerušení bývá obvykle za delší dobu než 200ms
to "několikrát se do sebe vnořit", to je pro mně novinka, je to opravdu tak?
díky moc
Enkoder píše:na konci podprogramu přerušení shazuji bit příznaku pro čekající přerušení (je to tak?) CLEAR_BIT(EIFR,4);
Když před tím povolíš přerušení, tak je to k ničemu, pokud se EIFR,4 nastaví, přerušení se okamžitě vyvolá znovu (a EIFR se tím následně shodí) a tím se vnoří samo do sebe (přeruší se vykonávaná obsluha INT4 a zavolá se znovu ta samá obsluha INT4).
Kód: Vybrat vše
The falling edge of INTn generates asynchronously an interrupt request.
The rising edge of INTn generates asynchronously an interrupt request.
Potom nemusíš nic "čistit", všechno se udělá "samo". Nakonec ty globální proměnné nejsou tak špatné. Asi jediný způsob jak předat něco z / do ISR().
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Interruptflags_l.C3.B6schen
PORTE má arduino s ATmega2560
k enkoderu jsem dal odpory 10k a kondíky 33nF.
budu sledovat diskuzi, opravím to až zítra
void Inicializace_INT4(void)
{
EICRB |= (1 << ISC41) | (1 << ISC40); // reakce přerušení INT4 na vzestupnou hranu
SET_BIT(EIMSK,4); // povol přerušení od INT4
}
díky moc