Beste,

Ik ben aan een project aan het werken waarbij ik problemen heb met het gebruik van een interrupt. De volledige probleemstelling heb ik zo volledig mogelijk omschreven in onderstaande link. Ik hoop dat er mensen zijn die me hier mee kunnen helpen.

http://sites.google.com/site/controllerselektronica/

als vast bedankt

Het verschuiven van PORTB tov. INT1 wordt IMHO veroorzaakt doordat main() in een lus "Status" en "zerocross" zit te bemonsteren. Als INT1 getriggerd wordt onmiddelijk na het checken van zerocross, duurt het veel langer voor Timer0 gestart wordt dan wanneer de interrupt juist daarvoor plaats vindt.
Oplossing: start Timer0 in de INT1-ISR.

Wat losse opmerkingen:
Het is onnodig de interrupt-flaggen in GIFR handmatig te wissen. Dat gebeurt automatisch bij het uitvoeren v/d ISR.
Deze zijn niet hetzelfde:


volatile unsigned zerocross = 0;
volatile unsigned char zerocross = 0;

Wat andere compilers er van maken weet ik niet, maar bij avr-gcc wordt zerocross bij default een unsigned int! Dat kost je onnodige instructies (18 bytes) en processortijd.

Het starten van de timer0 in de interruptroutine geeft hetzelfde resultaat.

Wat de losse opmerkingen betreft, bedankt.

Nog wat losse opmerkingen dan... :-)

Ik heb enkel rekening gehouden met de "#ifdef PS_8" code. Bij de overige prescaler-opties ontbreekt "TCNT0 = 0;". Maar dat weet je zelf ook, veronderstel ik.

Je kan daarnaast de prescaler ook resetten, alvorens Timer/Counter0 te herstarten. Als je dat in de INT1-ISR uitvoert, start je met TCNT0 die op 0 staat en een prescaler die vanaf 0 begint. Ik kan me niet voorstellen, wat er dan nog verschuivingen kan veroorzaken. Maar ik kan me ook vergissen...

Let wel op met het resetten v/d prescaler: ook Timer/Counter1 gebruikt die. Dat gaat nare resultaten geven als Timer/Counter1 in actie is en gebruik maakt van de prescaler (maar niet als hij de volle systeem-klok gebruikt, dunkt me).

Een aanpak die dit probleem omzeilt, zou er zo kunnen uitzien:
Laat Counter/Timer0 zonder prescaler draaien.
Voorzie een overflow-ISR voor Timer/Counter0.
Activeer het TOIE0-bit in het TIMSK-register, zodat deze ISR geactiveerd wordt als TCNT0 van 255 naar 0 gaat.
Laat deze ISR een teller bijhouden, en hem bij een bepaalde tellerstand resetten en een actie (het toggelen van PORTB, enz.) uitvoeren. Dat geeft je de mogelijkheid hem als prescaler met een deeltal van bv. 10 of 234 te gebruiken - het kost je wel processortijd, wees dus zuinig met instructies.

De INT1-ISR kan nu zowel TCNT0 als de overflow-ISR teller op 0 zetten.