Pic18 + timer + interrupts

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
stormbringer
Inlägg: 96
Blev medlem: 12 augusti 2003, 12:11:39
Ort: Lindesberg

Pic18 + timer + interrupts

Inlägg av stormbringer »

Tjenare. Jag skulle vilja lägga en rutin som gör att jag får en interrupt varannan millisekund, och dessutom skapar en interrupt när RB0 ändras.. Jag använder microchips c-kompilator, och får helt enkelt inte till det.. Tänkte lägga timern som lågprioritet & RB0 som högre prioriterad.. Problemet är att jag får RB0-interrupten hela tiden efter den aktiverats första gången.. Fungerar perfekt om jag stänger av interrupten för timer1...

Jag har dessutom problem att räkna ut hur jag ska använda timern så den gör en interrupt varannan ms. tips? har tyvär rinte koden tillgänglig idag..
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Är det jätte-superduper-viktigt att det ska vara exakt 2,000 ms? Isåfall blir det en liten gnutta svårare.

Vilken timer använder du för att skaffa interrupten? Och vilken PIC menar du mer specifikt?

Du har inte glömt att nollställa RB0-interruptflaggan i isr:en?

Edit: tiden
Senast redigerad av $tiff 21 december 2004, 11:12:44, redigerad totalt 1 gång.
Michel
Inlägg: 436
Blev medlem: 3 februari 2004, 18:08:04
Ort: Stockholm

Inlägg av Michel »

Inte för att jag vet hur det ser ut i ditt fall med AVR kretsen och din C kompilator, men

Vissa interrupter kräver att man manuellt resettar interrupt-flaggan. Detta görs lämpligen när man är på väg att lämna interrupt-rutinen och kan acceptera en ny interrupt.

För att få en timer till exakt 1mS finns det väl primärt 2st olika sätt.
1. Räkna fram den med hjälp av kristall / CPU klocka => antal maskincykler => nedräkningsvärde för timer => antal cyckler för att hoppa in i interrupt.
2. Toggla en portpinne i timern's interrupt-rutin och mät tiden på denna portpinne med ett oscilloskop.

...eller använd båda - räkna först och fintrimma / korrigera med hjälp av portpinnen.

Tänk på att även om du räknar ut din timer korrekt så kanske din kod - i interrupt-rutinen - tar en viss tid eller olika tid beroende på hur och vad du gör i den.
stormbringer
Inlägg: 96
Blev medlem: 12 augusti 2003, 12:11:39
Ort: Lindesberg

Inlägg av stormbringer »

Tjenare.. inte jätteviktigt att det är exakt, kör dessutom RC-osc.. Jag använder en pic18F458. Jag nollställer RB0 efter varje interrupt, och det fungerar perfekt sålänge jag inte använder timer1/2/3 till interrupt. Så fort jag aktiverar någon av dem, så fastnar den.. (mplab sim, har satt breakpoints på interruptfunktionerna)...

Själva bygget är en ledmatris.. Jag vill ha en interrupt som anropas efter ett givet intervall för att scrolla kolumnerna, och en annan interrupt för rb0 (data från PC'n), och en mainloop, som tänder/släcker varje kolumn, så ofta den kan.. Har gjort en teckenuppsättning på 240 byte, (char-vektor), en vektor som lagrar meddelandet, en vektor med bredd (i bytes) för varje tecken.. En 23 byte lång vektor för kolumnerna,

//bokstaven A:
CharMap[0]=0b00111110;
CharMap[1]=0b00001001;
CharMap[2]=0b00001001;
CharMap[3]=0b00111110;

Vektorn Message=själva meddelandet, innehåller referenser till CharMap-vektorn.

kolumnerna scrollas via en for-loop, är osäker på om jag kommer ihåg koden till 100 %...

for(a=0;a<23;a++)
{
Columns[a]=Columns[a+1];
}

columns[23]=CharMap[Message[MsgCurrent]+charOffset];
charOffset++
if(charOffset>CharMap[Message[MsgCurrent]+CharWidth[Message[MsgCurrent]])
{
charOffset=0;
MsgCurrent++;
}

Det är alltså den loopen som ska anropas enligt det givna intervallet.

edit: Meningen med att slösa bort så mycket minne är att datorn BARA ska kommunicera med picen för att skicka meddelandet, meddelandet ska sedan sparas i EEPROM & gå igång automatiskt...
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

Hmm, kanske hjälper om vi får se en kommenterad del av interruptinitieringen.

Du skulle kunna sätta en 16-bits timer att räkna från 2^16 - 10000 = 55536. Har du en 20 MHz kristall och 1:1 prescaler resulterar detta nämligen i ett interrupt varannan millisekund.

En 8-bits timer med 64 i prescaler går också bra. Låt den räkna 156 steg så motsvar det ca 2 ms @ 20 MHz.

För båda exempel krävs det att du laddar timern med ett nytt värde i ISRen, vilket kan de lite tidsfel, men som jag tolkade det är tiden inte speciellt viktigt egentligen? Annars går det säkert att lösa helautomatiskt med en CCP-funktion.
stormbringer
Inlägg: 96
Blev medlem: 12 augusti 2003, 12:11:39
Ort: Lindesberg

Inlägg av stormbringer »

Hmm. Tack för den informationen! Blir definitivt lättare att tänka ut hur jag ska skala om det! har tyvärr inte koden i huvudet för interruptrutinen, så jag kan inte skriva den här (sitter på jobbet). Får helt enkelt experimentera. :)
Skriv svar