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..
Pic18 + timer + interrupts
-
- Inlägg: 96
- Blev medlem: 12 augusti 2003, 12:11:39
- Ort: Lindesberg
Ä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
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.
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.
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.
-
- Inlägg: 96
- Blev medlem: 12 augusti 2003, 12:11:39
- Ort: Lindesberg
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...
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...
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.
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.
-
- Inlägg: 96
- Blev medlem: 12 augusti 2003, 12:11:39
- Ort: Lindesberg