Sida 1 av 1

interrupt problem PIC18f458 *LÖST*

Postat: 20 maj 2008, 18:36:50
av slatte
Jag är helt ny på 18f serien och som jag förstår det så använder man inte interruppt rutinen på samma sätt här. utan man har 2 st en hög och en låg prioritets interrupt? men jag lyckas inte få det att fungera har försökt att läsa mig till det och har provat en massa, men får det verkligen inte att fungera.
använder Mplab med c18 kompilatorn

Här är min kod se om ni kan säga vad jag gör för fel. säkert massor :D

Kod: Markera allt

#include <p18f458.h>
#pragma config OSC = XT, OSCS = OFF
#pragma config PWRT = ON, BOR = OFF
#pragma config WDT = OFF
#pragma config STVR = ON, LVP = OFF
#pragma interruptlow interrupt_low
#pragma interrupt interrupt_high 

void init (void){
	TRISA = 0;	//PORTA out
	TRISB = 0;	//PORTB out
	PORTA = 0;	
	PORTB = 0;
	T0CON = 0b11000000;
	INTCON = 0b10100000;
	INTCONbits.T0IF = 0;
	TMR0L = 0b00000000;
	TMR0H = 0b00000000;
	INTCON2bits.TMR0IP = 1;	
	
}
void interrupt_high(){
	static char temp = 0;
	
	if (temp < 10)
	PORTB = 0b11111111;
	else if(temp < 20)
	PORTB = 0b00000000;
	else
	temp = 0;

	INTCONbits.T0IF = 0;
	TMR0L = 0b00000000;
	TMR0H = 0b00000000;		
}
void interrupt_low(){
}

void main (void){
	init();

	while (1){	
	}
}

Postat: 20 maj 2008, 19:33:25
av sodjan
> utan man har 2 st en hög och en låg prioritets interrupt?

Om man vill och behöver !

I 99 fall av 100 behöver man det inte och det är *mycket*
enklare at köra "som vanligt" med 1 interrupt prio-nivå.

Postat: 20 maj 2008, 19:44:20
av bos
Till att börja med skulle du ju kunna berätta vad som är det förväntade resultatet, och vad som händer. Det går att med hjälp av din kod utröna vad som händer med PORTB, men du skriver inte om det händer något här.

Oavsett vilket så är din interrupt konstig. Du testar "temp" för olika värden, men inte någonstans inkrementeras denna variabel. Den är noll hela tiden.

Postat: 20 maj 2008, 19:59:45
av slatte
hmm har inte kollat så mycket på funktionen i interruptet ännu tack vare att jag inte får den att gå in i interruptet. Gjorde lite ändringar hitta var man stängde av prioitets interruptet nu;-). hela funktionen är bara att initiera och sedan gå till while satsen som är en evighetsloop och när timern0 går overflow ska den gå in i interrupt. Typ så var det tängt att det ska fungera.

När jag stegar igenom händer något annat. När TMR0IF (alltså då jag vill att den ska hoppa till interrupt rutinen) sätts så hoppar den in i filen c018i.c av någon anledning som jag inte förstår och där händer en del grejer som t.ex att den nollställer GIE

Kod: Markera allt

#include <p18f458.h>
#pragma config OSC = XT, OSCS = OFF
#pragma config PWRT = ON, BOR = OFF
#pragma config WDT = OFF
#pragma config STVR = ON, LVP = OFF


void init (void){
	TRISA = 0;	//PORTA out
	TRISB = 0;	//PORTB out
	PORTA = 0;	
	PORTB = 0;
	T0CON = 0b11000000;		// TIMER0  med prescaler 1:2 och intern CLK 
	INTCON = 0b10100000;	// 1= GIE; 0= IPEN; 1= TMR0IE; 0= INT0IE; 
							// 0= RBIE; 0= TMR0IF; 0= INT0IF; 0= RBIF
	INTCONbits.T0IF = 0;	//nollar TIMER0 interrupt flag
	TMR0L = 0;				//nollar TMR0
	TMR0H = 0;
	INTCON2bits.TMR0IP = 1;	//TMR0IP Overflow interrupt priority bit
	RCONbits.IPEN = 0; 		//disable priority interrupt
}
void interrupt(){
	static char temp = 0;         //VAD SOM GÖRS I INTERRUPTET ÄR INTE 
	                                      //SÅ VIKTIGT JAG VILL BARA VETA VARFÖR 
                                              //DEN INTE GÅR IN I INTERRUPTET
	if (temp < 10){
	PORTB = 0b11111111;
        temp++;
        {
	else if(temp < 20){
	PORTB = 0b00000000;
        temp++;
        }
	else
	temp = 0;

	INTCONbits.T0IF = 0;	//nollar flaggan
	TMR0L = 0b00000000;		//nollar TMR0
	TMR0H = 0b00000000;		//behöver nog inte nolla denna egetligen men gör det för säkerhets skull 
}

void main (void){
	init();

	while (1){	
	}
}

Postat: 20 maj 2008, 20:30:14
av Micke_s
Har inte PIC18F458 och massa andra äldre kiseluppsättningar massa skumma effekter när man använder olika prioriteringsordningar på interrupten?

Postat: 20 maj 2008, 20:33:56
av sodjan
Dels är det nu avstängt, dels så borde kompilatorn känna till det.

> och där händer en del grejer som t.ex att den nollställer GIE

Lite konstigt, GIE sköts av processorn (d.v.s hårdvaran) automatiskt.
D.v.s när interruptet inträffar och när man (eller kompilatorn) gör RETFIE.

Aja, jag vet inte hur det fungerar i C...

Postat: 20 maj 2008, 20:36:58
av slatte
ingen aning! men jag tror att jag har satt den funktionen som disable i vilket fall genom

Kod: Markera allt

RCONbits.IPEN = 0; 		//disable priority interrupt
Men hittar ni något jag känner att jag inte har alls koll på detta så att det kan vara något jätte basic fel med för den delen :-)

EDIT: bah får snart börja med assembler igen :-) fast det lär väll inte hjälpa

Postat: 20 maj 2008, 20:38:36
av bos
Jag ser inte att du sätter GIE någonstans.

Postat: 20 maj 2008, 20:40:32
av slatte

Kod: Markera allt

INTCON = 0b10100000;	// 1= GIE; 0= IPEN; 1= TMR0IE; 0= INT0IE; 
							// 0= RBIE; 0= TMR0IF; 0= INT0IF; 0= RBIF
:-)

Postat: 20 maj 2008, 21:45:04
av bos
När jag bytte till C så slutade jag använda den typen av deklarationer när det gäller konfigurationsflaggor, så det var därför jag missade det. Jag använder istället GIE = 1; T0IE = 1, osv.

Nåväl. Du har fortfarande inte ändrat koden i din interrupt, så den kommer bara att sätta PORTB till -1 en enda gång. Du vill nog lägga till en temp += 1 nånstans.

Har du byggt upp en krets kring cpu:n, eller kör du bara i simulator? Om det senare, sätt en breakpoint i interrupten.

Postat: 20 maj 2008, 22:03:17
av slatte
Jag kör bara simulator! och angående deklarationen är det nog snyggare att göra som du gör :-) ändrade lite i interrupt rutinen med, inte för att det kommer göra någon nytta om den inte hoppar in i funktionen :-(

Postat: 20 maj 2008, 22:49:43
av BER
Tror att detta saknas...

Kod: Markera allt

#pragma code HIGH_INTERRUPT_VECTOR = 0x208
void high_ISR (void) 
{
	_asm
	goto interrupt_high
	_endasm
}

#pragma code

#pragma interrupt_high

void interrupt(){
...
}
Kontrollera med databladet att 0x208 stämmer för din PIC

Postat: 20 maj 2008, 22:51:39
av slatte
Gött!! ska genast undersöka detta danke danke!!

Postat: 20 maj 2008, 23:02:21
av BER
Skall du lägga ut något på portpinnarna skall du anväda "LAT" registren om jag minns rätt.

Postat: 20 maj 2008, 23:10:10
av slatte
gött nu fungerar det gjorde lite ändringar men du löste problemet danke danke!! Du gjorde mig glad har suttit och klurat på det ett tag. jag läste lite om portarna och hittade något om LAT får kolla nogrannare på det. såhär fick jag det att fungera:

Kod: Markera allt

#include <p18f458.h>
#pragma config OSC = XT, OSCS = OFF
#pragma config PWRT = ON, BOR = OFF
#pragma config WDT = OFF
#pragma config STVR = ON, LVP = OFF
#pragma code high_vector = 0x0008

void interrupt_1(void);
void interrupt_at_high_vector(void)
{
	_asm GOTO interrupt_1 _endasm
}
#pragma code
#pragma interrupt interrupt_1

void init (void){
	TRISA = 0;	//PORTA out
	TRISB = 0;	//PORTB out
	PORTA = 0;	
	PORTB = 0;
	T0CON = 0b11000000;		// TIMER0  med prescaler 1:2 och intern CLK 
	INTCON = 0b10100000;	// 1= GIE; 0= IPEN; 1= TMR0IE; 0= INT0IE; 
							// 0= RBIE; 0= TMR0IF; 0= INT0IF; 0= RBIF
	INTCONbits.T0IF = 0;	//nollar TIMER0 interrupt flag
	TMR0L = 0;				//nollar TMR0
	TMR0H = 0;
	INTCON2bits.TMR0IP = 1;	//TMR0IP Overflow interrupt priority bit
	RCONbits.IPEN = 0; 		//disable priority interrupt
}
void interrupt_1(){
	static char temp = 0;
	
	if (temp < 10){
	PORTB = 0b11111111;
	temp++;
	}
	else if(temp < 20){
	PORTB = 0b00000000;
	temp++;
	}
	else
	temp = 0;

	INTCONbits.T0IF = 0;	//nollar flaggan
	TMR0L = 0b00000000;		//nollar TMR0
	TMR0H = 0b00000000;		//behöver nog inte nolla denna egetligen men gör det för säkerhets skull 
}

void main (void){
	init();

	while (1){	
	}
}
Äntligen kan man fortsätta leka :D