Interrupt fungerar inte på Mega88

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Interrupt fungerar inte på Mega88

Inlägg 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).
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Inlägg av eqlazer »

ISR (INT0_vect){} är en egen funktion, den ska alltså inte ligga innuti main().
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg 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.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Inlägg 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å
Snouser
Inlägg: 107
Blev medlem: 15 november 2006, 22:07:55
Ort: Göteborg

Inlägg 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?
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg 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.
Skriv svar