Interrupt i mikroC / Extern interrupt?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
gustavn
Inlägg: 297
Blev medlem: 30 november 2004, 12:27:05
Ort: Linköping
Kontakt:

Interrupt i mikroC / Extern interrupt?

Inlägg av gustavn »

Jag har en quadrature encoder med 3600 pulser/varv som jag vill läsa av med en PIC 16f877A @ 20Mhz. Jag vill räkna pulserna och visa dom på en display, detta har jag fått att fungera genom att sätta A och B pinnen från encodern till två vanliga digitala ingångar. Problemet är att under den tid det tar att skriva ut antalet pulser på displayen så missar räknaren pulser.
Så till frågan, hur ska man lösa detta på effektivast sätt?

Edit: Glömde skriva att jag använder mikroC.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Man löser det vid att ha 1 interrupt!

Den sitter på ena pulståget och vid interrupt kollar den fasen på andra pulsen, då vet den om det är + eller -.

En variabel (X) räknas då upp eller ner enl. detta.
Sedan gör ISR inget mer!

I mainloopen har du en annan variabel (Y):

Kod: Markera allt

if(X != Y)
  {
  Y = X;
  printf(Display,Y); // Nåja, du fattar nog...
  }
På det sätt är ISR'n snabb och utläsningen tar den tid den tar.
Användarvisningsbild
gustavn
Inlägg: 297
Blev medlem: 30 november 2004, 12:27:05
Ort: Linköping
Kontakt:

Inlägg av gustavn »

Tack Icecap!
Hur löser man det praktiskt med själva interrupt-inkopplingen? Jag har läst i databladet att det finns en pinne RB0/INT, är det den som man ska koppla in pulståget på?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det kan vara ett sätt, sedan väljer man rätt interrupt-enable och kör.
Användarvisningsbild
gustavn
Inlägg: 297
Blev medlem: 30 november 2004, 12:27:05
Ort: Linköping
Kontakt:

Inlägg av gustavn »

Tack, för snabbt svar, nu fungerar det! Men en konstig sak är att det bara verkar vara 1800 pulser / varv. Har provat att vrida motor axeln precis ett varv och den visar då ca 1800. Vad kan det bero på? Om det är av intresse så ser min kod ut så här:

Kod: Markera allt

char *siffra[7];
int i=0;

void interrupt(){
 INTCON.INTE = 0;
 if(PORTD.F3==0){
  i++;
 }
 else{
  i--;
 }
 INTCON.INTE = 1;
 INTCON.INTF = 0;
}


void main(){
 INTCON.INTE = 1;
 INTCON.PEIE = 1;
 INTCON.GIE = 1;
 OPTION_REG.INTEDG = 1;
 
 PORTB = 0;
 TRISB = 1;
 PORTD = 0;
 TRISD = 8;
 
 Lcd_Config(&PORTB,2,3,0,7,6,5,4);
 Lcd_Init(&PORTB);
 Lcd_Cmd(LCD_CURSOR_OFF);
 
 while(1){
  IntToStr(i,siffra);
  Lcd_Out(2,4,siffra);
 }
}
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Du får bara positiva *eller* negativa flanker. Sannolikt så räknar
tillverkaren med båda. Du kan vid varje interrupt ställa om INTEDG
dynamiskt så att du fångar båda flankerna, om det nu spelar någon roll...
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kod: Markera allt

void interrupt(VOID)
  {
  INTCON.INTE = 0; // VARFÖR?
  if(!PORTD.F3)
    {
    i++;
    }
 else
   {
   i--;
   }
 INTCON.INTE = 1;  // VARFÖR?
 INTCON.INTF = 0; // VARFÖR? Edit: Därför!!!
  }
Varför har du med dessa INTCON-grejer?

Du har 3600 pulser om du räknar alla fram (eller bak) flankor på båda pulstågen. Du kan åstadkomma det vid att ha 2 interrupt som räknar på ovanstående sätt.
Senast redigerad av Icecap 9 februari 2008, 21:30:45, redigerad totalt 1 gång.
Användarvisningsbild
gustavn
Inlägg: 297
Blev medlem: 30 november 2004, 12:27:05
Ort: Linköping
Kontakt:

Inlägg av gustavn »

INTCON.INTE = 0; och INTCON.INTE = 1;
Har jag med för att det inte ska kunna bli en interrupt till innan den aktuella interrupten har räknats. Vet inte om det är nödvändigt.

INTCON.INTF = 0; Har jag med efter att ha läst detta i databladet:
INTF: RB0/INT External Interrupt Flag bit
1 = The RB0/INT external interrupt occurred (must be cleared in software)
0 = The RB0/INT external interrupt did not occur
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

.INTF-flaggan ska nollas av mjukvaran, mitt fel.

Men låt bli .INTE i interrupten, den ställer man i initialiseringen och sedan får det räcka.
Användarvisningsbild
gustavn
Inlägg: 297
Blev medlem: 30 november 2004, 12:27:05
Ort: Linköping
Kontakt:

Inlägg av gustavn »

Ok Tack!, då ändrar jag det. :)

Finns det fler interrupt-pinnar än RB0/INT jag kan använda?
Jag har sett att det står i databladet att det finns 15 interrupts på 16f877A men vet inte vilka som dom menar förutom RB0/INT?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Jag har sett att det står i databladet att det finns 15 interrupts på 16f877A
> men vet inte vilka som dom menar förutom RB0/INT?

Figure 14-10. (*SÅ* svart var det väl inte att se... :-) )

> Finns det fler interrupt-pinnar än RB0/INT jag kan använda?

Se kapitel 14.11.3. Vet dock inte om det passar in på ditt fall. Kanske...
Skriv svar