Problem med interrupt-on-change (PIC16F887)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Axbri
Inlägg: 20
Blev medlem: 6 februari 2010, 20:15:47

Problem med interrupt-on-change (PIC16F887)

Inlägg av Axbri »

Hej. Jag försöker att programmera en robot som jag har byggt.

Bild

Jag programmerar i MikroC 8.2. Nu har jag en PIC16F887 men jag har även försökt och fått samma felsymptom med en PIC18F4550. Tanken är att roboten ska undvika hinder med hjälp av en ultraljudssensor som sitter på ett servo och fyra trycksensorer, som ska kännas av med hjälp av interrupt-on-change. Mellan servot/motorstyrningen och den här mikrokontrollen sitter andra små mikrokontrollrar, det gör att jag kan styra hela roboten genom att bara lägga ut ett värde mellan 0-15 på respektive port.

Så här är det kopplat:

Kod: Markera allt

//  Inputs:

//  PORTA.F0 = Rangefinder Data bit (1)
//  PORTA.F1 = Rangefinder Data bit (2)
//  PORTA.F2 = Rangefinder Data bit (4)
//  PORTB.F0 = Rangefinder Data bit (8)

//  PORTB.F4 = LF Bumper
//  PORTB.F5 = RF Bumper
//  PORTB.F6 = LB Bumper
//  PORTB.F7 = RB Bumper


//  Outputs:

//  PORTC.F0 = Servo Data bit (1)
//  PORTC.F1 = Servo Data bit (2)
//  PORTC.F2 = Servo Data bit (4)
//  PORTC.F3 = Servo Data bit (8)

//  PORTD.F0 = RM Data bit (1)
//  PORTD.F1 = RM Data bit (2)
//  PORTD.F2 = RM Data bit (4)
//  PORTD.F3 = RM Data bit (8)

//  PORTD.F4 = LM Data bit (1)
//  PORTD.F5 = LM Data bit (2)
//  PORTD.F6 = LM Data bit (4)
//  PORTD.F7 = LM Data bit (8)
För att testa interrupt-funktionen har jag har gjort ett program där jag ”tittar” med servot åt höger och vänster i huvudprogrammet, och när det blir interrupt (när någon av trycksensorerna blir intryckta) ska den titta fortare med servot åt höger och vänster några gånger. Det fungerar, men ibland, inte varje gång, så ”fastnar” programmet i ca 10 sekunder vid slutet av interrupt-rutinen precis efter att den har centrerat servot. Är det någon som vet vad jag gör för fel?

Här är mitt program:

Kod: Markera allt


void interrupt()
{

INTCON  = 0b00000000;                             // stäng av interrupt

PORTC = 7;                                        // "titta vänster"
PORTB.F0 = 0;
Delay_ms (100);

PORTC = 9;                                        // "titta höger"
PORTB.F0 = 1;
Delay_ms (100);

PORTC = 7;                                        // "titta vänster"
PORTB.F0 = 0;
Delay_ms (100);

PORTC = 9;                                        // "titta höger"
PORTB.F0 = 1;
Delay_ms (100);

PORTC = 7;                                        // "titta vänster"
PORTB.F0 = 0;
Delay_ms (100);

PORTC = 9;                                        // "titta höger"
PORTB.F0 = 1;
Delay_ms (100);

PORTC = 7;                                        // "titta vänster"
PORTB.F0 = 0;
Delay_ms (100);

PORTC = 9;                                        // "titta höger"
PORTB.F0 = 1;
Delay_ms (100);

PORTC = 8;                                        // "centrera servot"
PORTB.F0 = 1;

INTCON  = 0b10001000;                             // interrupt on change (PORTB)
IOCB    = 0b11110000;                             //                   (bit 4-7)
}

//************************************************************

void main()
{
Delay_ms(20);

OSCCON  = 0b00000000;                             // extern ochilator

ANSEL   = 0b00000000;                             //inga analoga ingångar
ANSELH  = 0b00000000;                             //inga analoga ingångar

PORTA   = 0b00000000;                             // cleara portarna
PORTB   = 0b00000000;
PORTC   = 0b00000000;
PORTD   = 0b00000000;
PORTE   = 0b00000000;

TRISA   = 0b00001111;                             // 0 = output, 1 = input
TRISB   = 0b11110000;
TRISC   = 0b00000000;
TRISD   = 0b00000000;
TRISE   = 0b00000000;

INTCON  = 0b10001000;                             // interrupt on change (PORTB)
IOCB    = 0b11110000;                             //                   (bit 4-7)
WPUB    = 0b00000000;                             // inga pull upp


  while(1)
  {
  PORTC = 5;                                      // "titta vänster"
  PORTB.F0 = 0;
  Delay_ms (1500);

  PORTC = 11;                                     // "titta höger"
  PORTB.F0 = 1;
  Delay_ms (1500);
  }

}

Användarvisningsbild
Axbri
Inlägg: 20
Blev medlem: 6 februari 2010, 20:15:47

Re: Problem med interrupt-on-change (PIC16F887)

Inlägg av Axbri »

Kanske uttryckte jag mig på fel sätt, men jag blev lite besviken på att jag inte fick några tips. Till exempel var det kanske inte så smart att använda "Delay_ms()" både i interrupt och main-voiden. Nu har jag löst det genom att bara stoppa motorerna och sätta en flagga i interrupt. Sedan pollar jag flaggan i huvudprogrammet.

Jag har gjort en tråd i projekt-kategorin om min robot:http://elektronikforumet.com/forum/view ... =3&t=44986
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: Problem med interrupt-on-change (PIC16F887)

Inlägg av dangraf »

jag hänger inte riktigt med på beskrivningen av processorerna och vad själva huvudproblemet är.
Sitter ultraljudssensorn på ett servo och 4 knappar? :-)

Exakt vad är det som är inkopplat på interrupt on change? är det enbart de fyra switcharna eller är det även utgångar från de andra processorerna? Som du själv säger är delayerna i interruptet väldigt dumt.

varför ska den "titta" åt höger eller vänster när en switch slår i? Om du ska mäta avståndet till det du bumpar i kanske det är bättre att gör en if else sats typ
if( Left Bumber== 1)
titta åt vänster
else if (right bumber == 1)
titta åt höger

etc. så tittar du direkt åt ett håll. Just nu i din kod så verkar den alltid titta åt vänster det första den gör..
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: Problem med interrupt-on-change (PIC16F887)

Inlägg av dangraf »

Föresten, vad är det som du löst? jag förstår att du tagit bort delayerna från interruptet, men är även huvudproblemet löst?
Användarvisningsbild
Axbri
Inlägg: 20
Blev medlem: 6 februari 2010, 20:15:47

Re: Problem med interrupt-on-change (PIC16F887)

Inlägg av Axbri »

Hej dangraf.

Mitt problem var bara att programmet hängde sig p.g.a. dålig kod. Men nu är det löst. Här har jag försökt beskriva hur trycksensorerna fungerar: http://letsmakerobots.com/node/22442
Skriv svar