Hallo,
in een programmaatje voor een atmega32 gebruik ik enkele globale variabelen. In een ISR wordt de modus geselecteerd. Een daarvan is de setup modus (waarin variabelen gezet worden, binnengekomen via uart).
Het programma moet dan in configuratie mode gaan, en zou daarin blijven. Echter ik zie dat de modus ongewenst veranderd.
- Ligt dat aan het gebruik van de globale variabele?
- In welk soort geheugen komt een globale variabele terecht.
- Is er een andere manier om een modus in te stellen vanuit een ISR?
Bedoel je met ISR "Interrupt Service Routine"?
Wat veranderd er precies met die modus dan? Variabelen die je binnen die modus gebruikt? Of word de modus te vroeg verlaten?
Een globale variabele komt in hetzelfde geheugen als alle andere variabelen en dat is het ram geheugen. Alleen blijft een globale variabele altijd in het ram staan. En vanuit ieder stukje code kan deze gebruikt worden.
Hoe haal je verder de data uit de uart binnen?
Dmv de interrupt? Houd er dan wel rekening mee dat iedere keer als data ontvangen is deze interrupt word uitgevoerd.
Dus in jou geval als een modus geselecteerd is dan zou ik de interrupt van de uart even uitzetten en dan de rest van de data inlezen. Als de modus klaar is weer de interrupt aanzetten.
Waar globals terecht komen, is afhankelijk van de taal. Uiteindelijk staan ze natuurlijk allemaal in RAM, daar ontkomt je doorgaans niet echt aan
.
Waarom zo'n ding spontaan verandert kan ik je zo niet zeggen. Ga er maar vanuit dat je code dat ergens doet.
Overigens vind ik het niet zo'n prettig idee om dit soort globals vanuit een ISR te zetten. Zie het nut er doorgaans ook niet zo van in. Kan goed gaan als de rest er goed mee om gaat; doorgaans maak je het jezelf moeilijk op deze manier.
Het is me niet helemaal duidelijk, maar misschien zit het probleem dat je een globale variabele aanpast in een ISR, en ergens anders leest, maar die variable niet als volatile hebt gedeclareerd, zo dus:
volatile int bla;
Dit is nodig zodat de c compiler weet dat een variabele op een 'willekeurig' moment aangepast kan worden, en dat het elke keer uit het geheugen moet worden gelezen ipv dat het 1x in een register wordt gezet.
Belleblaas
BelleBlazer4Life
Ik denk globaal het zelfde als Maarten B......
Ik weet niet zeker of dit je probleem zal oplossen maar probeer eens het volgende als je de programmeertaal C of C++ gebruikt:
[1] Geen globale variabelen gebruiken tenzij echt nodig.
[2] Voeg de declarator "volatile" toe bij de declaratie van je variabele.
[3] Definieer h.e.a. anders eens als "const"
Ik ken de source code niet maar ik denk dat je het in deze hoek moet zoeken.
De waarde van een als volatile gedeclareerde variabele zal worden gelezen elke keer op het moment dat hij (zij) zal worden gebruikt (zeker tijdens een ISR).
ff tussendoor.. ik vond het niet nodig om hiervoor een nieuw topic te openen..
maare dat Volatile. doet dan toch precies hetzelfde als zo'n globale variabele?
daarnaast heb je ook een Static..
Ik snap niet goed wat het verschil is..
neej, volatile zegt dat de variabele bijvoorbeeld voor een ISR kan worden veranderd, of bijv door DMA. Dus dat iets wat de compiler niet kan voorspellen, zodat de compiler niet kan aannemen dat een variabele niet zal worden veranderd buiten zijn eigen 'scope'/'inzicht'
Voorbeeld:
int status = 0;
// example isr
ISR(EXAMPLE_vect) {
status = 1;
}
int main() {
while(status == 0) {
// wait
}
execute_blaat();
}
Hier kan de compiler de volgende optimalisatie toepassen: status wordt in de while loop niet aangepast, dus als hij een keer in een register wordt ingelezen, hoeft het niet nog een keer gebeuren. De while loop kan zal dus (ervan uitgaande dat de compiler een zinnige optimalisatie doet) worden verlaten. (zelf als je het aanpast kan het zijn dat het niet naar het geheugen geschreven wordt, maar dat weet ik niet zeker, dan zou je de ISO C docs moeten lezen oid, mssn mag dit met bepaalde optimalisaties wel, of alleen bij register storage specifier)
Alternatief:
volatile int status = 0;
Deze declaratie wil zeggen, dat status op elk moment kan veranderen, dus dat elke keer de waarde uit het geheugen moet worden gelezen.
Het is misschien een leuk experiment om dit te bekijken in de disassmbler wat voor asm code er wordt gegenereerd..
(global) static storage specifier geeft aan dat de scope van de variabele binnen de file blijft. In c++ is dat deprecated, omdat je daar namespaces hebt om de scope te beperken.
static binnen een functie heeft een wat duidelijker nut. De scope blijft binnen de functie, maar de waarde behoud zijn waarde wanneer je de functie opnieuw 'betreedt'. Alsof het een globale variabele is die je alleen vanaf een beplaalde functie zichtbaar is.
Bedankt voor je uitleg maarten. nu snap ik het ..
en dat van disassembler, goed idee ik zal er eens naar kijken welke code de compiler hier van maakt.
[Bericht gewijzigd door Electroboy op ]