
Problem med interrupt på PORTB.
> Jag får in en periodisk dataström av ettor och nollor på RB5.
Bara "periodisk dataström" säger inte ett smack...
Hur ser den ut ? Periodtider ? Min-tid för en låg respektive hög puls ?
Sen angående att lägga BCF av RBIF flaggan *före* du läser PORTB, så
kan de få det hela att *se ut* som att det fungerar bättre. Men *INTE*
p.g.a något timing-fenomen som det har skivits om här.
RBIF är flaggan för "PORTB change interrupt", och den flaggan går bara att
clear *EFTER* att man har läst PORTB. Gör du det före så sätts den bara
direkt igen.
SE ***DATABLADET*** SIDAN 36 : "5.2 PORTB and TRISB Registers" ! :
> The user, in the interrupt service routine, can clear the interrupt in the following manner:
>
> a) Any read or write of PORTB. This will end the mismatch condition.
> b) Clear flag bit RBIF.
>
> A mismatch condition will continue to set flag bit RBIF. Reading PORTB will
> end the mismatch condition and allow flag bit RBIF to be cleared.
Det som händer med Icecap's ändring är att RBIF *aldrig* clearas, din
ISR loopar hela tiden och portpinnarna kopieras kontinuerligt, oavsett
om det har varit något ändring eller inte. Även om det till det yttre
i princip ger den funktion du ville, så är det sannolikt inte så du ville
att det skulle fungera. Då hade det varit enklare att skippa interrupt
och lägga en loop i main() som bara kopierade pinnarna hela tiden.
Så din originalkod är i princip korrekt.
Men det finns två saker som är nyckeln til problemet och som skulle ha
varit med i första inlägget, hur inpulserna ser ut och dina CONFIG inställningar.
Innan vi vet timingen på in-pulserna (och vilka krav du har på "följsamhet")
så går det naturligtsivs inte heller att säga något om val av programeringsspråk.
Eller om processorn behöver köras snabbare.
Beroende på vilken följsamhet du behöver mellan RB5 och RB3, så
kanske det även finns andra sätt att lösa det på. Om kraven är "låga",
så skulle kopieringen av pinnarna kunna ske i ett timer-interrupt vilket
är lite lättare att få stabilt.
Dangraf har dessutom helt rätt angående de övriga RB pinnarna. Om det
är "open inputs" så kommer de att ge falska interrupt. Utan tvekan. Du
kollar ju inte heller att det är just *RB5* som har ändrats !
Summerat så är tråden ett bra exempel på hur det det hela spårar ur i olika
felaktiga riktningar p.g.a att mycket nyckelinformation utelämnats i förstainlägget.
Och även att inte rätt följdfrågor ställdes direkt...
Slutligen några möjliga felorsaker :
- WDT
- Falska interrupt från andra RB-pinnar (kommer att ibland att dölja ändringar på RB5).
- Snabba spikar/störningar på insignalen.
Bara "periodisk dataström" säger inte ett smack...
Hur ser den ut ? Periodtider ? Min-tid för en låg respektive hög puls ?
Sen angående att lägga BCF av RBIF flaggan *före* du läser PORTB, så
kan de få det hela att *se ut* som att det fungerar bättre. Men *INTE*
p.g.a något timing-fenomen som det har skivits om här.
RBIF är flaggan för "PORTB change interrupt", och den flaggan går bara att
clear *EFTER* att man har läst PORTB. Gör du det före så sätts den bara
direkt igen.
SE ***DATABLADET*** SIDAN 36 : "5.2 PORTB and TRISB Registers" ! :
> The user, in the interrupt service routine, can clear the interrupt in the following manner:
>
> a) Any read or write of PORTB. This will end the mismatch condition.
> b) Clear flag bit RBIF.
>
> A mismatch condition will continue to set flag bit RBIF. Reading PORTB will
> end the mismatch condition and allow flag bit RBIF to be cleared.
Det som händer med Icecap's ändring är att RBIF *aldrig* clearas, din
ISR loopar hela tiden och portpinnarna kopieras kontinuerligt, oavsett
om det har varit något ändring eller inte. Även om det till det yttre
i princip ger den funktion du ville, så är det sannolikt inte så du ville
att det skulle fungera. Då hade det varit enklare att skippa interrupt
och lägga en loop i main() som bara kopierade pinnarna hela tiden.
Så din originalkod är i princip korrekt.
Men det finns två saker som är nyckeln til problemet och som skulle ha
varit med i första inlägget, hur inpulserna ser ut och dina CONFIG inställningar.
Innan vi vet timingen på in-pulserna (och vilka krav du har på "följsamhet")
så går det naturligtsivs inte heller att säga något om val av programeringsspråk.
Eller om processorn behöver köras snabbare.
Beroende på vilken följsamhet du behöver mellan RB5 och RB3, så
kanske det även finns andra sätt att lösa det på. Om kraven är "låga",
så skulle kopieringen av pinnarna kunna ske i ett timer-interrupt vilket
är lite lättare att få stabilt.
Dangraf har dessutom helt rätt angående de övriga RB pinnarna. Om det
är "open inputs" så kommer de att ge falska interrupt. Utan tvekan. Du
kollar ju inte heller att det är just *RB5* som har ändrats !
Summerat så är tråden ett bra exempel på hur det det hela spårar ur i olika
felaktiga riktningar p.g.a att mycket nyckelinformation utelämnats i förstainlägget.
Och även att inte rätt följdfrågor ställdes direkt...
Slutligen några möjliga felorsaker :
- WDT
- Falska interrupt från andra RB-pinnar (kommer att ibland att dölja ändringar på RB5).
- Snabba spikar/störningar på insignalen.
Har testat lite mer nu.
TRISB = 0b00100000 funkar alldeles utmärkt. Så det var som dangraf och Sodjan bla sa, att det kan ju komma interrupt på dem andra pinnarna
(WDT är avstängd )
>Dangraf har dessutom helt rätt angående de övriga RB pinnarna. Om det
>är "open inputs" så kommer de att ge falska interrupt. Utan tvekan.
Jo jag märkte det
. Men hur skall man hindra at dem ger falska interrupt?
Skall man aktivera internal pull-up?
När skall man använda pull-ups rent generellt?
Det här är koden som jag kör med nu och som verkar fungera:
TRISB = 0b00100000 funkar alldeles utmärkt. Så det var som dangraf och Sodjan bla sa, att det kan ju komma interrupt på dem andra pinnarna
(WDT är avstängd )
>Dangraf har dessutom helt rätt angående de övriga RB pinnarna. Om det
>är "open inputs" så kommer de att ge falska interrupt. Utan tvekan.
Jo jag märkte det

Skall man aktivera internal pull-up?
När skall man använda pull-ups rent generellt?
Det här är koden som jag kör med nu och som verkar fungera:
Kod: Markera allt
char old_valueOf_F5;
void main(){
TRISB = 0b111100000; //1 = input, 0 = output
INTCON.RBIE = 1; //enable RB interrupt.
INTCON.PEIE=1; // pheripheral enable interrupt.
INTCON.GIE=1; // global enable interrupt
while (1){
delay_ms(500);
PORTB.F0 = ~PORTB.F0; // To check that we dont get stuck in interrupt().
}
}
void interrupt(void){
if(INTCON.RBIF == 1){
INTCON.RBIF = 0;
if(PORTB.F5 != old_valueOf_F5){
PORTB.F3 = PORTB.F5;
old_valueOf_F5 = PORTB.F5;
}
}
}