Hallo zusammen.
Meine Variable i soll um eins inkrementieren, wenn der Timer Compare
(10KHz) die ISR losjagt. ISR wird erfolgreich durchgeführt, im 10KHz
Frequenz. Das Problem ist, dass i = 0 bleibt.
Dadurch bleibt auch das Lämpchen aus. Es sollte ja angehen und nicht
mehr aus.
Ich habe versucht i global und auch mit volatile zu definieren, ohne
Erfolg. Jemand eine Idee? Danke im Voraus.
ISR (TIMER0_COMPA_vect) //10 KHz
{
static uint8_t i; //wurde auch mal global definiert/ volatile
i++;
UDR0=(i); //Sende den aktuellen Wert für i
switch (i) {
case 5:
PORTB=(1<<PB0); //Lampe an
break;
case 10:
i=0; //zurücksetzen
break;
}
}
Wenn man PB0 bloss einschaltet, bleibt er ein.
Was macht dein wahllos verstreutes Wort volatile dort ?
Die Frage wäre auch, von welchem Wert an er loszählt.
Und ist dein USART überhaupt richtig initialisiert, um ein Zeichen in
1/10000 Sekunde wegzusenden ?
MaWin schrieb:> Wenn man PB0 bloss einschaltet, bleibt er ein.
richtig, damit wollte ich prüfen ob meine switch-abfrage richtig
abläuft.
MaWin schrieb:> Was macht dein wahllos verstreutes Wort volatile dort ?
statt static.
MaWin schrieb:> Die Frage wäre auch, von welchem Wert an er loszählt.
null.
MaWin schrieb:> Und ist dein USART überhaupt richtig initialisiert, um ein Zeichen in> 1/10000 Sekunde wegzusenden ?
Baud: 230400. Zeichen werden korrekt dargestellt. Für i bekomme ich nur
nuller.
WeißerRiese schrieb:> (10KHz) die ISR losjagt. ISR wird erfolgreich durchgeführt, im 10KHz> Frequenz. Das Problem ist, dass i = 0 bleibt.
Das Problem ist, dass du nur denkst, dass i Null bleibt.
Wenn die Senderoutine richtig funktioniert:
a) PB.0 nicht als Ausgang gesetzt.
b) LED falsch angeschlossen.
Marc V. schrieb:> Das Problem ist, dass du nur denkst, dass i Null bleibt.> Wenn die Senderoutine richtig funktioniert:
tut sie.
Marc V. schrieb:> a) PB.0 nicht als Ausgang gesetzt.> b) LED falsch angeschlossen (Anode an PB.0).
Ist alles richtig gesetzt.
Wenn ich die LED einfach so anschalte im ISR unabhängig vom i-Wert
leuchtet sie. Es liegt wirklich daran, dass i nicht inkrementiert.
WeißerRiese schrieb:> Wenn ich die LED einfach so anschalte im ISR unabhängig vom i-Wert> leuchtet sie. Es liegt wirklich daran, dass i nicht inkrementiert.
Dann probiere es mal so:
static uint8_t i = 0;
ISR (TIMER0_COMPA_vect)
{
i++;
UDR0=(i);
}
... nur einser. Die Variable wird nirgendswo sonst verwendet und weitere
ISR sind nicht vorhanden.
WeißerRiese schrieb:> Sorry obig genannter Code liefert mir zurück eine> 129, DEC> es wird nichts inkrementiert und gibt auch kein Überlauf.
Dann ist das jetzt der Punkt an dem du entweder
- den gesammten Code auf ein Minimum reduzierst oder
- den gesammten Code hier anhängst.
Für mich sieht das nämlich so aus als ob irgendwas
i überschreibt....
Volatile ist schon die richtige Idee. Probiere mal
static volatile uint8_t i;
Sonst kann es passieren, dass sich Interrupt oder Hauptprogramm i
gegenseitig überschreiben o. ä..
Dirk B. schrieb:> i ist so ziemlich der schlechteste Bezeichner für eine globale> Variable.> Auch, wenn es nur ein Beispiel ist.
Das ist es! Jetzt haben wir den Grund gefunden, warum die Variable nicht
inkrementiert wird. Wir werden dir auf ewige Zeiten dankbar sein und dir
die Füße küssen!
Statische Variablen sollten bei der Deklaration initialisiert werden.
1
staticuint8_ti=0;
Ansonsten sicherstellen, dass das Programm auch wirklich in die ISR
springt. Dazu evtl. die LED auf eine andere Art toggeln (Frequenz muss
deutlich kleiner sein, damit du ein Blinken erkennst):
Ich würde mal als aller erstes in der ISR mit cli() verhindern dass
weitere Interrupts die ISR unterbrechen.
Achtung am Ende der ISR das sei() nicht vergessen.
Juergen R. schrieb:> Ich würde mal als aller erstes in der ISR mit cli() verhindern dass> weitere Interrupts die ISR unterbrechen.> Achtung am Ende der ISR das sei() nicht vergessen.
Bloß nicht, das macht der GCC von selber... ISRs auf nem AVR sind von
Natur aus unterbrechungsfrei
Juergen R. schrieb:> Ich würde mal als aller erstes in der ISR mit cli() verhindern dass> weitere Interrupts die ISR unterbrechen.
Unnötig, macht die Maschine selbst.
> Achtung am Ende der ISR das sei() nicht vergessen.
Nicht nur unnötig, sondern direkt schädlich, weil dann in der Zeit
zwischen SEI und RETI andere ISRs durchkommen können, die damit
ungeplanten Stack belegen.
Juergen R. schrieb:> Ich würde mal als aller erstes in der ISR mit cli() verhindern dass> weitere Interrupts die ISR unterbrechen.> Achtung am Ende der ISR das sei() nicht vergessen.
Wenn es sich beim µC um einen AVR handelt, dann macht der das schon
selbst.
A. K. schrieb:>> Statische Variablen sollten bei der Deklaration initialisiert werden.>> Bei 0 unnötig.
Ist das sicher immer der Fall? Falls nicht, hätten wir nämlich ein
Problem. Ich gehe da lieber auf Nummer sicher.
Ingo L. schrieb:> ISR{> PORTB ^= (1<<PB0);> }> Die LED blinkt dann mit halber ISR-Frequenz
Genau, das ist die elegantere Variante.
Habe das Beispiel extra so gewählt, damit wir eine statische Variable in
der ISR deklarieren ;)
Dominik B. schrieb:> Ist das sicher immer der Fall?
Ja, ist im Standard so definiert. Ob du die Variablen trotzdem explizit
initialisierst, ist Geschmackssache.
WeißerRiese schrieb:> ISR (TIMER0_COMPA_vect)> {> i++;> UDR0=(i);> }>> Sorry obig genannter Code liefert mir zurück eine> 129, DEC> Die Variable wird nirgendswo sonst verwendet und weitere> ISR sind nicht vorhanden.
Sicher.
Code fast gleich, trotzdem wird im ersten Beispiel 1 und im zweiten
dann 129 zurückgeliefert (dasselbe, aber mit Bit7 gesetzt).
Aber nein, i wird nirgends überschrieben...
Hallo zusammen und danke für eure Beiträge.
Die ISR wird aufgerufen und funktioniert wie sie soll, Zeiten stimmen.
Ich sende den i-Wert doch nur in der ISR(sonst würde ich gar nichts
empfangen). Die LED geht an wenn ich den Befehl in default habe, statt
Case xy:
aber wie schon erwähnt tut sich auch ohne switch-abfrage bezüglich dem
Inkrementierern nichts. Es wird in der ISR inkrementiert und der Wert
ausgegeben. Immer 129.
Ich hab schon die ISR auf 1 Khz begrenzt, ich weiß nicht wieviele takte
eingeplant werden müssen, um den Wert einer Variable um 1 zu erhöhen.
Vorweg : Es handelt sich um atmega328p, FCPU: 9.216 MHz
static volatile habe ich auch schon probiert:
Ausgeben wird eine 1, statt 129. Jedoch auch nichts inkrementiert.
Ich werde den Code dann mal soweit wie möglich kürzen und hochladen.
WeißerRiese schrieb:> static uint8_t i; //wurde auch mal global
was denn nun, i in der ISR und extern deklariert?
Wenn es immer dieselbe i sein soll dann doch nur EINMAL deklarieren und
initialisieren sonst hat man zwei i.
Ein Verweis mit extern ist natürlich erlaubt und evtl. auch nötig.
Joachim B. schrieb:> was denn nun, i in der ISR und extern deklariert?
Beides mal probiert. Kein Unterschied.
Aber als static deklariert ist es in der ISR ja erlaubt.
Joachim B. schrieb:> Wenn es immer dieselbe i sein soll dann doch nur EINMAL deklarieren und> initialisieren sonst hat man zwei i.
Logisch.
Joachim B. schrieb:> Ein Verweis mit extern ist natürlich erlaubt und evtl. auch nötig.
Das habe ich noch nicht probiert.
WeißerRiese schrieb:> Joachim B. schrieb:>> Ein Verweis mit extern ist natürlich erlaubt und evtl. auch nötig.>> Das habe ich noch nicht probiert.
extern volatile unsigned char count; // wäre dein i in der ISR
volatile unsigned char count=0;// an anderer Stelle
umgedreht gehts aber auch
Dussel schrieb:> Was macht denn die Simulation? Die dürfte helfen, Programmfehler zu> finden, insbesondere, wenn man den Wert von i verfolgt.
Ich habe bisher immer die Finger davon gelassen. Hab mir sagen lassen,
ist furchtbar langsam.
Aber dann will ich das auch nicht unprobiert lassen.
WeißerRiese schrieb:> Ich werde den Code dann mal soweit wie möglich kürzen und hochladen.
Nicht nötig, dein gekürzter Code wird bestimmt funktionieren.
Oder so etwas probieren:
WeißerRiese schrieb:> Ich habe bisher immer die Finger davon gelassen. Hab mir sagen lassen,> ist furchtbar langsam.
Es wäre auch etwas unpraktisch, Variablenwerte in
Originalgeschwindigkeit zu verfolgen.
Danke werde ich gleich mal alles ausprobieren.
Dussel schrieb:> Es wäre auch etwas unpraktisch, Variablenwerte in> Originalgeschwindigkeit zu verfolgen.
Das stimmt, aber es würde reichen wenn man eine Änderung sehen könnte,
statt immer den gleichen Wert.
WeißerRiese schrieb:> Das stimmt, aber es würde reichen wenn man eine Änderung sehen könnte,> statt immer den gleichen Wert.
wenn es nur eine einzige i gibt und diese auch volatile ist klappt das.
Wenn du diese i auch noch umbenennst zu immer_wieder_sonntags kannst du
dir sicher sein nicht irgendwo ein i übersehen zu haben
von mir aus auch
isr_i_die_nur_hier_interessiert
WeißerRiese schrieb:> Danke werde ich gleich mal alles ausprobieren.
Oder die Variable als erste in deinem Programm deklarieren, also
vor allen anderen Variablen:
Marc V. schrieb:> Oder die Variable als erste in deinem Programm deklarieren, also> vor allen anderen Variablen:> volatile uin8_t IsrVar=0; // anstatt i
und überall in anderen Modulen:
extern volatile uin8_t IsrVar; // anstatt i
WeißerRiese schrieb:> static volatile habe ich auch schon probiert:
Probieren ist einfach nur sch...lecht. Wissen ist besser.
1. Wenn Du eine Variable in einer ISR und in einer anderen
Funktion benutzt: volatile
2. Wenn Du eine Variable ausschließlich in einer ISR benutzt:
Definiere sie innerhalb der ISR, aber NICHT volatile.
3. Wenn der Wert einer Variablen, welche innerhalb der ISR
definiert wurde, nach Beenden der ISR erhalten bleiben soll:
static
Nach Anwendung dieser 3 Regeln ergibt sich:
1
ISR(TIMER0_COMPA_vect)
2
{
3
staticuint8_ti;
4
i++;
5
...
6
}
Das muss funktionieren. Wenn nicht, überschreibt Dein Programm
irgendwo anders Deine globalen Variablen (Merke: Auch eine innerhalb
einer Funktion definierte static-Variable liegt ähnlich wie Deine
sonstigen globalen Variablen nicht auf dem Stack).
Alles bisherigen Beiträge, die da rumrätseln "vielleicht static,
vielleicht volatile, probiere mal aus" sind Dünnpfiff, weil sie nämlich
von Leuten kommen, die keine Ahnung haben.
Der OP muss hier mal das komplette Programm posten.
Das Verhalten klingt nämlich nach "Reset nach nicht behandeltem
Interrupt", bzw. "Error is in Code not shown".
Und ja, das hätte man schon 10 Beiträge früher machen müssen.
Frank M. schrieb:> Nach Anwendung dieser 3 Regeln ergibt sich:ISR (TIMER0_COMPA_vect)> {> static uint8_t i;> i++;> ...> }>> Das muss funktionieren.
Funktionert aber nicht bei TO.
Frank M. schrieb:> Wenn nicht, überschreibt Dein Programm> irgendwo anders Deine globalen Variablen
Habe ich ihm schon geschrieben, was hast du neues beizutragen ?
Frank M. schrieb:> Alles bisherigen Beiträge, die da rumrätseln "vielleicht static,> vielleicht volatile, probiere mal aus" sind Dünnpfiff, weil sie nämlich> von Leuten kommen, die keine Ahnung haben.
Und du bist staatlich anerkannter Ahnungsschätzer, oder was ?
Marc V. schrieb:>> Wenn nicht, überschreibt Dein Programm>> irgendwo anders Deine globalen Variablen>> Habe ich ihm schon geschrieben, was hast du neues beizutragen ?
Du hast es lediglich angedeutet. Damit kann der TO nichts anfangen.
Ich schreibe, dass es so sein muss. Damit kann man was anfangen.
> Und du bist staatlich anerkannter Ahnungsschätzer, oder was ?
Da braucht man nicht schätzen, sondern einfach nur die Symptome zu
beurteilen.
Was passt Dir nicht an meinem Beitrag? Fühlst Du Dich angepisst, obwohl
ich Dich überhaupt nicht meinte? Nicht mein Schuh, sondern Deiner :-)
P.S.
Stelle bitte das plenken ab. Danke.
WeißerRiese schrieb:> ISR (TIMER0_COMPA_vect) //10 KHz> {>> static uint8_t i; //wurde auch mal global definiert/ volatile> i++;> UDR0=(i); //Sende den aktuellen Wert für i> switch (i) {> case 5:>> PORTB=(1<<PB0); //Lampe an>> break;>> case 10:>> i=0; //zurücksetzen> break;> }> }
Also meine beschränkte Auffassung sagt mir:
ISR Wird aufgerufen -> i wird deklariert -> i wird um eins inkrementiert
(daher die 1) -> Switch/Case -> ISR wird beendet und i wird fallen
gelassen -> ISR wird aufgerufen -> i wird deklariert -> i wird um eins
inkrementiert.... usw... usw.
i kann immer nur auf eins (1) kommen, da die Variable zum Ende der ISR
ja wieder freigegeben wird. i gehört außerhalb volatile deklariert und
nicht in der ISR!
Draco schrieb:> i kann immer nur auf eins (1) kommen, da die Variable zum Ende der ISR> ja wieder freigegeben wird
Nö. Da steht eindeutig ein static davor.
Lies mal ein gutes Buch über die Programmiersprache "C".
Der OP hat mit einem Programmierfehler im nicht geposteten Teil für
einen Reset gesorgt. Daher hab ich oben nachgefragt.
Draco schrieb:> WeißerRiese schrieb:>> static uint8_t i; //wurde auch mal global definiert/ volatile> i kann immer nur auf eins (1) kommen, da die Variable zum Ende der ISR> ja wieder freigegeben wird.
Schwachsinn Nr. 1: i ist static und wird deshalb nicht freigegeben.
> i gehört außerhalb volatile deklariert und nicht in der ISR!
Schwachsinn Nr. 2: Wenn i ausschließlich in der ISR benutzt wird, dann
sollte man die Variable auch innerhalb der ISR definieren. volatile
ist dabei tunlichst zu vermeiden, weil man damit dem Optimierer des
C-Compilers ein Bein stellt.
Genau diese Art von Beiträgen meinte ich oben: Keine Ahnung, aber
Unsinn erzählen. Lies mal in Deinem C-Buch nach, was static bedeutet.
Frank M. schrieb:> Was passt Dir nicht an meinem Beitrag? Fühlst Du Dich angepisst, obwohl> ich Dich überhaupt nicht meinte? Nicht mein Schuh, sondern Deiner :-)
Dein Pauschalurteil.
Man kann schreiben, dass die "bisherigen Beiträge, die da
rumrätseln vielleicht static, vielleicht volatile, probiere mal aus"
Dünnpfiff sind, aber nicht, dass die alle von Leuten kommen, die
keine Ahnung haben.
> P.S.> Stelle bitte das plenken ab. Danke.
plenken ?
Wo ?
Falls du plänkeln meinst:
Diesmal wollte ich wirklich nicht plänkeln, war vielleicht etwas zu
voreilig, entschuldige mich hiermit.
Mit static ist i noch immer nicht global, aber auch nicht local... Ich
gehe noch immer nach meinem Sinn, auch wenn mir ein C Buch was anderes
sagt. Und wenn ich sehe das i nach der deklaration auf 1 inkrementiert
wird und bei jedem Aufruf der ISR immer wieder ne 1 rausgehauen wird,
dann ist das erste was icj probiere: Die Variable global volatile
außerhalb der ISR deklarieren und probieren ob sie funktionert. (Wobei
der Name i, entschuldigung, wirklich dämlich gewählt ist!)
Draco schrieb:> Mit static ist i noch immer nicht global
Sie hat keinen globalen Scope, aber sonst wird sie wie eine globale
Variable gehandhabt: Sie liegt nicht auf dem Stack wie lokale
auto-Variablen.
> Ich> gehe noch immer nach meinem Sinn, auch wenn mir ein C Buch was anderes> sagt.
Das solltest Du bleiben lassen, denn das führt Dich auf Abwege.
> Und wenn ich sehe das i nach der deklaration auf 1 inkrementiert> wird und bei jedem Aufruf der ISR immer wieder ne 1 rausgehauen wird,> dann ist das erste was icj probiere
"Probiere"? Das ist genau das falsche! Man sollte wissen, was man tut
und nicht probieren! Der TO haut sich seine globalen und
static-Variablen mit einem Überschreiber im RAM weg, NICHTS ANDERES
bleibt als Konsequenz übrig!
Hör auf, mit Deinem Halbwissen so einen Mist zu verbreiten.
Draco schrieb:> dann ist das erste was icj probiere: Die Variable global volatile> außerhalb der ISR deklarieren und probieren ob sie funktionert.
Was auf dasselbe hinauskommt solange es um Speicher geht, aber
die Möglichkeit, irgendwo in main() oder in einer anderen Routine
die Variable zu überschreiben, um ein vielfaches erhöht.
Marc V. schrieb:> plenken ?> Wo ?
Zum Beispiel hier zweimal :-)
Plenken wird hier erklärt:
https://de.wikipedia.org/wiki/Plenk
Dein abgesetztes Fragezeichen führt dabei zu ungewollten Umbrüchen.
Beispiel:
Ist das eine Unart, ein Fragezeichen mit einem Leerzeichen abzusetzen
?
Das passiert nicht, wenn man das Leerzeichen vor dem Fragezeichen
unterlässt - wie es auch jede Zeitung - aus gutem Grunde - tut.
Schließlich machst Du ja auch kein Leerzeichen vor einem Satzpunkt.
Dussel schrieb:> Was ist es denn sonst? Von wo kann man auf i sonst noch zugreifen,> außerhalb der Funktion?
wenn er mehr als eine i benutzt, passiert gerne bei typischen c & p dann
weiss hier keiner welche i welchen Inhalt hat!
Deswegen statt i mal eindeutige Variablennamen zu benutzen die
zweifelsfrei immer identifiziert werden können wo sie hingehören.
Joachim B. schrieb:> Dussel schrieb:>> Was ist es denn sonst? Von wo kann man auf i sonst noch zugreifen,>> außerhalb der Funktion?>> wenn er mehr als eine i benutzt, passiert gerne bei typischen c & p dann> weiss hier keiner welche i welchen Inhalt hat!>> Deswegen statt i mal eindeutige Variablennamen zu benutzen die> zweifelsfrei immer identifiziert werden können wo sie hingehören.
Wenn aber eine andere Variable "i" (außerhalb der ISR) wegen des
Namens-Irrtums auf Null gesetzt würde, dann hätte das keinen Einfluß auf
"i" innerhalb der ISR. Du hast zwar recht mit der Variablen-Benennung,
aber das ist nicht die Ursache des Fehlers beim TO.
Joachim B. schrieb:> Deswegen statt i mal eindeutige Variablennamen zu benutzen die> zweifelsfrei immer identifiziert werden können wo sie hingehören.
Wenn der TO die Variable i sauber innerhalb der ISR mit static
definiert, ist es vollkommen egal, ob "draussen" noch eine weitere
Variable i mit gleichem Namen herumschwirrt. Da gibt es keine Konflikte.
Von daher muss es gar nicht "eindeutig" sein.
Der RAM-Überschreiber kommt woanders her. Mit dem Namen der Variablen
hat es nichts zu tun.
Huh schrieb:> Wenn aber eine andere Variable "i" (außerhalb der ISR) wegen des> Namens-Irrtums auf Null gesetzt würde, dann hätte das keinen Einfluß auf> "i" innerhalb der ISR. Du hast zwar recht mit der Variablen-Benennung,> aber das ist nicht die Ursache des Fehlers beim TO.
Korrekt.
Frank M. schrieb:> Schließlich machst Du ja auch kein Leerzeichen vor einem Satzpunkt.
Nein, aber wenn Leerzeichen vor ? nicht zu Umbrüchen führen,
mache ich das so. Wenn doch, dann ohne.
Mit ist irgendwie übersichtlicher, zumindest für mich und ich mache
es (aber nur im Forum) immer so.
Und das ist plänkeln deinerseits.
Sende doch einfach mal vor dem Betreten Deiner Endlosschleife in Deiner
Main ein 0xFF auf die UART.
Wenn dann 0xFF 0x01 0xFF 0x01 ... raus kommt ist der ständige Reset
bestätigt.
Kannst aber auch n Debugger nehmen und einfach n Breakpoint an Beginn
der Main setzen.
Hans
Frank M. schrieb:> Der RAM-Überschreiber kommt woanders her. Mit dem Namen der Variablen> hat es nichts zu tun.
Ja.
Deswegen soll er die Variable als erste deklarieren.
Eine andere Möglichkeit (zum Testen) ist es, ein Array vor dieser
Variable zu deklarieren.
Marc V. schrieb:> Nein, aber wenn Leerzeichen vor ? nicht zu Umbrüchen führen,> mache ich das so. Wenn doch, dann ohne.
an dieser Stelle bin ich bei dir, nur übersieht man leicht das der
Zeilenumbruch automatisch generiert wird, was wir nicht sehen sehen
andere!
Ich kann die Kritik verstehen, mag aber trotzdem lieber vor dem ? ein
<SPACE>
Joachim B. schrieb:> an dieser Stelle bin ich bei dir, nur übersieht man leicht das der
Und deinetwegen ging EDIT nicht mehr;)
Hmmm.
Mit Leerzeichen sieht das nicht so beschissen aus ;-)
Marc V. schrieb:> Eine andere Möglichkeit (zum Testen) ist es, ein Array vor dieser> Variable zu deklarieren.
und danach die Werte im Array kontrollieren/ausgeben.
Marc V. schrieb:> Ralf G. schrieb:>> Marc V. schrieb:>>> Ja.>> Nein.>> Doch.
bei soviel i-Verwirrung weiss doch keiner wieviele i und wo der TO alle
i deklariert hat, es ist auch müssig über i zu streiten, der
Variablenname i ist einfach nur Mist wenn er mehrfach auftaucht.
Joachim B. schrieb:> bei soviel i-Verwirrung weiss doch keiner wieviele i und wo der TO alle> i deklariert hat, es ist auch müssig über i zu streiten, der> Variablenname i ist einfach nur Mist wenn er mehrfach auftaucht.
Ich deklariere in Funktionen alle Variablen mit l am Anfang, also
lVar1, lVar2, Parameter kriegen ein p davor, also pPar1, pPar2 usw.
Konstanten werden mit c_Konst1, c_Konst2 deklariert, Eeprom Variablen
dementsprechend mit e_Var etc.
Variablen die in jedem Programmteil beliebig geändert werden können,
kriegen ein x davor.
Auch nach ein paar Monaten weiss ich, ob der wert einer Variable noch
irgendwo anders sicher geändert werden kann und wo sich was befindet.
Ansonnsten kriegen die Variablen sinnvolle Namen, i ist wirklich ein
schlechter Name, aber in diesem Fall absolut irrelevant.
Marc V. schrieb:> Nicht nötig, dein gekürzter Code wird bestimmt funktionieren.
Recht sollst du behalten.
http://pastebin.com/w9Fx16Ye so funktioniert es.
Die Variable i = cnt, habe sie nur hier als Beispiel "i" getauft, habe
nicht gedacht, dass ein Buchstabe für so viel Verwirrung sorgt.
Muss ich wohl nochmal den Code durchschauen. Bin/war mir eigentlich
sicher dass auf die Variable bezogen nichts geändert wurde. Danke euch
allen.
Joachim B. schrieb:> hast du den gesamten Code gesehen?
Nenne bitte eine Möglichkeit, eine Variable i, die innerhalb einer
Funktion static definiert ist, durch eine gleichnamige Variable - außer
durch RAM-Überschreibungen - zu manipulieren.
Glaube mir: am Namen liegts nicht.
Joachim B. schrieb:> hast du den gesamten Code gesehen? ich nicht.
Die Variable "i", um die es hier geht, ist in der ISR definiert und hat
damit keinen Sichtbarkeitsbereich außerhalb der ISR. Da können im
restlichen Programm noch hunderte "i" auftauchen, das kratzt die "i" in
der ISR nicht.
Frank M. schrieb:> Glaube mir: am Namen liegts nicht.Huh schrieb:> Da können im> restlichen Programm noch hunderte "i" auftauchen, das kratzt die "i" in> der ISR nicht.
glaube ich euch unbesehen, nur ist das Problem vom TO damit
offensichtlich nicht vom Tisch, abgesehen davon das ich bei seinen
Aussagen was wann wo nicht mehr durchblicke und ich aus eigener
Erfahrung beim Schindluder treiben mit dem Variablennamen i selber schon
reingefallen bin.
Auch wenn i richtig angewendet kein Problem ist ist der Variablenname
doof gewählt weil uneindeutig.
Ingo L. schrieb:> Oder gibts da evtl. doch den Klassiker unter den Fehlern und die> Warnung> wird ignoriert?:if ( i = 1 )...> ;)
Das wäre auch nur ein Problem, wenn es innerhalb der ISR stehen würde.
Außerhalb wird es zwar unerwünschte Effekte haben, aber nicht den hier
beschriebenen Fehler.
Joachim B. schrieb:> Auch wenn i richtig angewendet kein Problem ist ist der Variablenname> doof gewählt weil uneindeutig.
Stell Dir vor, Du schreibst eine C-Library. Oder Du nutzt eine ... und
Du müsstest immer darauf achten, dass alle Variablennamen eindeutig
sind!
Glücklicherweise ist es nicht so, dass die Variablen eindeutig sein
müssen. Sonst müsste ich als Bibliotheks-Programmierer ja schon im
vorhinein wissen, was die Anwender für Variablennamen wählen, damit ich
diese selbst vermeide, um Konflikte zu vermeiden. Die Programmiersprache
C wäre in diesem Fall unbrauchbar, weil man überhaupt nicht modular
programmieren könnte.
Also: Benutzte ruhig nicht-eindeutige Variablen. Aber wende die Regeln
für die Scopes eindeutig an. Dann gibt es auch keine Schwierigkeiten.
Joachim B. schrieb:> nur ist das Problem vom TO damit> offensichtlich nicht vom Tisch, abgesehen davon das ich bei seinen> Aussagen was wann wo nicht mehr durchblicke und ich aus eigener> Erfahrung beim Schindluder treiben mit dem Variablennamen i selber schon> reingefallen bin.
Hey doch ist es. Es muss so funktionieren, wie beschrieben wurde.
Das Problem liegt offensichtlich doch irgendwo in meinem Code, aber den
Fehler muss ich dann selbst finden. :)
Fakt ist : es funktioniert mit dem Schlüsselwort static in der ISR
Routine.
An dem Variablennamen i lag es nicht. Der Fehler ist in meinem Code. Wo
muss ich herausfinden.
Aber dass es so gehen muss, hilft mir schon weiter :)
Danke euch.
Da grad noch weiter diskutiert wurde. Falls mein Beitrag übersehen
wurde nochmal:
http://pastebin.com/w9Fx16Ye
SO FUNKTIONIERT ES.
Hiermit ist mein Problem zwar nicht gelöst, aber ich weiß bescheid dass
es so gehen muss.
Natürlich dürft ich weiter diskutieren, aber meinetwegen ist hiermit die
Sache erledigt.
Vielen Danke an alle.
Es ist übrigens keine gute Idee, UDR einfach zu beschreiben, vor allem,
wenn das mit 10kHz Wiederholrate geschieht. Um sicherzustellen, das das
Zeichen schon weg ist, das da vorher drin war, muss man bei 8-Bit ohne
Parity eine Baudrate von über 100kBaud servieren. (Jedes Zeichen besteht
aus 10 Bit)
Selbst bei 1kHz sollte man mit mindestens 10kBaud wegsenden.
Gut, es gibt ein wenig Luft, weil die Verarbeitung der ISR etwas dauert,
das sind aber eben nur µs.
Matthias S. schrieb:> Es ist übrigens keine gute Idee, UDR einfach zu beschreiben, vor allem,> wenn das mit 10kHz Wiederholrate geschieht. Um sicherzustellen, das das> Zeichen schon weg ist, das da vorher drin war, muss man bei 8-Bit ohne> Parity eine Baudrate von über 100kBaud servieren. (Jedes Zeichen besteht> aus 10 Bit)
Habe eine Baud von 230.4k
Ja ist noch nicht alles ausgereift.
Vielleicht probiere ich mich dann an den FIFO's.
Danke.
Matthias S. schrieb:> Es ist übrigens keine gute Idee, UDR einfach zu beschreiben, vor allem,> wenn das mit 10kHz Wiederholrate geschieht. Um sicherzustellen, das das> Zeichen schon weg ist, das da vorher drin war, muss man bei 8-Bit ohne> Parity eine Baudrate von über 100kBaud servieren. (Jedes Zeichen besteht> aus 10 Bit)
Daran hatte ich auch gedacht, aber es hieß ja es käme nicht zu einem
Überlauf.
Anstatt die Baudrate hochzubohren, würde ich das ganze aber eher mit
Polling machen (hoffe, das ist das richtige Flag):
1
while(!UDRE);// Warten bis vorheriges Senden abgeschlossen
2
UDR0=i;
Dann ist sichergestellt, dass auch das Zeichen vorher rausgegangen ist,
bevor die ISR das Daten-Register wieder vollstopft
Dominik B. schrieb:> while(!UDRE); // Warten bis vorheriges Senden abgeschlossen> UDR0 = i;
Warten in einer ISR könnte unerwünschte Nebeneffekte haben - kommt auf
das Programm im Ganzen an. Aber das kennen wir überhaupt nicht.
Frank M. schrieb:> Dominik B. schrieb:>> while(!UDRE); // Warten bis vorheriges Senden abgeschlossen>> UDR0 = i;>> Warten in einer ISR könnte unerwünschte Nebeneffekte haben - kommt auf> das Programm im Ganzen an. Aber das kennen wir überhaupt nicht.
Das ist richtig, sauber ist das definitiv auch nicht. Könnte dadurch
zumindest ausschließen, dass der UART nicht abgehängt wird beim Senden.
Dominik B. schrieb:> Anstatt die Baudrate hochzubohren, würde ich das ganze aber eher mit> Polling machen (hoffe, das ist das richtige Flag):> while(!UDRE); // Warten bis vorheriges Senden abgeschlossen> UDR0 = i;
Selbst wenn der Code stimmen würde (richtig wäre etwa
1
while(!(UCSR0A&(1<<UDRE0))){};
2
UDR0=i;
) ,hebelt man damit den grossen Vorteil eines Timer Interrupt aus -
nämlich das beinharte Abarbeiten in genau definierten Zeitabständen.
Wenn UDR nicht leer ist, wird das nicht klappen.
Seriellen Kram also besser ausserhalb der ISR machen.
Dafür müsste i allerdings global sein, was auf den kleinen MC aber auch
kein Nachteil ist.
Matthias S. schrieb:> Seriellen Kram also besser ausserhalb der ISR machen.
Ist deshalb innerhalb der ISR, weil der CTC Timer 0 durch Autotrigger an
den ADC-Start gebunden ist.
Dadurch soll das Timing beim Samplen eingehalten werden.
WeißerRiese schrieb:> Dadurch soll das Timing beim Samplen eingehalten werden.
Man kann durchaus ausrechnen, welche Baudraten bei welcher Samplerate
möglich sind. Bei geeigneten Geschwindigkeiten kann dann das Testen auf
UCSR0A & (1<<UDRE0) tatsächlich entfallen.
Hast Du Dir das vorher ausgerechnet, damit die serielle Schnittstelle
nicht überläuft? Wenn ja, ist das durchaus okay so.
Ich hab mühselig jetzt alles durchprobiert.
Es ist alles gleich.
Einzige Änderung, ich habe ADC vom Timer entkoppelt. Dann inkrementiert
die Variable.
Nun gut. Ich wollte mir das Aufrufen von ADC-Start sparen, in dem ich
den Autotrigger nutze für ADC-Start, der mit CTC Timer0 ausgelöst wird.
Dann wird das eben manuell gestartet.
Frank M. schrieb:> Hast Du Dir das vorher ausgerechnet, damit die serielle Schnittstelle> nicht überläuft? Wenn ja, ist das durchaus okay so.
ja, haut alles hin. Danke.
WeißerRiese schrieb:> Einzige Änderung, ich habe ADC vom Timer entkoppelt. Dann inkrementiert> die Variable.
Dann hast du irgendwo in der ADC Routine munter die Variable i
überschrieben, wahrscheinlich mit einem Array oder mit einem
ADC-integer der als uint8_t deklariert war.
Warum deklarierst du die ISR Variable nicht als volatile und als
erste Variable überhaupt und probierst es dann nochmal ?
Marc V. schrieb:> Dann hast du irgendwo in der ADC Routine munter die Variable i> überschrieben, wahrscheinlich mit einem Array oder mit einem> ADC-integer der als uint8_t deklariert war.
nein. Es war der ADC-Interrupt. Es ist immer noch Autogetriggert, aber
der ADC-Interrupt ausgeschalten. Alles läuft wunderbar.
Heiner schrieb im Beitrag #4644798:
> typisch Anfänger: Problem nicht mehr sichtbar -> weiter geht's ohne> die wirkliche Ursache nachvollzogen und verstanden zu haben. Wenn du> noch
Das Problem ist mir zur Hälfte klar.
Durch Fehler lernt man. Und ja ich bin Anfänger.
Heiner schrieb im Beitrag #4644798:
> mit FIFO´s anfängst, endet das in einer Katastrophe.
Nicht unbedingt, hab es aber so aufgeteilt bekommen, dass ich das nicht
mehr brauche.
WeißerRiese schrieb:> nein. Es war der ADC-Interrupt. Es ist immer noch Autogetriggert, aber> der ADC-Interrupt ausgeschalten. Alles läuft wunderbar.
Nein, sicher nicht.
Aber du kannst es ruhig weiter glauben.
Marc V. schrieb:> WeißerRiese schrieb:>> nein. Es war der ADC-Interrupt. Es ist immer noch Autogetriggert, aber>> der ADC-Interrupt ausgeschalten. Alles läuft wunderbar.>> Nein, sicher nicht.> Aber du kannst es ruhig weiter glauben.
// ADCSRA |= (1<<ADIE); geht
ADCSRA |= (1<<ADIE); geht nicht.
ADC-Autotrigger an CTC Timer 0.
WeißerRiese schrieb:
Oh mann. Mach es uns doch nicht so schwer.
Ohne deinen Vollständigen Code zu kennen kann
dir hier keiner effektiv helfen. Das ist alles
nur stochern im Nebel.
Dem Hinweis das ein anderer Codeteil dir i überschreibt(*)
und es deshalb nötig ist den ganzen Code zu betrachten
gehst du nicht ein. Den Beweis das der uns unbekannte Code
schuld ist hast du mit dem funktionierenden minimal Beispiel
ja selbst geliefert.
Und wenn ich versuche die 2 Aussagen:
> // ADCSRA |= (1<<ADIE); geht> ADCSRA |= (1<<ADIE); geht nicht.
mit deinem Code in einklang zu bringen passt das hinten
und vorne nicht. Du hast keine ISR für den ADC drin,
ergo das ding macht einen reset, was nicht sein kann
da du den ADC noch nicht mal startest geschweige denn
konfigurierst.... Willkommen im Nebel.
Also Poste alles an Code oder begib dich in der *.sym / *.size
auf die suche nach verdächtigen.
*) Zum Thema überschreiben:
Es hat nichts mit dem i in der ISR zu tun. Diese i steht an
einer bestimmten Stelle im RAM und irgendwer schreibt da
illegalerweise auch rein. Die üblichen Verdächtigen sind:
- Arrays
- das meiste aus string.h
- Pointer
Oder der µC macht einen Reset. Das geht so schnell, das
merkst du nicht -> ausbremsen mit einem LED-Test am anfang.
Julian .. schrieb:> Oh mann. Mach es uns doch nicht so schwer.> Ohne deinen Vollständigen Code zu kennen kann> dir hier keiner effektiv helfen.
Es hat sich doch schon lange erledigt. Ich denke kaum, dass jemand Lust
hat sich durch den ganzen Code zu wurschteln.
Julian .. schrieb:>> // ADCSRA |= (1<<ADIE); geht>> ADCSRA |= (1<<ADIE); geht nicht.>> mit deinem Code in einklang zu bringen passt das hinten> und vorne nicht.
Doch tut es..
>Du hast keine ISR für den ADC drin,
Braucht man nicht.
> ergo das ding macht einen reset, was nicht sein kann> da du den ADC noch nicht mal startest geschweige denn
..Autostart. Alle Werte und Frequenzen sind korrekt. Counter läuft wie
er soll.
Julian .. schrieb:> Also Poste alles an Code oder begib dich in der *.sym / *.size> auf die suche nach verdächtigen.
Hab ich doch schon lange.
Julian .. schrieb:> Oder der µC macht einen Reset. Das geht so schnell, das> merkst du nicht -> ausbremsen mit einem LED-Test am anfang.
ausgeschlossen. Die "Messung" startet erst wenn ein bestimmtes Zeichen
empfangen wird.
WeißerRiese schrieb:> Das Problem ist mir zur Hälfte klar.> Durch Fehler lernt man. Und ja ich bin Anfänger.
Um auf diese Aussage einzugehen.
Der Timer0 startet im Hintergrund eine single ADC-Conversion ohne
Weiteres Dazutun -> Autostart.
Zusätzlich nutze ich die ISR von Timer0 (mit dem Wissen, dass gerade
eine ADC-Start erfolgt ist).
In der inkrementiert meine Variable, die aber nie aufaddiert wurde.
Zwischen dem Beginn der ISR(Timer0) und den ADC-Interrupt (den ich
eigentlich nirgends aufgerufen habe) vergeht 1/45KHz [s].
Nachdem ich den Interrupt für den ADC ausgeschalten habe (Der restliche
Code ist völlig identisch), habe ich das Problem nicht mehr.
Und ich habe nur eine einzige Variable in einer Schleife. Es wird nichts
überschrieben.
WeißerRiese schrieb:> Nachdem ich den Interrupt für den ADC ausgeschalten habe (Der restliche> Code ist völlig identisch), habe ich das Problem nicht mehr.
Das klingt aber wirklich nach folgendem:
Zuerst hattest du den Interrupt für den ADC eingeschaltet, hattest aber
keine ISR dafür (hast du weiter oben selbst gesagt). Der µC wollte die
ISR aufrufen beim ADC-Interrupt, fand aber keine, springt ins Leere,
deshalb RESET...
Als du den ADC-Interrupt ausgeschaltet hattest, ging es. Jetzt versucht
er auch nicht mehr ins Leere zu springen...
Räusper schrieb:> Das klingt aber wirklich nach folgendem:> Zuerst hattest du den Interrupt für den ADC eingeschaltet, hattest aber> keine ISR dafür (hast du weiter oben selbst gesagt). Der µC wollte die> ISR aufrufen beim ADC-Interrupt, fand aber keine, springt ins Leere,> deshalb RESET...> Als du den ADC-Interrupt ausgeschaltet hattest, ging es. Jetzt versucht> er auch nicht mehr ins Leere zu springen...
Das ist möglich.
Wenn du noch zwischen ins Leere und RESET unterscheidest.
Auf jeden Fall lag der Fehler darin. Der Rest wurde ja auch nicht
ausgeführt von der ISR.
Ich hab nicht dran gedacht, die Interrupts auszuschalten. War noch vom
vorherigen Code, wo die ISR(ADC) genutzt wurde.
Nur würde er beim RESET mir keinen weiteren Wert liefern ohne dass ich
ihm ein Zeichen sende.
WeißerRiese schrieb:> WeißerRiese schrieb:>> Das Problem ist mir zur Hälfte klar.>> Durch Fehler lernt man. Und ja ich bin Anfänger.
Ich erkläre es mir so:
es ist als würde da stehen:
void (ADC-ISR)
{
//leer
}
Wie dem auch sei. Vielen Dank für eure Beiträge. Ich habe wieder was
lernen können.
WeißerRiese schrieb:> Ich hab nicht dran gedacht, die Interrupts auszuschalten. War noch vom> vorherigen Code, wo die ISR(ADC) genutzt wurde.
Eben. Das musst du dir merken. Zu jedem freigegebenen Interrupt gehört
zwingend eine ISR. Sonst kracht's. Hast du ja gesehen :-)
Räusper schrieb:> Eben. Das musst du dir merken. Zu jedem freigegebenen Interrupt gehört> zwingend eine ISR. Sonst kracht's. Hast du ja gesehen :-)
ist verinnerlicht.
in meinem Kopf war das so:
wo keine Aufruf (Interrupt), da kein Interrupt :) Danke euch allen.
Das hier:
> // ADCSRA |= (1<<ADIE); geht> ADCSRA |= (1<<ADIE); geht nicht.
gibt einen Hinweis auf die Lösung.
Da der TIMER0-Interrupt und der ADC-Interrupt gleichzeitig auftreten,
wenn das ADIE-Bit im ADCSRA gesetzt ist, werden zwei Interrupts
gleichzeitig getriggert.
Diese Interrupts werden vom AVR nacheinander bearbeitet in der
Reihenfolge, wie sie im Datenblatt in Tabelle 12-1 aufgeführt sind.
Timer0_compA wohnt im Vector Nr.15, der ADC-Interrupt hat den Vector
Nr.22
In den Vektoren werden vom Compiler Sprungbefehle zum Anfang der
jeweiligen ISR eingefügt - aber nur, wenn auch eine im Programm
definiert ist.
Es wird also der Timer-Interrupt aufgeführt.
Der AVR ist so konstruiert, dass nach dem reti des Timer-Interrupts
zunächst ein Befehl des Hauptprogramms ausgeführt wird, dann wird in den
Vector des ADC verzweigt. Da ist aber nun kein Sprungbefehl eingetragen
(ich habe den Thread nochmal überflogen und nicht gesehen dass eine ISR
für den ADC definiert wurde.)
Also steht in Vector Nummer 22 vermutlich 0xFFFF , genau wie in Vector
Nummer 23-26 vermutlich auch. Der AVR versucht die 0xFFFF als Befehl zu
interpretieren. Entweder ist dass Bitmuster unbekannt, dann wird es als
"nop" interpretiert, oder es wird irgendetwas sinnfreies gemacht.
Da 0xFFFF jedoch kein Sprung ist, läuft der AVR nach dem Ende der
Vectortabelle ganz banal in den C-startup-Code, und alles wird neu
initialisiert. Das ist nicht direkt ein Reset, aber ich denke auf die
Variablen wirkt es so. (bei einem Reset im AVR würden auch die Register
auf die Reset-Werte gestellt, das ist hier aber nicht so)
Jedenfalls sollte das beobachtete Verhalten so zu erklären sein.
Cheers
Wolfgang
WeißerRiese schrieb:> Julian .. schrieb:>> Ohne deinen Vollständigen Code zu kennen kann>> dir hier keiner effektiv helfen.>> Es hat sich doch schon lange erledigt. Ich denke kaum, dass jemand Lust> hat sich durch den ganzen Code zu wurschteln.
Test?
Was meinst du macht mehr spass:
- Raten was im vorenthaltenden Code steht
- Nachschauen zu können was Sache ist.
> Julian .. schrieb:>>> // ADCSRA |= (1<<ADIE); geht>>> ADCSRA |= (1<<ADIE); geht nicht.>>>> mit deinem Code in einklang zu bringen passt das hinten>> und vorne nicht.>> Doch tut es..
Mit dem Code vor deiner Nase vielleicht.
Ich habe hier nur den: http://pastebin.com/w9Fx16Ye
Ergo bleibe ich bei meiner Aussage das das nicht zusammen passt.
>>Du hast keine ISR für den ADC drin,>> Braucht man nicht.
Wenn du die Interrupts beim ADC einschaltest (1<<ADIE) schon.
>> ergo das ding macht einen reset, was nicht sein kann>> da du den ADC noch nicht mal startest geschweige denn>> ..Autostart. Alle Werte und Frequenzen sind korrekt. Counter läuft wie> er soll.
In http://pastebin.com/w9Fx16Ye ist kein ADC autostart drin....
Julian .. schrieb:> Wenn du die Interrupts beim ADC einschaltest (1<<ADIE) schon.
(Hatte dich missverstanden).
Entschuldige. Damit hast du auch vollkommen recht und das war auch der
Auslöser. (Richtig konnte keiner von euch riechen)
Ich habe den Interrupt ignoriert, weil ich es nicht besser wusste. Ist
ja auch meine heutige Erkenntnis. Also dir auch vielen Dank noch.
@Wolfgang,
Danke für die ausführliche Information.
@WeißerRiese: gerne, leider war ich zum Ende hin nicht ganz korrekt.
Bin gerade mal durchgegangen, was der GCC hier produziert. In einem
nicht verwendeten Vector läßt GCC keineswegs 0xFFFF stehen, sondern fügt
in unbenutzten Vektoren Sprünge in einen Teil des Startup-codes ein, an
dem ein Sprung auf den Resetvektor steht, in dem wiederum ein Sprung auf
den Beginn des Startupcodes steht.
Das Ergebnis ist allerdings dann das selbe.
Cheers!
Wolfgang
wneudert schrieb:
Okay, zu spät. Jetzt habe ich das aber schon getippt....
> Also steht in Vector Nummer 22 vermutlich 0xFFFF , genau wie in Vector> Nummer 23-26 vermutlich auch. Der AVR versucht die 0xFFFF als Befehl zu> interpretieren. Entweder ist dass Bitmuster unbekannt, dann wird es als> "nop" interpretiert, oder es wird irgendetwas sinnfreies gemacht.
Im .lss File steht bei nicht definierten IRQs:
Springe zu __bad_interrupt.
__bad_interrupt hat nur einen Befehl: jmp auf 0x0000
Also ein Pseudo Reset (ein Hardware Reset wird nicht ausgelöst).
Genau wie in der Dokumentation beschrieben:
http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
WeißerRiese schrieb:
> (Richtig konnte keiner von euch riechen)
Deswegen wird hier immer darauf bestanden den Vollständigen Code zu
zeigen.
> Ich habe den Interrupt ignoriert, weil ich es nicht besser wusste. Ist> ja auch meine heutige Erkenntnis.
Das wird dir nicht mehr passieren ;-)
> Also dir auch vielen Dank noch.
Aber Gerne doch.
Ingo L. schrieb:> Juergen R. schrieb:>> Ich würde mal als aller erstes in der ISR mit cli() verhindern dass>> weitere Interrupts die ISR unterbrechen.>> Achtung am Ende der ISR das sei() nicht vergessen.> Bloß nicht, das macht der GCC von selber... ISRs auf nem AVR sind von> Natur aus unterbrechungsfrei
Damit hätte doch Jürgen Recht?
Die Routine läuft ja "nicht-atomar" ab?
(Entschuldigt meine wahrscheinlich erfundene Fachbegriffe.)
Interrupts werden zu keinem Zeitpunkt ausgeschalten.
Julian .. schrieb:> Also ein Pseudo Reset (ein Hardware Reset wird nicht ausgelöst).
Das deckt sich auch damit, dass kein Zeichen mehr empfangen werden muss.
Julian .. schrieb:> Deswegen wird hier immer darauf bestanden den Vollständigen Code zu> zeigen.
Wenn ich mir nicht zu 100% sicher gewesen wäre, dass es nicht an dem
ADC-Interrupt liegt..
(aber ich habe vergessen, dass ihr nicht wissen könnt, dass ich kein
ADC_ISR habe... ;) )
Der AVR hat keine echten Interruptprioritäten.
Wenn eine ISR dran ist, ist sie dran und kann nicht unterbrochen werden.
Es sei denn, du setzt von Hand das I-Flag im Statusregister wieder.
Cheers!
Wolfgang
wneudert schrieb:> Der AVR hat keine echten Interruptprioritäten.> Wenn eine ISR dran ist, ist sie dran und kann nicht unterbrochen werden.> Es sei denn, du setzt von Hand das I-Flag im Statusregister wieder.
Ich dachte, genau das Gegenteil ist dann der Fall.
Da keine Priorität = alle gleichwertig.
D.h. wenn die nächste dran ist, ist sie halt jetzt dran.
Carl D. schrieb:> Wenn man eineISR(BADISR_vect) {> // some usefull debug code> }anlegt, dann kann man dieses Problem abfangen.
Wieder was gelernt. Merci!
Priorität bei Interrupts bedeutet, dass eine ISR mit niedrigerer
Priorität durch eine ISR höherer Priorität unterbrochen werden kann.
Das aber gibt es bei ATTINY- und ATMEGA-AVRs nicht. Da sind alle
gleichwertig (mit gleicher Priorität), und gleiche Prioritäten
unterbrechen sich nicht gegenseitig.
Im Datenblatt wird trotzdem das Wort Priorität erwähnt.
Das bedeutet nur, daß, wenn mehrer Interrupt mehr oder weniger
gleichzeitig auftreten und die entsprechenden Flags gesetzt sind, die
zugehörigen ISRs in der Reihenfolge abgearbeitet werden, wie sie in der
Position in der Tabelle liegen.
Deswegen kommt zum Beispiel die Timer-ISR vor der ADC-ISR dran, wenn
beide Interrupts gleichzeitig auftreten.
Cheers!
Wolfgang
na gut!
Nur wird der nicht in der Vektoren eingetragen, sondern im C-Startup
gibts einen Sprung, entweder auf den 0x0000 oder auf diese BADISR.
In den Vectoren stehen wiederum Sprünge auf diesen Sprung.
:)
Nur so um spitzfindig zu bleiben :)
Eigentlich wollt ich dem TO erklären, wie das geht. Denn der hat
gezeigt, daß er was dazulernen will. Manche Feinheiten wird er später
selbst rausbekommen. (Und ja Klugscheisser deiner Art sind zum K.....)
WeißerRiese schrieb:> Der "Pseude-Reset" erklärt dann auch, warum ich 1er (einmal> inkrementiert) ständig bekommen habe. Danke fürs Aufklären.> Wieder was gelernt. Merci!
Das glaube ich nicht.
Ich glaube, du wirst die Leute nur verarschen und die meisten sind
darauf reingefallen.
Erstens:
WeißerRiese schrieb:> Sorry obig genannter Code liefert mir zurück eine> 129, DEC> es wird nichts inkrementiert und gibt auch kein Überlauf.Wie soll da die 129 reinkommen wenn der uC ständig resettet ?
Zweitens:
WeißerRiese schrieb:> Julian .. schrieb:>> Oder der µC macht einen Reset. Das geht so schnell, das>> merkst du nicht -> ausbremsen mit einem LED-Test am anfang.>> ausgeschlossen. Die "Messung" startet erst wenn ein bestimmtes Zeichen> empfangen wird.
An deiner Stelle würde ich aufhören rumzutrollen.
Carl D. schrieb:> Eigentlich wollt ich dem TO erklären, wie das geht. Denn der hat> gezeigt, daß er was dazulernen will. Manche Feinheiten wird er später
Er hat nur gezeigt, dass er ein Troll ist, dass sein Programm und das
was er hier erzählt, nichts gemeinsam haben und dass er alle für zu
dumm hält, um sein (nicht gepostetes) Programm zu verstehen.
Deswegen hält er es auch nicht für nötig, dieses Glanzwerk der
Programmierkunst hier zu zeigen.
Marc V. schrieb:> Ich glaube, du wirst die Leute nur verarschen und die meisten sind> darauf reingefallen.
Mist. Wie hast du mich nur erwischt?
Marc V. schrieb:> Wie soll da die 129 reinkommen wenn der uC ständig resettet ?
Wenn du es wissen, willst nur für dich kann ich nochmal probieren.
Glaube es war bei der Initialisierung mit static volatile eine 1 und nur
mit static eine 129.
Marc V. schrieb:>> ausgeschlossen. Die "Messung" startet erst wenn ein bestimmtes Zeichen>> empfangen wird.>> An deiner Stelle würde ich aufhören rumzutrollen.
Das nennt sich dann Bluetooth-Kommunikation mit einem Mobilfunkgerät.
Dieses genannte Gerät schickt so komische Zeichen wenn man bei der App
so komische virtuelle Knöpfe betätigt. Abhängig davon erledigt der µC
sein Zeugs.. Wenn keine Knöpfe gedrückt -> µC warten. Wenn µC reset-> µC
nichts machen.
Marc V. schrieb:> Er hat nur gezeigt, dass er ein Troll ist, dass sein Programm und das> was er hier erzählt, nichts gemeinsam haben und dass er alle für zu> dumm hält, um sein (nicht gepostetes) Programm zu verstehen.> Deswegen hält er es auch nicht für nötig, dieses Glanzwerk der> Programmierkunst hier zu zeigen.
genau aus solchen Gründen habe ich das "Programm"
a) gekürzt bis aufs Minimum
b) vorenthalten.
Bei allem Respekt vor deinem Können Marc, hast du es nachts wirklich
nötig auf einem Anfänger rumzuhacken mit einem Beitrag, der nichts
sinnvolles beiträgt?
Das Thema ist hier doch schon lange durch.
Angenehmes Nächtle.
Wenn jemand den Code haben möchte (was auch immer er damit machen
möchte) oder mich noch jemand für einen Troll hält
(@Marc, ich musste herzhaft lachen.), teile ich Ihn natürlich.
Zwecks Fragestellung ist das nicht mehr notwendig, denn diese hat sich
lediglich darauf bezogen, ob das Vorgehen bzgl. der Inkrementierung
innerhalb einer ISR richtig war.
Denn dadurch konnte ich vermeindliche Fehler ausschließen und bin euch
dankbar dafür, unglaublich wie manchen einfach die Diskussions-Lust
nicht vergeht.
Klasse Forum, weiter so! :D :D