Timer - Interruptafhandeling

Postby arjen h. » Wed Jan 16, 2008 12:00 am

Betreft de timers, even in de gaten houden dat de controller op 48 Mhz loopt en niet op 20 MHz (ik had dus een klokje dat een factor 2,4 te hard liep).

Voor een interrupt van 1 s, prescaler = 256 en preload = 18660.
Voor een interrupt van 100 ms, prescaler = 32 en preload = 28035.
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

Postby arjen h. » Sun Feb 17, 2008 12:00 am

Een probleem met externe interrupt 2. Ik ben er al even mee aan het knoeien, maar ik zie het even niet. Wellicht dat iemand van jullie de vinger op de zere plek kan leggen ?!?!

Ik bied op pootje RB2 een blokgolf aan waarvan ik op zowel de opgaande als de neergaande flank een interrupt-routine wil uitvoeren. Om te testen heb ik de frequentie zeer laag staan, ongeveer 0,3 Hz (1x in de 3 sec. dus).

 
void UserInit(void)
{
OpenRB2INT( PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF);
}

void high_isr(void)
{
if (INTCON3bits.INT2IF == 1)
{
wInterrupt++; // globale counter
UpdateRpm(wInterrupt);
}
}

void UpdateRpm(word wInterrupt)
{
// overnemen counter om later te displayen
wDisplayInterrup = wInterrupt;

// reset interrupt
INTCON3bits.INT2IF = 0;

// wisselen van flank
if (INTCON2bits.INTEDG2)
{
OpenRB2INT( PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_OFF);
}
else
{
OpenRB2INT( PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF);
}



Wat ik nu zie is dat als de blokgolf 'laag' is de interrupt-counter keurig stil blijft staan.
Is de blokgolf 'hoog' dan loopt de interrupt-counter rappido op wat aangeeft dat de interrupt routine continue wordt aangeroepen.

Het verwarrende vind ik dat ik denk dat de interrupt alleen op een EDGE kan optreden aangezien ik kan instellen RISING_EDGE_INT en FALLING_EDGE_INT.
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

Postby pjongen » Sun Feb 17, 2008 12:00 am

Arjen,

Vooropgesteld dat ik nog niet gespeeld heb met de externe interupt op deze manier.

Maar zoals je het beschrijft lijkt het erop dat het omzetten dan het INTEDGx bit meteen weer een interupt veroorzaakt als de input hoog is. Dat staat wel nergens beschreven, maar ja, kan best een gevolg zijn van het ontwerp van de circuits daaromheen.

Ik zou daarom INT2IE disable zetten gedurende het "ompolen" van de edge en pas weer enabelen als je klaar bent met die operatie. Dan ook nog voor alle zekerheid vóór het enablen de INT2F resetten.

In pricipe moet je ook het INT2IF-bit pas resetten als je bereid bent weer een volgende interupt van dat type af te handelen.

Ik ben benieuwd.
pjongen
 
Posts: 64
Joined: Thu Jan 02, 2014 3:37 pm

Postby arjen h. » Sun Feb 17, 2008 12:00 am

pjongenIk zou daarom INT2IE disable zetten gedurende het "ompolen" van de edge en pas weer enabelen als je klaar bent met die operatie. Dan ook nog voor alle zekerheid vóór het enablen de INT2F resetten.

In pricipe moet je ook het INT2IF-bit pas resetten als je bereid bent weer een volgende interupt van dat type af te handelen.


Ja, kan ik mij helemaal in vinden, ik heb/had hier ook mee zitten spelen. Zelfs de algehele interrupt disable/enable gebruikt.

Ik heb er even dit van gemaakt:

 
void UserInit(void)
{
OpenRB2INT( PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF);

mEnableInterrupt(); // enable all interrupts
}

void high_isr(void)
{
if (INTCONbits.TMR0IF == 1) // timer interrupt
{
UpdateI();
}
if (INTCON3bits.INT2IF == 1)
{
INTCON3bits.INT2IE = 0; // disable RB2 interrupt

wInterrupt++; // global counter
UpdateRpm(wInterrupt);

INTCON2bits.INTEDG2 = !INTCON2bits.INTEDG2; // interrupt opposite edge
INTCON3bits.INT2IF = 0; // reset RB2 interrupt
INTCON3bits.INT2IE = 1; // enable RB2 interrupt
}
}

void UpdateRpm(word wCount)
{
wFlipper = wCount;

if (INTCON2bits.INTEDG2)
{
mFLIP_A = 1; // led aan
}
else
{
mFLIP_A = 0; // led uit
}
}


Probleem nog niet opgelost dus...
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

Postby pjongen » Sun Feb 17, 2008 12:00 am

Even voor de goede orde:

Het werkt toch zonder die "edge flip"? Op zowel leading als trailing appart??

Die controle led FLIP_A, die knippert tijdens het hoog singaal veronderstel ik?

Ben je trouwens bezig op die manier een rotary encoder te interfacen??
pjongen
 
Posts: 64
Joined: Thu Jan 02, 2014 3:37 pm

Postby arjen h. » Sun Feb 17, 2008 12:00 am

- Ook zonder de edge flip werkt het niet...

- FLIP_A gaat keurig met de blokgolf mee aan en uit en als hij aan is dan lijkt het constant (heb thuis geen scoop), led lijkt ook niet gedimt als gevolg van een (50%) dutycycle. Uit is in ieder geval uit.

- Nee, geen rotary encoder. Bedoeling is meten van toerental van een machine, normaal gesproken tussen 50 en 1500 Rpm en, op 0 en 180 graden (hiervoor dus opgaande en neergaande flank) schakelen van een 2-tal ventielen.


Ik kwam in de knoei met het bepalen van de tijd (=rpm) tussen 2 opgaande flanken, zeer instabiel. Met de counter in de interrupt routine meen ik te zien dat deze routine bij een hoog signaal continue wordt aangeroepen, maar ik zou dan inderdaad ook verwachten dat FLIP_A zou flippen.

Ik heb even wat getest met het volgende in ProcessIO().
Tellertje loopt keurig met 1 op bij elke flank.

 
BOOL bRB2 = FALSE; // globaal
if (bRB2 != PORTBbits.RB2)
{
wFLIPPER++;
bRB2 = PORTBbits.RB2;
}


Ik zit toch wel op de goede gedachte dat de counter alleen opgehoogd mag (zou mogen) worden bij een flank op RB2?


EDIT
Edge flip uit, oftewel alleen opgaande flank, en mFLIP_A = !mFLIP_A in UpdateRpm(). Als de led nu 'uit' gaat, dan zie ik wel wat geknipper.
Reden genoeg om aan te nemen dat als de led 'aan' gaat deze ook knippert, maar dit met het oog niet is te zien.
Frappant is dat de led zich niet vergist, ondanks het knipperen is hij wel 'uit' als hij uit moet gaan en 'aan' bij aan. Lijkt wel denderen van een schakelaar (?!?!).
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

Postby pjongen » Mon Feb 18, 2008 12:00 am

Arjen,

Ik heb even een pushbutton naar ground aan PortB2 gehangen (met een C erover voor debounce).

Bij mij werkt de volgende code als verwacht dus ik neem maar over wat er bij mij in de source staat:

 
// User Intit
OpenRB2INT (PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_ON);


 
// Deze staat bij mij in main, bij jou in int.c of zo
#pragma interruptlow _isrPJ

void _isrPJ (void)
{
if (INTCONbits.TMR0IF==1)
{
updateI();
INTCONbits.TMR0IF = 0;
}
if (INTCON3bits.INT2IF ==1)
{
updateII();
INTCON2bits.INTEDG2 = !INTCON2bits.INTEDG2; //Flip edge
INTCON3bits.INT2IF =0;
}

}



 
void updateII(void)
{
itoa(++Rcounter,P4Cnt);
while (BusyXLCD());
SetDDRamAddr(0x06);
while (BusyXLCD());
putsXLCD(P4Cnt);
}


De updateII routine displayed een counter op mijn LCD scherm.
UpdateI doet hetzelfde met een andere counter.

Als ik zonder het statement "flip edge" deze code inzet dan verhoogd de counter met 1 voor iedere push. Zoals verwacht.

Als ik het statement "Flip Edge" erin zet dan verhoogd de counter bij het indrukken en daarna weer bij het loslaten. Ook zoals verwacht.

Ik zit nu al een tijdje naar jouw code te staren en vraag mij af wat er nu anders is...

Je hebt vergeten de timer interupt te clearen, of doe je dat ergens anders?.
 INTCONbits.TMR0IF = 0;

Maar daaruit kan ik niet helemaal verklaren dat je counter alleen bij 'hoog' van portB blijft doorlopen. Ik zou eerder verwachten dat het bij beide toestanden zou zijn.

Ohja, ik laat de pull-ups on omdat ik met een switch werk, maar ook hiervan kan ik mij niet echt voorstellen dat het jouw probleem veroorzaakt.

Maar in ieder geval, de code hierboven werkt zoals jij wil. Als die bij jou niet werkt dan toch ergens anders zoeken.

Ik heb ook even portB2 aan een van de status leds gehangen. Ik zie de counter mooi oplopen bij elke 'aan' en 'uit'. Dus het werkt ook met logische signalen, ook al komen die in dit geval uit de PIC zelf.
pjongen
 
Posts: 64
Joined: Thu Jan 02, 2014 3:37 pm

Postby arjen h. » Mon Feb 18, 2008 12:00 am

Ik heb mijn code gestript tot enkel functionaliteit interrupt op RB2 en heb dat werkend. Nu (waarschijnlijk 2e helft van deze week) de oude code weer terug zetten ... en kijken waar het probleem weer om de hoek komt kijken.

Voor de geinteresseerden hieronder een scoopbeeld van het bronsignaal (groen) en uitgang met led (geel). Zie daar de ongewenste pulsen tijdens het 'hoog' zijn van het bronsignaal.

Als ik de 'foute' heb gevonden zal ik dit hier nog even melden.

Speciale dank voor Peter voor het on- en offline meedenken.

Edit: Deel van de code terug gezet, combinatie van interrupts Timer0 en RB2 gaat goed.
Attachments

[The extension bmp has been deactivated and can no longer be displayed.]

Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

Postby velswijk » Sun Feb 24, 2008 12:00 am

Arjen,

Uit nieuwsgierigheid: is er een reden waarom je de RB2 interrupt gebruikt en niet de change-detect interrupts van RB7:RB4?

vr.gr.
PvE
velswijk
 
Posts: 16
Joined: Thu Jan 02, 2014 3:42 pm

Postby arjen h. » Sun Feb 24, 2008 12:00 am

Op zich geen specifieke reden, behalve dan dat een RB2 een eigen vlag heeft en RB7:RB4 een gezamelijke. Bij de laatste moet je dus nog weer testen welke van de 4 het is geweest. RB2 werkt ook op flanken, waarbij je ook kan aangeven rising of falling edge (in mijn geval wenselijk).

@velswijk: als je tips, tricks, overwegingen of bepaalde ideeen hebt over mijn probleem, dan hoor ik dat graag!


Mijn originele code heb ik weer terug geplaatst en kom tot de conclusie dat in de functie ProcessIO( ) een call (of beide in mijn geval) naar OpenADC( ) roet in het eten gooit. Als ik de OpenADC( )'s uit commentarieer, dan heb ik geen storing op de RB2 interrupt.

Iemand hier een idee over?
Het Elektor forum is voor de lezers; voor een vraag aan de redactie kun je het beste Elektor een email sturen.
arjen h.
Moderator
 
Posts: 1290
Joined: Thu Jan 02, 2014 10:40 am

PreviousNext

Return to 2007-11 USB data-acquisitiekaart

Who is online

Users browsing this forum: No registered users and 1 guest