B0/INT interrupt crasht microcontroller

Ik heb hier een projectje waarbij ik voor menu navigatie gebruik maak van een rotary encoder. Die lees ik uit via een poort B0/INT interrupt, waarin ik dan de 2e "fase" van de encoder check. Het probleem is echter dat de microcontroller op willekeurige momenten crasht (16F876) op het moment dat ik de rotary encoder verdraai. Hij reset zich dan volledig naar het begin van het programma. Dit is niet na een vast aantal rotaties oid. Soms crasht hij bij een eerste "klik", de andere keer gaat het 5 minuten lang goed. De rest van het programma werkt wel perfect.

Hier is de ISR voor B0/INT:


static void interrupt isr(void) {
    //B0/INT interrupt
    if(INTF) {
	tmrDly = 0;
	sleepMinutes = 0;
	doWake = 1;

        if(rotPh2) {
		rotDir = ROTUP;
	} else {
		rotDir = ROTDOWN;
	}

	INTF = 0;
    }
}

Zelfs met een "lege" interrupt crasht de microcontroller na enige tijd spelen met de rotary encoder:


static void interrupt isr(void) {
    //B0/INT interrupt
    if(INTF) {
	INTF = 0;
    }
}

Verder is er nog een tmr0 en een UART receive interrupt. Het uitschakelen + verwijderen van beide heeft geen effect op het crashgedrag. Dat blijft doorgaan.

Iemand enig idee waar dit aan kan liggen?

Arco

Special Member

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

WDT staat uit:


__CONFIG(HS & UNPROTECT & PWRTDIS & WDTDIS & LVPDIS & BORDIS);

een niet afgehandelde interrupt misschien ?

Nope, heb alle interrupts handmatig ingesteld door direct naar INTCON te schrijven (INTCON = 0b11110000; ). Dit schakelt de volgende bits in:
- GIE
- PEIE
- T0IE
- INTE

INTE en T0IE worden allemaal netjes afgehandeld.
Alle interrupts behalve de INTE uitschakelen + verwijderen uit de ISR helpt ook niet. De microcontroller reset zich nog steeds.

Arco

Special Member

Pull-up aan MCLR ook niet vergeten? (of te hoog van waarde)
Beste iets van 3k3...10k met een 100nF naar Gnd.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Beide zijn aanwezig. 10K naar Vdd en 100nF naar gnd.
Lijkt me geen MCLR probleem, want als ik de rotary encoder met rust laat werkt het prima.

Het project is een GPS logger. Ik heb er een route van 1,5 uur gewoon mee kunnen loggen zonder resets. Zolang je maar van die rotary encoder afblijft...

Arco

Special Member

Het lijkt me dat er dan toch ergens iets lelijks in je code moet gebeuren...
RB0 staat ook niet als output? Probeer anders eens een gewoon drukschakelaartje i.p.v. de rotary.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Zelfs als ik mijn hele main loop reduceer tot dit:


for(;;) {

}

(en alle config en functie declaraties met rust laat) blijft het ding willekeurig crashen op een interrupt... Schakelaartje ga ik morgen eens testen, maar ik vermoed dat dit ook gewoon moet werken.

Edit:

Op 7 juli 2011 23:52:18 schreef Arco:
Ook zoals gezegd kijken dat RB0 niet als output staat. Dan werkt hij wel als input, maar trekt erg veel stroom...

TRISB0 is als input ingesteld... Dat lijkt me toch correct?

[Bericht gewijzigd door TheCrazyInventor op donderdag 7 juli 2011 23:55:27 (26%)

Arco

Special Member

Ook zoals gezegd kijken dat RB0 niet als output staat. Dan werkt hij wel als input, maar trekt erg veel stroom...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
JoWi

Special Member

Het is toch niet een heel "oude" 16F876 ?
Met een productiedatum uit 2002 of eerder ?

Ooit twee weken gespendeerd aan een soortgelijk random crash probleem met een interrupt (toevallig ook met een rotary encoder). Bleek het uiteindelijk een bug in 16F876A te zijn (chip revisie B0).

Een nieuwere chip besteld en het probleem was opgelost (en ik had flink wat tijd verspilt). Dit probleem is beschreven in het rev B0 errata sheet (ds80128f.pdf).

Ignorance is bliss

De datum stempel op de PIC is 062252S. Ik kan even nergens vinden hoe je die datum moet lezen, maar dit lijkt op week 22 van 2006.

Misschien moet je niet in je programma zoeken, maar zit je ergens met een elektrisch/EMC probleem.

It is so simple to be happy, but it is so difficult to be simple
JoWi

Special Member

Op 8 juli 2011 12:00:35 schreef TheCrazyInventor:
De datum stempel op de PIC is 062252S. Ik kan even nergens vinden hoe je die datum moet lezen, maar dit lijkt op week 22 van 2006.

Yep, daar is die bug al in gefixt. Dan moet je na een reset maar eens kijken waardoor die reset komt (TO en PD), misschien heb je glitches op de power of reset lijn.

Ignorance is bliss

OK, probleem gefixt... Hoe? Weerstandje in serie met de voeding van de encoder gesoldeerd.

Ik dacht vanmorgen dat het aan het ontdenderen kan liggen. Dus daarom eens een potmetertje van 1k in serie met de voeding van de encoder geplaatst. Dat bleek te werken. Sommige kliks zag hij niet, maar hij crasht in ieder geval niet...
Vervolgens die potmeter terug gaan draaien. Op een gegeven moment deed hij het lekker ZONDER te resetten. Dat bleek bij 10 ohm te zijn. Ik kon zelfs nog tot 5 ohm zakken... Daar heb ik het maar op gehouden en dat heb ik er tussen gebakken.

Ik begrijp nu nog steeds niet waarom het ding eerst wel deed resetten. Veel interrupts achter elkaar (vanwege denderen) is toch geen reden om te resetten...? En 5 ohm is toch totaal niks op de 10K pulldown die er al zat...

Lucky Luke

Golden Member

Denderen -> veel interrupts -> stack ontploft?

Alleen, ik denk niet dat 5R in serie het denderen oplost... Dan heb je toch een RC combinatie nodig.

Eluke.nl | handgetypt | De mens onderscheid zich van (andere) dieren door o.a. complexe gereedschappen en bouwwerken te maken. Mens zijn is nerd zijn. Blijf Maken. (Of wordt, bijvoorbeeld, cultuurhistoricus)

Hoezo ontploft de stack? Als er een interrupt is geweest, worden de interrupts uitgeschakeld. De INT interrupt word afgehandeld en vervolgens worden de interrupts weer ingeschakeld. De ISR word vervolgens weer aangeroepen vanwege dender en het hele verhaal hierboven begint weer opnieuw... De stack word dan nu toch niet veel groter? En daarbij, er is plaats zat op mijn stack. Programma is niet zo complex.

Arco

Special Member

Ik vind dit soort 'fixes' maar griezelig... (Iets doen 'omdat 't werkt'...)
Moet een andere oorzaak zijn. (Dender kan een MCU niet laten vastlopen of resetten)
Ook ontkoppelingsc 100nF aanwezig tussen Vcc en Gnd bij PIC?

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

@inventor, een klassieke stack ontploft gebeurt als je interrupt niet vanzelf de interrupts uitzet en/of aanzet. Hoe dat in de PIC ook al weer werkte weet ik niet meer.

Ik zie jou code iets doen als INTF = 0. Mogelijk zet je daarmee je interrupts al weer aan. Als er dan al een interrupt staat te wachten.... gaat ie nog voordat ie de return from interrupt gedaan heeft weer de interrupt routine in. Die moet returnen naar de eerste interrupt routine, dus dat kost een extra stack positie. Enz. enz....

Is dat gedoe met "intf" nodig? .... effe gegoogled: ja. OK.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/

@ arco: ik vind deze "fix" ook maar niks. Ik snap gewoon niet hoe dit kan werken... Als ik die weerstand weg neem reset hij zich weer mooi, zoals hij altijd deed. Soldeer ik hem terug --> alles goed. Misschien wat Peter al zei, een EMC probleem oid... De flanken uit die encoder zijn vrij krap.

Heb al verschillende dingetjes geprobeert zoals een grotere waarde voor de pulldown, grotere ontdender capaciteit, kleinere ontdender capaciteit, maar het probleem blijft gewoon.

@rew: als de PIC de ISR verlaat, word er een context restore gedaan. Daar worden de interrupts ook weer ingeschakeld. Als ik het goed begrepen heb, heeft de ISR de stack alweer verlaten voordat de interrupts weer worden geactiveerd.

[Bericht gewijzigd door TheCrazyInventor op vrijdag 8 juli 2011 16:30:14 (20%)

Arco

Special Member

Je kunt de 16f876a ook vervangen door een 16f1936. Pin compatible, goedkoper, en kan veel meer...
Die heeft een tweemaal zo grote stack, en ook een 'stack overflow' flag die je kunt testen.
Zou met wat kleine wijzigingen in de firmware moeten werken.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Probeer eens een 100nF tussen de RB0/INT en GND te zetten ? Dit zal het dender-probleem op lossen...
Uiteraard ook een 100nF tussen de GND & +5V, dichtbij de µC

Master Industriële Wetenschappen: Elektronica-ICT

@roel: cap op B0/INT zit er al:

Op 7 juli 2011 23:31:25 schreef TheCrazyInventor:
Beide zijn aanwezig. 10K naar Vdd en 100nF naar gnd.

Ontkoppel condensators op de voeding van de pic is er ook. Het project is verder batterij gevoed (3 * lion) en de spanning wordt geregeld met een 7805. Mijn scoop vindt dat de voeding zeer stabiel is. Het hele project trekt ook maar slechts 60mA.

free_electron

Silicon Member

zodra je de interrupt handler binnevalt moet je de interrupt disablen.. waar gebeurt dat in je code.

en die stack. ik meen me te herinneren dat de 16 reeks hoop en al 4 of 6 levels heeft op zijn stack ....

dat gedoe met die 5 ohm weerstand wijst op een mogelijke hardware probleem...

ben je zeker dat de logische nieveaus niet boven de voeding van de pic uit komen ?

zet eens een scoop op de voedingsspanning van de pic en draai eens aan de encoder ...

Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
JoWi

Special Member

Op 8 juli 2011 19:07:10 schreef free_electron:
zodra je de interrupt handler binnevalt moet je de interrupt disablen.. waar gebeurt dat in je code.

Bij een PIC zijn de interrupts automatisch disabled, enablen gebeurt met de retfie instructie.

Ignorance is bliss