Interrupts

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Interrupts

Inlägg av sica06 »

Hej!

Har nyligen börjat pilla med min AVR-P28 (labbplatta) och en tillhörande ATmega88.
Har nu tänkt lära mig att använda interrupts. Har kollat runt lite på nätet och försökt en del själv, men fastnar och har några frågor. Uppskattar givetvis också länkar till sidor som kan hjälpa mig.

1. Har kollat på denna sidan som ganska bra förklarar interrupts. Är det denna princip som gäller, det vill säga att PCMSK sätts beroende på vilken pin som bevakas, att MCUCR sätts för att specifiera vilken interrupt-typ som gäller samt att GIMSK används för att "sätta igång" en interrupt?

Undrar också ifall SIGNAL (SIG_INT0) {} sedan används för att specifiera vad som ska göras när interrupt sker.

2. Fick en exempelkod från OLIMEX i vilken LED:en sätts igång vid knapptryckning.
Undrar över felmeddelandet.

Kod: Markera allt

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

void Initialize(void)
{
	PORTB = 0x0;
	PORTC = 1<<5;	/* turn the LED off */
	PORTD = 0x0;

	DDRB = 0x0;
	DDRC = 1<<5;	/* PC5 as output - the LED is there */
	DDRD = 0x0;

	// External Interrupt(s) initialization
	// INT0: Off
	// INT1: Off
	GIMSK=0x00;
	MCUCR=0x00;

	
}


/*	state = 0 -> Led Off
 *	state = 1 -> Led On
 *	state !=[0,1] -> Led Toggle 
 */
void LedSet(unsigned char state)
{
	switch (state)
	{
		case 0:
			PORTC &= ~(1<<5);
			break;
		case 1:
			PORTC |= 1<<5;
			break;
		default:
			if (PORTC & 1<<5)
				PORTC &= ~(1<<5);
			else
				PORTC |= 1<<5;
	}
	
}


int main(void)
{
	int i;

	Initialize();

	while (1)
	{
		if (!(PIND & 1<<2))	/* PIND2 is LOW when the button is pressed*/
		{
			LedSet(0);
			for (i=65535;i;i--);
			{
			__asm__ __volatile__ ("nop");
			__asm__ __volatile__ ("nop");
			__asm__ __volatile__ ("nop");
			__asm__ __volatile__ ("nop");
			}
			LedSet(1);
		}
	}
	return 0;
}
Felmeddelande:
../test3_LedLabbknapp.c: In function 'Initialize':
../test3_LedLabbknapp.c:18: error: 'GIMSK' undeclared (first use in this function)
../test3_LedLabbknapp.c:18: error: (Each undeclared identifier is reported only once
../test3_LedLabbknapp.c:18: error: for each function it appears in.)

Uppskattar all hjälp!
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: Interrupts

Inlägg av vfr »

Har du kollat om den saknade definitionen av GIMSK verkligen finns med i dina inkluderingsfiler?
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Interrupts

Inlägg av sica06 »

Med risk för att låta som en idiot - vilka inkluderingsfiler?
Är nybörjare på området.
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Re: Interrupts

Inlägg av thepirateboy »

När det gäller SIGNAL (SIG_INT0) så är det de gamla definitionerna för avr-gcc, använd de nya istället enligt manualen
http://www.nongnu.org/avr-libc/user-man ... rupts.html

För vilka register som ska sättas kolla databladet så du anger de rätta registernamnen (GIMSK heter EIMSK på AT88).

För att aktivera interrupt använder man normalt macrot sei();

Kolla sedan på sid 65 och framåt i databladet för att ange vilken pinne och när interrupt ska ske (rising/falling edge)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Interrupts

Inlägg av sodjan »

> Har kollat runt lite på nätet ...

Primärt är det Atmels datablad för den aktuella processorn samt
dokumentationen för den kompilator du använder, som du ska kolla i.
Är det dessa som du menar med att "kolla runt på nätet" ?
Det finns väldigt mycket skräp "på nätet"... :-)

> Har nu tänkt lära mig att använda interrupts....

Av resten av inlägget så ser det ut som om det igentligen bara handlar
om (externa) interrupt via I/O pinnar ? Du kanske ska förtydliga det lite.
Det gäller alltså inte interrupt generellt, eller gör det det ?

> det vill säga att PCMSK sätts beroende på vilken pin som bevakas,

Ja, det är ju det sidan säger... :-) Men, oavsett vad som just denna sida
säger, så är det viktiga är vad databladet säger. Har du jämfört ?
Var det några skillnader ? Om du är osäker på om den där sidan har
rätt, så skulle jag lita mer på databladet. Samma sak gäller de andra
registren du frågar om, generellt är det det som databladet som gäller.
Det är bättre om du pekar ut vad som var oklart i databladet (och
gärna en länk till det datablad som du använder). Det är ju lite
onödigt att upprepa vad som redan står i dokumentationen bara
för att du kanske inte har läst det. Läst först och fråga sen... :-) :-)

Dessutom verkar de heta PCMSK0, PCMSK1 och PCMSK2 (?)...

PCMSKx har dessutom med "pin change interrupt" att göra, inte med
det vanliga interrupt ingångarna. Vilket är det du vill använda ? Jag
tolkade det först att de var "vanliga" interrupt via INT0 och/eller INT1.
Men det kanske är interrupt-on-change du är ute efter ? Det är ju
två olika saker med sina egna inställningar.

> ...att MCUCR sätts för att specifiera vilken interrupt-typ som gäller...

Nja, typ och typ. Det verkar finnas en ganska utförlig beskrivning i
databladat. Vilken del av den var det som var oklar ? Men så vitt
jag förstår så är MCUCR inget som du borde behöva bry dig om, om
du inte håller på med bootloaders (inte sannolikt).

> ...samt att GIMSK används för att "sätta igång" en interrupt?

Jag hitter inte GIMSK i databladet till ATmega88. Har du en referens ?

När det gäller kompileringsfelen, så är det samma sak med dom.
Det framgår inte att du ens har kollat dokumentationen för den
kompilator du använder (vilken det nu är, det framgr inte heller).
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Interrupts

Inlägg av sica06 »

Stort tack! Gjorde en sökning tidigare i databladet på GIMSK utan resultat, men hittar nu med EIMSK.
Menar du EIMSK kan ersättas med sei();? Detsamma som EIMSK = 0xff;? Ska kanske inte säga för mycket innan jag har läst om det.

I exemplet används inte SIGNAL (SIG_INT0) eller motsvarande - finns det något skriven/oskriven regel om detta eller något annat generellt värt att veta?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Interrupts

Inlägg av sodjan »

> Menar du EIMSK kan ersättas med sei();

Har du ens kollat vad sei()/SEI gör ?
Jag är ganska övertygad om att C funktionen sei() bara är
en direkt översättning av assembler instruktinen SEI.
Kolla vad den gör så är det nog ganska tydligt. Det räcker
med att söka efter SEI i ATmega88 databladet, men en längre
beskrivning finns i t.ex doc0856.pdf med AVR instruktionerna.

EIMSK är ett register (ingen instruktion) och kan alltså inte ersättas
av SEI och har dessutom en annan funktion.

> Ska kanske inte säga för mycket innan jag har läst om det.

Korrekt ! :-) :-)
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Interrupts

Inlägg av sica06 »

Sodjan:
Jo, inlägget är lite otydligt, håller med om det. Blir nog lite så i början när man vill lära sig rent allmänt. Men ska bättra mig.

> Av resten av inlägget så ser det ut som om det igentligen bara handlar
om (externa) interrupt via I/O pinnar ?

- Japp, det gäller externa interrupts (inte för att jag känner till annat).


> Jag tolkade det först att de var "vanliga" interrupt via INT0 och/eller INT1.
Men det kanske är interrupt-on-change du är ute efter ?

-Gällande PCMSKx så vet jag helt enkelt inte skillnaden mellan INT0/INT1 och Interrupt-on-change. I mitt fall, till en början, tror jag dock att det främst gällen INT0/INT1 då denna pinne berörs vid min test-programmering (tända led mha knapp på labbplattan).

> Jag hitter inte GIMSK i databladet till ATmega88. Har du en referens ?

- Stämmer. Thepirateboy berättade nyss att GIMSK är ersatt av EIMSK.

Har inte kollat så mycket i databladet eftersom jag för tillfället inte kan utröna så mycket från det. Tänkte därför få lite allmän info här, sedan gå på det på allvar.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Interrupts

Inlägg av sica06 »

haha ja den kan jag ha! :)

Sökte på "sei()", gav inget. SEI funkade, precis.

Tyckte bara att det lät som att EIMSK och SEI var samma sak. Men ska som sagt läsa mer om det.

Tack för hjälpen!
Godnatt
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Re: Interrupts

Inlägg av thepirateboy »

sei(); används för att aktivera "global" interrupt (I-bit in the Status Register (SREG), alltså en bit i ett register för aktivering av alla sorts interrupt.
Är denna bit inte satt, spelar det ingen roll hur du ställer in de andra registren, du kommer aldrig få något interrupt.

Bestäm sedan vilken pinne som ska ge interrupt och när interrupt ska ske, när signalen går från låg till hög eller vice versa
(kolla framförallt registren EIMSK och EICRA)

När detta är gjort lägg till den korrekta interruptvektorn (kolla avr-gcc manualen enligt länk)
Programmet kommer hoppa till detta ställe när interrupt sker.
sica06
Inlägg: 83
Blev medlem: 31 augusti 2008, 17:31:50
Ort: Karlskrona

Re: Interrupts

Inlägg av sica06 »

Tack Thepirateboy - då förstår jag! =)
Får sätta mig imorrn igen efter jobbet, ser redan fram emot det!
Tackar en gång för hjälpen, sparade nog mig mycket möda.

Ha en bra kväll
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Interrupts

Inlägg av sodjan »

> Har inte kollat så mycket i databladet eftersom jag för tillfället inte kan utröna så mycket från det.
> Godnatt

Notera att ett datablad är alldeles utmärkt underhållning i sängen ! :-)
Och fullständigt ofarligt.... 8)

Men ärligt talat så är *databladet* det absolut viktigaste dokumentet.

Om du just har börjat med en viss processor så bör du ta ett par dagar
på dig att läsa igenom det. I alla fall snabbt så att du känner dig som
hemma i dig och snabbt kan hitta tillbaka när det är något speciellt du
letar efter. Kanske inte alla specialkapiteln om de olika enheterna men
de generella delarna om minne, oscillator, arkitektur o.s.v *MÅSTE*
du kunna ordenligt innan du skriver den första kodraden. Om du sedan
t.ex vill börja med interrupt (bara för att ta ett exempel ur högen) så
är det just interrupt-kapitlet som *MÅSTE* studeras i detalj.

Allt annat är att ta genvägar och det slår tillbaka direkt, om inte så
genom att du riskerar RTFM-svar på "dumma" frågor... :-) :-)

Det händer ibland att en del nybörjare tror att databladet enbart är
för de som programmerar i assembler, men det är helt fel...
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Re: Interrupts

Inlägg av bos »

sica06 skrev:Med risk för att låta som en idiot - vilka inkluderingsfiler?
De två översta raderna i din kod:

Kod: Markera allt

#include<avr/io.h>
#include<avr/interrupt.h>
är inkluderingsfiler. Dvs filerna "io.h" och "interrupt.h" i (för avr-kompilatorn) systemkatalogen "avr/".
Skriv svar