Hallo,
kann man AVR Studio beibringen, dass es meckert, wenn man bei einer
Switch Case Anweisung das Break vergisst? Werror habe ich eingeschaltet.
Weiter interessier es mich, ob es einen Unterschied macht, den
Programmteil in der Switch Anweisung einzuklammern oder nicht?:
Case xyz:
{
....
break;
}
ich habe das dumme Problem, wenn ich in einer ISR die Switch-Case
Anweisung ausführe, das dann das Programm die ISR nicht mehr verlässt
und wdt greift (wdto60ms).
Mache ich den Programmausschnitt in der main-while(1) Schleife geht
alles. Jedoch muss die Ausführung der Switch Anweisung unmittelbar nach
dem adc-Complete Interrupt erfolgen, da es sehr zeitkritisch ist.
Ich habe den Inhalt der Switch-Anweisung in geschweiften Klammern, wie
oben.
Ich kann's leider im Moment nicht selber testen, bin unterwegs. Bin für
jeden Tipp dankbar.
MfG Hansi
Hans schrieb:> Programmteil in der Switch Anweisung einzuklammern oder nicht?:>> Case xyz:> {> ....> break;> }
Das macht dann einen Unterschied, wenn man noch eine lokale Variable
darin definiert (oder ähnliches), sonst nicht.
Hans schrieb:> kann man AVR Studio beibringen, dass es meckert, wenn man bei einer> Switch Case Anweisung das Break vergisst?
Meines Wissens nicht.
> Weiter interessier es mich, ob es einen Unterschied macht, den> Programmteil in der Switch Anweisung einzuklammern oder nicht?:
Nein. Es sei denn im Block sind lokale Variablen definiert.
Hans schrieb:> ich habe das dumme Problem, wenn ich in einer ISR die Switch-Case> Anweisung ausführe, das dann das Programm die ISR nicht mehr verlässt> und wdt greift (wdto60ms).
Da würde ich eher tippen, daß du noch etwas anderes falsch machst.
Hans schrieb:> kann man AVR Studio beibringen, dass es meckert, wenn man bei einer> Switch Case Anweisung das Break vergisst?
Vermutlich nicht, denn wenn man die break-Anweisung weglässt, ist das in
keiner Weise ein Fehler, sondern wird sogar oft und mit Absicht so
gemacht.
Und Zugriffe außerhalb der ISR darauf sind atomar?
Debugger steht dir nicht zur Verfügung um nachzuschauen, wo genau sich
der AVR in seiner Ausführung befindet?
Hans schrieb:> Ich kann's leider im Moment nicht selber testen, bin unterwegs. Bin für> jeden Tipp dankbar.
Nach Hause kommen, Code hier posten. Bis dahin ist das nur raten auf
Raten.
Oliver
A. K. schrieb:> Hans schrieb:>>> kann man AVR Studio beibringen, dass es meckert, wenn man bei einer>> Switch Case Anweisung das Break vergisst?>> Meines Wissens nicht.
Nope, sieht nicht so aus, zumindest nicht für gcc:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7652
Eventuell können einige statische Code-Checker hier aber Warnungen
werfen (z.B. "splint" o.ä.), hab ich nicht geprüft.
Hans schrieb:> Programmteil in der Switch Anweisung einzuklammern oder nicht?:
Aber sicher.
> Case xyz:> { ....> break;> }
Das break gehört jetzt nicht mehr zum switch, sondern zu der Anweisung,
die unter dem case läuft. Die wird dann mit einem break abgebrochen. Er
springt also aus dem geklammerten Teil raus und landet dann im
geklammerten Teil des switch. Da muß dann auch wieder ein break stehen.
Also:
switch(a)
{
case 0:
//Mach' was
break;
case 1:
{
int b;
//Mach' was
}
break;
}
Hans schrieb:> kann man AVR Studio beibringen, dass es meckert, wenn man bei einer> Switch Case Anweisung das Break vergisst?
Nein. Das hat mit AVR-Studio nichts zu tun, sondern mit C. Und da ist es
erlaubt.
mfg.
Thomas Eckmann schrieb:> Das break gehört jetzt nicht mehr zum switch, sondern zu der Anweisung,> die unter dem case läuft. Die wird dann mit einem break abgebrochen. Er> springt also aus dem geklammerten Teil raus und landet dann im> geklammerten Teil des switch. Da muß dann auch wieder ein break stehen.
Ein break gehört zum nächsten umgebenden for/while/do/switch Konstrukt,
egal wieviele {} Klammern zwischendrin stehen. Ob man den zu einem case
gehörenden Code umklammert oder nicht ändert nichts an der Zugehörigkeit
vom break.
Die 3 Varianten hier sind also in dieser Hinsicht gleich:
und aus dieser scheint es kein zurück mehr zu geben, da der AVR sich mit
der im WDT eingestellten Zeit resettet. Wenn ich die Funktion in der
main ausführen geht es, weil hier keine ISRs gesperrt sind und somit der
WDT im Timerintterupt (alles 7,nochwas ms) zurückgesetzt wird.
Werds Montag gleich mal an der Hardware ausprobieren, aber daran könnte
liegen (mit den geschweiften Klammern)?
Hansi
Hans schrieb:> kann man AVR Studio beibringen, dass es meckert, wenn man bei einer> Switch Case Anweisung das Break vergisst?
In Eclipse (Indigo) geht das.
A. K. schrieb:> Ein break gehört zum nächsten umgebenden for/while/do/switch Konstrukt,> egal wieviele {} Klammern zwischendrin stehen. Ob man den zu einem case> gehörenden Code umklammert oder nicht ändert nichts an der Zugehörigkeit> vom break.Thomas Eckmann schrieb:> as break gehört jetzt nicht mehr zum switch, sondern zu der Anweisung,> die unter dem case läuft. Die wird dann mit einem break abgebrochen. Er> springt also aus dem geklammerten Teil raus und landet dann im> geklammerten Teil des switch. Da muß dann auch wieder ein break stehen.
Wer hat denn nun Recht?
Hans schrieb:> und aus dieser scheint es kein zurück mehr zu geben
Du weisst aber nicht wirklich, ob die Funktion zurückkehrt, oder?
An der Funktion set_brake() kann es nicht liegen. Was passiert denn noch
so in der ISR?
Oliver
Hans schrieb:> void set_brake (unsigned char brake_mode, unsigned char state)
Füg' hier mal ein Watchdog-Reset ein. Vielleicht dödelt er die 8ms ja
schon vorher ab.
> {> switch (brake_mode)
Nachdem wir das jetzt mit den Klammern und dem break geklärt haben, muss
es ja irgendwo anders liegen.
Die Auswertung ist Moment noch mit direkten unskalierten ADC werten,
nicht wundern.
Wenn ich einmal die if-Passage betrete, verriegelt sich diese
anschließend durch verändern von brake_state selbst. Gleichzeitig wird
eine variable (timer) auf einen wert gesetzt und in im
Timeroverflow-Vektor decrementiert (Zeitfenster). Hier wird auch die
nächste Messung angestoßen und der wdt zurück gesetzt. Aber das passiert
alles schon garnicht mehr, da der wdt-reset dazwischen kommt. Ich sehe
noch wie der Pin PORTA |= (1<<TRIGGER_RB) auf H geht und noch 60ms der
WDT das Spiel beendet.
rfv schrieb:> Wird das ISR-Flag am Ende restet (von Dir)?
??? Das Flag löscht sich bei Verlassen der ISR selbst... ???!
Wie gesagt, wenn ich den teil unter
1
u_gen=ADC+1;
in die main packe, geht es einwandfrei, nur halt die Reaktion auf einen
zu hohen ADC-Wert dauert mir zu lange, da die Kiste auch "nur" auf 32kHz
Uhrenquarz läuft.
Hans schrieb:> da die Kiste auch "nur" auf 32kHz> Uhrenquarz läuft.
Dann verlängere mal deinen Watchdog. Das kann doch gar nicht gehen.
Was soll das überhaupt?
mfg.
Hans schrieb:> in die main packe, geht es einwandfrei, nur halt die Reaktion auf einen> zu hohen ADC-Wert dauert mir zu lange, da die Kiste auch "nur" auf 32kHz> Uhrenquarz läuft.
wenn ich mich recht erinnere braucht der ADC doch eine Frequenz zwischen
50kHz und 200kHz.
Was du da also mit deinem ADC misst ist Mist.
Ich denke aber auch, dass das Problem an dem WDT liegt.
weiß ja nicht, was du für einen ADC-Prescaler hast und auf was für eine
Sample-Dauer du am Ende kommst. Eventuell beißt der Hund vorher in die
Resetleitung.
Die ISR wird ja erst aufgerufen, wenn der ADC fertig meldet. Und dann
bleiben 1920 Zyklen, bis der wdt wieder zuschlägt. Das sollte für die
paar Anweisungen ausreichen.
Wenn möglich, schalte doch mal LEDs beim ein- und Austritt in die ISR.
Vielleicht ist der wdt ja auch falsch parametriert, und schlägt viel
schneller zu.
Oliver
Mit dem Watchdog ist das wie mit dem Sleep. Das wird zuletzt eingebaut.
Wenn alles andere läuft.
Dann findet man auch schneller den Fehler, wenn es irgendwo mit dem
Timing doch nicht so passt, wie erwartet.
mfg.
Das Problem tritt nicht auf, wenn ich es mit 1MHz laufen lasse. Folglich
fange ich mir das Timeout wegen zu langsam ein. Mit 120ms geht's auch
nicht. Merkwürdig...
Hans schrieb:> Merkwürdig...
Dann ist es jetzt vielleicht doch mal an der Zeit, den Simulator
anzuschmeißen, mit den passenden Stimuli zu füttern und zu gucken, womit
der µC sich denn so die Zeit vertreibt, bis ihn der Hund erwischt.
Aus dem Datenblatt:
By default, the successive approximation circuitry requires an input
clock frequency between 50kHz and 200kHz to get maximum resolution.
Und nun??? Internen WDT Oszillator mit 125kHz als Taktquelle nehmen?
Ich will sol wenig Strom wie möglich verbrauchen...
Aber sieht irgendjemand wo er sich ein Timout einfangen könnte?
Hier die Timer ISR:
1
/* System tick with 7,8ms */
2
ISR(TIMER0_COMPA_vect)
3
{
4
/* Watchdog reset */
5
wdt_reset();
6
7
/*start new conversation */
8
ADCSRA|=(1<<ADSC);
9
10
/* decrement timer */
11
if(timer)
12
{
13
timer--;
14
}
15
}
Watchdog resetten, neue Messung starten, wenn Wandlung fertig watchdog
resetten, ergebnis auswerten und von vorn.
was dauert da länger als 60ms (1966 Clocks)?
Hansi
Oliver schrieb:> Die ISR wird ja erst aufgerufen, wenn der ADC fertig meldet.
ebend.
wird der Wdt zwischendurch resetted?
> Und dann> bleiben 1920 Zyklen, bis der wdt wieder zuschlägt. Das sollte für die> paar Anweisungen ausreichen.Hansi schrieb:> Und nun??? Internen WDT Oszillator mit 125kHz als Taktquelle nehmen?> Ich will sol wenig Strom wie möglich verbrauchen...
dann laufe mit 1Mhz und lege dich in den Power Down und lass dich von
dem WDT wecken.
Ob du jetzt 10s mit 32kHz ackerst oder .3s mit 1Mhz -da wird
stromspartechnisch wahrscheinlich letzteres effektiver sein.
Vlad Tepesch schrieb:> Ob du jetzt 10s mit 32kHz ackerst oder .3s mit 1Mhz -da wird> stromspartechnisch wahrscheinlich letzteres effektiver sein.
Sehe ich auch so. Was für ein Controller ist das überhaupt?
mfg.
Karl Heinz Buchegger schrieb:> Dein im Nebel stochern bringt doch nix. Du verplemperst nur deine Zeit.
Richtig, der Simulator zeigte Klarheit. Ich habe mit dem nur noch nie
gearbeitet, aber ist ja relativ intuitiv...
Ich habe den Timer, der mit /* System tick with 7,8ms */
läuft falsch initialisiert, sodass der Timer0 im 16Bit Modus gelaufen
ist und merkwürdigerweise trotzdem irgendwie funktioniert hat. Das es
mir 1MHz lief, lag daran, dass das Programm eigentlich schon komplett
ausgeführt worden war, bis der Timeout entstand...
*Schande über mein Haupt, dass is n dummer Anfängerfehler*
Ich benutze einen Tiny861. Nun läuft es im Simulator und auch
hoffentlich in der Praxis am Montag. Besten Dank für alle Hilfen.
Hansi