Sida 1 av 1

Interrupt fungerar inte på Mega88

Postat: 25 oktober 2008, 22:28:30
av Snouser
Jag får inte interrupt att fungera på min mikrokontroller.

Så här ser min kod ut:

Kod: Markera allt

#include <avr/io.h> 
#include <util/delay.h>
#include <avr/iom88.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#define F_CPU 4915200 // 4 Mhz 
#define sBit(byte,bit) (byte |= 1<<bit)
#define cBit(byte,bit) (byte &= ~(1<<bit))
#define tBit(byte,bit) (byte & (1<<bit))

void init(void)
{
	DDRB = 0b00111111; //Sätter dioderna som ut
	PORTD = 0b00000100; //INT0
	EICRA = (0<<ISC01) | (0<<ISC00);
	EIMSK |= (1<<INT0);
}

int main ()
{
   init();
   sei();
   while(1)
   {}
   ISR (INT0_vect)
   {
	sBit(PORTB,3);
	_delay_ms(200);
	cBit(PORTB,3);
	reti();
    }
}
Inget händer när jag kopplar INT0 till jord (tror jag det var).

Postat: 25 oktober 2008, 22:56:58
av eqlazer
ISR (INT0_vect){} är en egen funktion, den ska alltså inte ligga innuti main().

Postat: 25 oktober 2008, 23:05:53
av thepirateboy
Delayer i interrupt är inte att rekommendera. Sätt en flagga till "true" och ta hand om det som ska utföras i main.

Postat: 25 oktober 2008, 23:19:34
av Korken
Samt: "The maximal possible delay is 262.14 ms / F_CPU in MHz." från util\delay.h
Så din delay är för stor.

//Emil
Luleå

Postat: 26 oktober 2008, 01:39:12
av Snouser
Okej, tack för svaren.

Nu har jag gjort om koden lite, men jag får det inte att fungera ändå.

Först och främst så gjorde jag en lite delay funktion, eftersom mina vänte tider tydligen inte vara okej.

Den ser ut så här.

Kod: Markera allt

void pause(int mill)
{
	double tal;
	int tal2;
	int a;
	tal = mill/53;
	tal2 = round(tal);
	
	for(a = 0; a < tal2; a++)
	{
		_delay_ms(53);	
	}
	return;
}
Math biblioteket är inkluderat för round, men det hjälper inte.
Som det är nu så är pause(1000); väldigt lite.
Lampan som jag har kopplat till kontrollen lyser väldigt kort tid, kanske 100ms.

Sedan så har jag pillat lite med interrupten. Nu får jag iallafall inga fel från kompilatorn som jag fick innan.

Så här ser koden ut nu.

Kod: Markera allt

static int INT = 0;
void init(void)
{
	DDRB = 0b00111111; //Sätter dioderna som ut
	PORTD = 0b00000100; 
	EICRA = (0<<ISC01) | (0<<ISC00);
	EIMSK |= (1<<INT0);
}

ISR (INT0_vect)
{
	INT = 1;
	reti();
}
int main()
{
while (1)
	{
		if (INT == 1)
		{
			INT = 0;
			sBit(PORTB,2);
			_delay_ms(300);
			cBit(PORTB,2);
		}
	}
}
Denna kod fungerar inte alls, nödvändiga bibliotek är förövrigt redan inkluderade i koden. Det borde finnas något enklare sätt än IF i detta fallet, eller?

Postat: 26 oktober 2008, 09:07:45
av thepirateboy
Du måste deklarera variabler som används i interrupt som volatile, annars finns det risk att de optimeras bort av kompilatorn. ex. volatile unsigned char pushButton = 0;

Du har väl inte glömt sei(); ??

reti(); behövs inte.

Att göra en delayfunktion med double känns lite overkill. Kan du inte bara göra en for-loop med några _delay_ms(10); ? Blir inte så exakt men känns som det duger om du bara ska blinka en diod.