C van uit een interrupt een andere interrupt aanroepen ?

trix

Golden Member

hallo,

de vraag is eigenlijk het geen wat in de titel staat:
kan je vanuit een interrupt een andere interrupt aanroepen ?

ik laat een timer lopen (timer1) en op een compare match gaat hij naar een interrupt routine.
binnen in die routine start ik een nieuwe timer (timer0) waar ik bij een (weer een) compare match een nieuwe interruptroutine wil starten.
gaat dat ?

probleem wat ik wil oplossen staat in deze topic onderaan:
https://www.circuitsonline.net/forum/view/150606

alvast bedankt.

eigenwijs = ook wijs

Het zal misschien wel kunnen maar is wel een heel smerige manier van programmeren. Laat beide timers gewoon lopen en gebruik flags voor de status.
Je start trouwens geen nieuwe interrupt routine zo, dat doet de timer.

Of geneste interrupts toegestaan zijn hangt van processor en compiler af...

[Bericht gewijzigd door Arco op 2 augustus 2020 12:32:57 (15%)]

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

Ja geen probleem.

Je kunt binnen een interrupt service routine voor timer1 best wel een andere timer instellen zodat die later een eigen interrupt genereert. Niks mis mee.

Of andere dingen doen, wat je maar wilt. Je kunt ook bijvoorbeeld data in een buffer zetten en dan de uart interrupt aanzetten om die te gaan versturen.

Wat lastiger is is om direct een andere interrupt service routine aanroepen alsof het een subroutine is. Dat kan wel in principe maar heeft bijwerkingen die je niet altijd kunt overzien. Als dat l nodig zou zijn dan kun je beter een deel van die ISR afspliten en een eigen functie van maken.

Je kunt een andere interrupt aanzetten, dat is niet hetzelfde als de interrupt service routine aanroepen; die wordt immers pas uitgevoerd zodra de bijbehorende gebeurtenis heeft plaatsgevonden. Gewoonlijk doe je in de ISR ook alleen dingen die daarmee te maken hebben, dus het is meestal niet zinnig om de ISR zelf uit te voeren; er is immers nog niets gebeurd, en als je onterecht een interrupt acknowledge genereert loop je het risico de werkelijke interrupt te missen.

Ik krijg sterk de indruk dat je nog niet begrijpt hoe interrupts echt werken, en hoe je ze hoort te gebruiken; ik zou je aanraden dat wat meer over te gaan lezen.

Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Hoeben

Golden Member

Maak gewoon 2 routines die je kunt aanroepen vanuit interrupts.

Maak een verschil tussen de interrupt vanuit de CPU en de routine die je dan aanroept. Gooi dat niet op een hoop.

trix

Golden Member

het is niet aan te raden begrijp ik, mits onder de juiste voorwaarden die ik met mijn beperkte programeer skils niet kan overzien.
ik kijk naar een andere oplossing voor mijn probleem. tnx.

eigenwijs = ook wijs
High met Henk

Special Member

Sommige timers hebben 2 compare interrupt flags..
Kun je daar wat mee??

E = MC^2, dus de magnetische compatibiliteit doet kwadratisch mee???

In dat andere plaatje wat je gepost heb in die vorige thread is inderdaad precies wat ik bedoelde.

Je hebt helemaal geen 2 interrupts nodig.

Echter je tekent wel mooi een puls van 2 ms breed maar in werkelijkheid is het maar een pulsje van enkele instructies: Op die opgaande flank kom je binnen in je ISR, dan lees je de input van je IR sensor, schrijf je bitje weg in het array waar je het wil hebben, hoog een tellertje op en verlaat de routine.

De kunst is nu om de eerste puls ongeveer in het midden van je zender puls te krijgen.

Een van de oplossingen is om je timer in de main loop op een interval van 2 ms te zetten en je zet een flag die aangeeft dat het het eerste bitje is.
Dan in de ISR check je die vlag, is dat bitje '1' dan programmeer je je timer om op 4 ms t.b.v. je andere 23 bits en clear de flag.
Je leest dan je IR sensor op de normale manier en schrijft het bitje weg.
Vanaf dat punt is je interval van je timer netjes 4 ms en lees je de rest in.

Ipv een flag te gebruiken kun je natuurlijk ook je row/scan counter gebruiken, is die 0 moet je de timer in de ISR omprogrammeren, is die 23 geworden moet je de timer stoppen.

In je main loop wacht je gewoon tot je row counter 24 geworden is en ben je klaar.

Zoiets in pseudo code

code:



main() {
 rowcounter = 0;
 settimer_interval(2);

 if (rowcounter ==24) {
   done
 }
}

ISR() {

   if (row==0) {
       settimer_interval(4);
   }

   if (row==23) {
       stop_timer();
   }

   bit = readISR();

   // Store bit in array
   // Hier hebben we het in het vorige topic over gehad.

    row++;
}
Henri's Law 1: De wet van behoud van ellende. Law 2: Ellende komt nooit alleen.
elmowww

Golden Member

Het kan wel, je kunt zelfs in een timer interrupt een andere interrupt handler aanroepen. Maar ik denk dat het niet handig is ;)

Als je (coditioneel) iets wilt doen in een interrupt, zou ik eigenlijk een event gebaseerde state machine maken.

Je houdt dan in een statische (of globale) variabele de state bij, en afhankelijk van de state doe je iets in de interrupt handler (waaroner je eigen state veranderen).

De state kan je in een int zettten, maar een enum is vaak wat nuttiger.

bijv:

code:


int myState = 0; //0=init, 1=waiting for trigger, 2=triggered

void ISR(void) {
    switch (myState) {
        case (0): //init
            //Initialiseer state machine en variabelen
            myState = 1;
            break;
        case (1): //Waiting for trigger
            //Wacht op trigger, bijv:
            if (pinX == hoog) {
                myState = 2;
            }
            break;
        case (2): //Triggered
            //triggered, wacht tot ik weer naar "Waiting for trigger" mag
            if (pinX == laag) {
                //Geef signaal of voer actie uit die moet, bijv process starten
                StartProcess();
                //Ga terug naar "Waiting for trigger"
                myState = 1;
            }
            break;
    }
}

Dit is nu heel simpel, maar je kunt hier heel veel gedrag mee in een proces krijgen, dat goed leesbaar en weinig verwoven is.

Je kunt dit soort state machines continu uittvoeren in een loop, waarbij je de timings afhankelijk maakt van de SysTick (meestal wel beschikbaar) voor minder kritische timings. Als het heel kritisch komt roep je de state machines aan in een interrupt (DMA transfer complete, timer, external interrupt etc etc).

PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling
trix

Golden Member

ik heb het ondertussen werkend, ik had deze vraag beter in het andere topic kunnen stellen.
ik zal daar de nieuwe code posten plus een print screen v/d logic analyzer.
het werkt nog niet volledig maar het "kijk" moment is goed.

eigenwijs = ook wijs
trix

Golden Member

Op 2 augustus 2020 15:56:37 schreef henri62:
Je leest dan je IR sensor op de normale manier en schrijft het bitje weg.

dat is nu het stukje wat nog niet werkt.

die constructie van mij wat betreft het 4 mS gebeuren, en naar het midden v/d puls kijken is allemaal gebaseerd op de code die in de IR zender (TSAL) zit. die heb ik eigenlijk gekopieerd en aangepast, om een beetje eenheid te houden. voor als nog werkt dat ook. ik krijg alleen nog niet de status v/d sensor in de array. mischien kijk ik te lang naar de sensor (2mS) ?

[Bericht gewijzigd door trix op 2 augustus 2020 17:17:42 (10%)]

eigenwijs = ook wijs

Je leest toch gewoon een input pin? Dat duurt op een ATMEGA maar 125 nS als die op 8 MHz draait.

Wat wel misschien een probleem is, dat je misschien wat moet doen aan filtering van de ingang, maar dat wordt een heel ander verhaal.

@elmoww: Wat ik deed met die compare (row==0 of row==23) die ik al boven aangaf is stiekem ook een soort statemachine.
Hierbij heb je 3 states:

eerste row
laatste row
alle andere rows

En trouwens, dat hele trigger verhaal hoort in de main loop te zitten waar je EEN scan van 24 bits triggerd (door de timer te starten) en wacht tot dat klaar is.
Dan wacht je op een RS485 commando voor de volgende kolom en hoog je de kolom teller ook op.

En daar moet ook nog een ander commando bij komen om alles te resetten als een complete nieuwe scan gedaan moet worden. Die zit dat de row/kolom tellers weer op 0.

Henri's Law 1: De wet van behoud van ellende. Law 2: Ellende komt nooit alleen.
trix

Golden Member

ja, ik lees gewoon een input pin, op de manier zoals in de code die ik vanmiddag in het andere topic heb gepost.
ik zie even niet waarom dat niet werkt. de ontvanger (TSOP) zit recht streeks op de atmega zonder condensator of wat dan ook.
morgen vroeg even verder testen.

maar het heeft zoals je al zei geen zin om 2 mS lang te kijken, mag veel korter. tnx.

[Bericht gewijzigd door trix op 2 augustus 2020 19:57:58 (14%)]

eigenwijs = ook wijs

Kijk trix. Je stelt nu een vraag: "Kan ik een interrupt... "

Dan zijn er mensen die er moeite in steken om dat uit te leggen....

En 8 uur later blijkt dat het om een sub-probleem van "JOU" project gaat wat eigenlijk al in jou andere topics besproken wordt. Kortom: Hier mist weer een hoop context waardoor mensen onnodig gevraagd wordt om een probleem te analyseren wat je helemaal niet hebt.

Zo'n vraag van "kan je een interrupt... " moet je stellen met de context: Ik heb een systeem waarbij ik een signaal wil inlezen wat er zo uitziet: ... <tekening van signaal> en nu heb ik het probleem dat ... en ik dacht ik ga het zo oplossen: interrupt... interrupt. Kan dat?

Als je vaak genoeg mensen hun tijd loopt te verspillen, dan ga je antwoorden krijgen als "ja". Of een lang antwoord als "ja dat kan".

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

Het heeft mijn interesse ook al een tijdje verloren... ;)
(steeds opnieuw na veel omzwervingen op hetzelfde uit te komen is nogal vermoeiend als alles over tientallen topics is verspreid)

Terwijl het in principe op 2 topics neerkomt: 'Hoe programmeer ik in C' en 'Hoe maak ik een 300 kanaals lichtsluis'...

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

ja gewoon uitbesteden aan mij of conculega ;)

trix

Golden Member

beetje laat,

mijn excuses als het zo word ervaren, het is nou eenmaal een wat groter project (al valt het wel mee als je het IRL ziet).
meeste vragen gaan inderdaad over C. dat is voor mij het moeilijkste gedeelte omdat ik maar zeer beperkte programmeer skils heb.
als ik bij iedere vraag het totaal plaatje uit leg, dan krijg je veel reacties die niet over de eigenlijke vraag stelling gaan. en dan dwaalt het snel af.
bovendien heb ik al een het al een paar keer uitgelegd, maar omdat het totaal redelijk complex is, komt dit niet over, en krijg ik hier een hoop vragen over, wat overigens geen probleem is.

dus ik probeer om een C probleem terug te brengen tot dat ene probleem op een zodanige manier dat het beantwoord zou kunnen worden zonder het totaal te kennen. maar dat lukt niet altijd goed, en dan krijg je vragen, met vervolgens......haaaa...het gaat weer over dat ene project,....zegt dat dan meteen......je hebt de verkeerde controller (wat op zich wel een beetje klopt) maar dat beantwoord mijn vraag niet.

dat is ook een beetje een mankement van b.v. een forum, discusies met text en meerdere personen is nou eenmaal lastig te stroomlijnen (als het wat complexer word).

maar weet dat ik alle hulp enorm weet te waarderen _/-\o_

eigenwijs = ook wijs
trix

Golden Member

Op 3 augustus 2020 11:43:13 schreef Arco:
vermoeiend als alles over tientallen topics is verspreid)

als alles in een topic zou zitten, dan krijg je zoveel verschillende disiplines in een topic dat het bijzonder lang word. als ik dan een simpele vraag over C heb, word er minder op gereageerd want "ik heb geen zin om dat hele topic te lezen".

eigenwijs = ook wijs

Ik vind over het algemeen dat je het juist wel netjes doet. Nieuw probleem nieuw topic. Maar de uitleg en de context in je openingspost kan wel stukken beter.

Zoals je in het begin van dit topic zegt je "probleem wat ik wil oplossen staat in deze topic onderaan:". Ja welk probleem? daar staat alleen stuk code zonder uitleg, dat is niet goed.