interrupt problem PIC18f458 *LÖST*

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

interrupt problem PIC18f458 *LÖST*

Inlägg 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){	
	}
}
Senast redigerad av slatte 21 maj 2008, 16:47:19, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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å.
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg 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.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg 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){	
	}
}
Senast redigerad av slatte 20 maj 2008, 22:06:52, redigerad totalt 2 gånger.
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

Har inte PIC18F458 och massa andra äldre kiseluppsättningar massa skumma effekter när man använder olika prioriteringsordningar på interrupten?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg 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
Senast redigerad av slatte 20 maj 2008, 20:39:02, redigerad totalt 1 gång.
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg av bos »

Jag ser inte att du sätter GIE någonstans.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg av slatte »

Kod: Markera allt

INTCON = 0b10100000;	// 1= GIE; 0= IPEN; 1= TMR0IE; 0= INT0IE; 
							// 0= RBIE; 0= TMR0IF; 0= INT0IF; 0= RBIF
:-)
bos
Inlägg: 2314
Blev medlem: 24 februari 2007, 23:29:15
Kontakt:

Inlägg 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.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg 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 :-(
Användarvisningsbild
BER
Inlägg: 399
Blev medlem: 9 mars 2005, 00:02:10
Ort: Östergötland

Inlägg 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
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

Inlägg av slatte »

Gött!! ska genast undersöka detta danke danke!!
Användarvisningsbild
BER
Inlägg: 399
Blev medlem: 9 mars 2005, 00:02:10
Ort: Östergötland

Inlägg av BER »

Skall du lägga ut något på portpinnarna skall du anväda "LAT" registren om jag minns rätt.
Användarvisningsbild
slatte
Inlägg: 420
Blev medlem: 1 april 2008, 16:05:17
Ort: Jönköping

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