Hallo zusammen,
ich bin gerade an einem Projekt in C für den Atmega88P. Als
"Alive-Anzeige" lasse ich nebenher eine LED im Sekundentakt blinken. Das
entsprechende Port-Bit toggle ich direkt in der ISR vom Timer0:
1
#define DEBUG_DIR DDRC
2
#define DEBUG_VAL PORTC
3
#define DEBUG_PIN PC5
4
5
ISR(TIMER0_COMPA_vect){
6
7
++tick_ms;
8
if(tick_ms==1000){
9
/* Set debug state */
10
DEBUG_VAL^=(1<<DEBUG_PIN);
11
tick_ms=0U;
12
}
13
14
}
Ich habe im AtmelStudio 7 einen Breakpoint auf die Null-Zuweisung
gesetzt jedoch sieht man keine Änderung des Zustands (ist dauerhaft
gesetzt). Woran liegt es? Am Programm oder an der Bedienung des
Simulators?
Gruß Dennis
Dennis S. schrieb:> Woran liegt es?> Am Programm
Wenn es keinen Rest vom Programm gibt, den wir nicht sehen dann liegt es
wohl am Programm.
> oder an der Bedienung des Simulators?
könnte man ja testen im dem man den Breakpoint woanders setzt.
Christian M. schrieb:> Müsste das nicht tick_ms++; heißen?
Nein...
Peter II schrieb:> Wenn es keinen Rest vom Programm gibt, den wir nicht sehen dann liegt es> wohl am Programm.
Es gibt einen Rest (siehe unten). Aber da alles andere funktioniert und
die ISR in keiner Verbindung zum restlichen Programm steht habe ich mich
aufs Wesentliche konzentriert.
> könnte man ja testen im dem man den Breakpoint woanders setzt.
Habe ich und funktioniert wie gewünscht. Die Frage ist eher: hat der
Simulator vielleicht Probleme eine ISR zu debuggen oder so?
Gruß Dennis
1
#include<stdint.h>
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<util/delay.h>
5
#include"config.h"
6
7
typedefenumSTATE{
8
IDLE,
9
RUN_UPSTAIRS,
10
RUN_DOWNSTAIRS
11
}state_t;
12
13
/* global variables */
14
volatileuint16_ttick_ms;
15
volatileuint8_ttick_s;
16
volatilestate_tcurrent_state;
17
18
voidinitGPIO(void){
19
20
/* Complete PORTD is used as output for LED stripes */
21
LED_DIR=(1<<LED1)|(1<<LED2)|(1<<LED3)|(1<<LED4)|
22
(1<<LED5)|(1<<LED6)|(1<<LED7)|(1<<LED8);
23
24
/* Set Pin PC5 as debug port for */
25
DEBUG_DIR=(1<<DEBUG_PIN);
26
27
/* Set two Pins of PORTB as inputs for sensors */
28
INP_DIR&=~((1<<SENSOR_TOP)|(1<<SENSOR_BOTTOM));
29
30
}
31
32
voidinitTIMER(void){
33
34
TCCR0A=(1<<WGM01);/* Enable CTC mode */
35
TCCR0B|=(1<<CS01);/* Set prescaler to 8 */
36
OCR0A=OCR0A_VALUE-1;/* Set upper limit */
37
38
/* Enable Timer- and Global Interrupt */
39
TIMSK0|=(1<<OCIE0A);
40
sei();
41
42
}
43
44
voidlong_delay(uint16_tms){
45
46
for(;ms>0U;--ms){
47
_delay_ms(1);
48
}
49
50
}
51
52
voidrunUpstairs(void){
53
54
for(uint8_ti=0U;i<8;++i){
55
LED_VAL=(LED_VAL<<1U)|1U;
56
long_delay(TURN_ON_MS);
57
}
58
59
long_delay(TURN_OFF_MS);
60
LED_VAL=0U;
61
62
}
63
64
voidrunDownstairs(void){
65
66
for(uint8_ti=0U;i<8;++i){
67
LED_VAL=(LED_VAL>>1U)|0x80U;
68
long_delay(TURN_ON_MS);
69
}
70
71
long_delay(TURN_OFF_MS);
72
LED_VAL=0U;
73
74
}
75
76
intmain(void){
77
78
initGPIO();
79
initTIMER();
80
81
current_state=IDLE;
82
83
while(1){
84
85
/* Get values from sensors */
86
if(INP_VAL&(1<<SENSOR_BOTTOM)){
87
current_state=RUN_UPSTAIRS;
88
}
89
elseif(INP_VAL&(1<<SENSOR_TOP)){
90
current_state=RUN_DOWNSTAIRS;
91
}
92
93
switch(current_state){
94
caseRUN_UPSTAIRS:
95
runUpstairs();
96
current_state=IDLE;
97
break;
98
99
caseRUN_DOWNSTAIRS:
100
runDownstairs();
101
current_state=IDLE;
102
break;
103
104
caseIDLE:
105
default:
106
/* some error occurred */
107
current_state=IDLE;
108
break;
109
}
110
}
111
112
return0;
113
114
}
115
116
ISR(TIMER0_COMPA_vect){
117
118
++tick_ms;
119
if(tick_ms==1000){
120
/* Set debug state */
121
DEBUG_VAL^=(1<<DEBUG_PIN);
122
tick_ms=0U;
123
}
124
125
}
Header:
1
#ifndef CONFIG_H_9D7E44C9__
2
#define CONFIG_H_9D7E44C9__
3
4
/* Timer config: Check consistency with initTIMER() */
Dennis S. schrieb:> Habe ich und funktioniert wie gewünscht. Die Frage ist eher: hat der> Simulator vielleicht Probleme eine ISR zu debuggen oder so?
hast du wirklich lange genug gewartet? (einfach mal Pause drücken und
die CPU-Zeit anschauen)
Hinweis:
long_delay braucht man nicht mehr, du kannst direkt _delay_ms aufrufen.
Peter II schrieb:> hast du wirklich lange genug gewartet? (einfach mal Pause drücken und> die CPU-Zeit anschauen)
Probiere ich mal aus, danke! Habe schon gemerkt, dass das ganze nicht
"Echtzeit" ist. Ich arbeite sonst unter Linux und habe wenig Erfahrung
mit dem AtmelStudio.
> Hinweis:> long_delay braucht man nicht mehr, du kannst direkt _delay_ms aufrufen.
Was heißt das genau? Ab einer bestimmten AVR-LIB-Version? Ich hätte das
Ganze gerne so portabel wie möglich.
Gruß Dennis
Dennis S. schrieb:> Peter II schrieb:>> hast du wirklich lange genug gewartet? (einfach mal Pause drücken und>> die CPU-Zeit anschauen)
Ich denke ja.. wenn das Programm läuft ist im Memory Fenster "prog
FLASH" deaktiviert. Beim Breakpoint geht es dann wieder. Ich denke das
sollte reichen? Aber der Pin bleibt permanent auf 1...
Ich habe leider gerade keine Hardware hier. :-/
Dennis S. schrieb:> Was heißt das genau? Ab einer bestimmten AVR-LIB-Version? Ich hätte das> Ganze gerne so portabel wie möglich.Dennis S. schrieb:> Was heißt das genau? Ab einer bestimmten AVR-LIB-Version?
ja, aber die ist bestimmt schon 10Jahre alt.
> Ich hätte das Ganze gerne so portabel wie möglich.
bei der alten Version gab es auch noch andere namen für die ISR also eh
nicht wirklich portabel.
@Peter II (Gast):
Da muss ich doch noch mal nachhaken: Unter [1] steht "bis 6553,5 ms".
Das wäre für den "Produktiveinsatz" der Treppenbeleuchtung sicher zu
wenig! Die Werte in der config.h sind lediglich um beim Simulieren nicht
so lange warten zu müssen.
Gruß Dennis
[1] http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Dennis S. schrieb:> Da muss ich doch noch mal nachhaken: Unter [1] steht "bis 6553,5 ms".> Das wäre für den "Produktiveinsatz" der Treppenbeleuchtung sicher zu> wenig! Die Werte in der config.h sind lediglich um beim Simulieren nicht> so lange warten zu müssen.
oh, merkwüdig. Ich kannte nur
> Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz)> überschritten, so arbeitet _delay_ms() einfach etwas ungenauer
Dieter F. schrieb:> Definierst Du auch irgendwo F_CPU?
Ja in den Compileroptionen.. Aber das wird ja kaum der Grund sein, dass
ein GPIO nicht gesetzt wird oder? Zumal die entsprechende Zeile ja wie
beschrieben periodisch aufgerufen wird.
Gruß
Dennis
Dennis S. schrieb:> Aber das wird ja kaum der Grund sein, dass> ein GPIO nicht gesetzt wird oder?Dennis S. schrieb:> #define OCR0A_VALUE ( (F_CPU / PRESCALER) / IRQ_VALUE_MS )
...
> OCR0A = OCR0A_VALUE-1; /* Set upper limit */
K.A., was rauskommt, wenn F_CPU nicht definiert ist
Wenn der Interrupt permanent aufgerufen wird passiert sonst nicht mehr
viel ....
Wie prüfst Du das denn? Mit einer LED? Oder hast Du ein Oszilloskop?
Dieter F. schrieb:> Wenn der Interrupt permanent aufgerufen wird passiert sonst nicht mehr> viel ....
doch, es wird immer noch ein Befehl außerhalb der ISR ausgeführt.
Außerdem hat er geschrieben das F_CPU definiert ist.
1) Ich sagte nicht, dass die ISR permanent aufgerufen wird sondern
periodisch. Das ist auch der Zweck eines Timers..
2) Mal abgesehen davon, dass ich F_CPU selber definiert habe, hier
folgendes aus der "delay.h":
1
#ifndef F_CPU
2
/* prevent compiler error by supplying a default */
3
# warning "F_CPU not defined for <util/delay.h>"
4
# define F_CPU 1000000UL
5
#endif
Aber es scheint jetzt ein bisschen in Nebenschaukämpfe auszuarten. Im
Code scheint jedenfalls kein offensichtlicher (Flüchtigkeits-)Fehler zu
sein, Ist ja auch nicht wirklich Hexenwerk da drin... Ich habe
(weiterhin) den Simulator in Verdacht. Aber da das nicht wirklich
wichtig ist weil ich in der Regel nicht damit arbeite, lasse ich es mal
darauf beruhen.
Gruß
Dennis
Dennis S. schrieb:> Ich habe im AtmelStudio 7 einen Breakpoint auf die Null-Zuweisung> gesetzt jedoch sieht man keine Änderung des Zustands (ist dauerhaft> gesetzt). Woran liegt es? Am Programm oder an der Bedienung des> Simulators?
Wie definierst Du "keine Änderung des Zustands"? Was "... ist dauerhaft
gesetzt ..."?
Hält der Simulator überhaupt bei Deinem Brechpunkt an?
Erhälst Du Compiler-Warnungen?
In solchen Fällen schalte ich die Compiler-Optimierung komplett aus und
das Debug-Level auf Maximum.
Übrigens bekomme ich 2 Warnungen - aber mit vorgenannten Einstellungen
funktioniert alles (d.h. im Interrupt wird korrekt getriggert) - WENN
ich die Definitionen vor das Programm setze.
Möglicherweise hast Du ein Problem mit Deinem
#include "config.h"
oder Deinen
#ifndef CONFIG_H_9D7E44C9__
#define CONFIG_H_9D7E44C9__
falls sich diese (u. a. ???) in Deiner "config.h" befinden.
Vollständiges Coding vorzuzeigen ist anders ...
Ein Bild meines Debuggers (Simulator) nach dem ersten Interrupt anbei.
Der Programmname Murks hat NICHTS mit Deiner Entwicklung zu tun -
darunter packe ich alle Tests, die ich hier so mit Fremd-Programmen
durchführe (hätte ich auch "Temp" nennen können - hätte ich ...) :-)
Dennis S. schrieb:> 2) Mal abgesehen davon, dass ich F_CPU selber definiert habe, hier> folgendes aus der "delay.h"
Ja, warum weist Du darauf hin, wenn Du F_CPU definiert hast?
Ansonsten ist es immer sinnvoll, das komplette Projekt zu posten. Wenn
ich gerade Zeit habe (und andere auch) wird das ggf. mal durchgespielt
und Du bekommst auch Feedback. Bei Fragmenten ist das aber nicht
unbedingt (qualifiziert) möglich.
Dieter F. schrieb:> Wie definierst Du "keine Änderung des Zustands"? Was "... ist dauerhaft> gesetzt ..."?
"Dauerhaft gesetzt" bedeutet in diesem Zusammenhang, dass an den
diskreten Ereignissen des Anhaltens beim genannten Breakpoint der
entsprechende PortPin auch nach dem Durchlaufen des Codes zum Toggeln
des Bits den gleichen Wert behält. Dies ist ein unerwarteter Effekt,
weil... nun ja... ein Code zum Togglen des Bits das Bit togglen sollte.
> Hält der Simulator überhaupt bei Deinem Brechpunkt an?
Ja. Wie sonst sollte ich sehen, welchen Wert der Portpin hat?
> Erhälst Du Compiler-Warnungen?
Nein.
> In solchen Fällen schalte ich die Compiler-Optimierung komplett aus und> das Debug-Level auf Maximum.>> Übrigens bekomme ich 2 Warnungen - aber mit vorgenannten Einstellungen> funktioniert alles (d.h. im Interrupt wird korrekt getriggert) - WENN> ich die Definitionen vor das Programm setze.
Welche Warnungen? Welche Definitionen? Bitte vollständige Informationen
liefern da sonst eine Fehlersuche erschwert wird..
> Möglicherweise hast Du ein Problem mit Deinem>> #include "config.h"> oder Deinen> #ifndef CONFIG_H_9D7E44C9__> #define CONFIG_H_9D7E44C9__>> falls sich diese (u. a. ???) in Deiner "config.h" befinden.
Ähm... das sind Include-Guards.. wo sollen die denn sonst sein?
> Vollständiges Coding vorzuzeigen ist anders ...
Was fehlt dir? Das Programm besteht nur aus den beiden Files die oben
schon gepostet wurden.
> Ein Bild meines Debuggers (Simulator) nach dem ersten Interrupt anbei.> Der Programmname Murks hat NICHTS mit Deiner Entwicklung zu tun -> darunter packe ich alle Tests, die ich hier so mit Fremd-Programmen> durchführe (hätte ich auch "Temp" nennen können - hätte ich ...) :-)
Ist leider völlig nichtssagend.. man sieht ja an einem Bild nicht ob das
Bit wechselt. Das gleiche Bild habe ich hier ja auch.
Dieter F. schrieb:> Ja, warum weist Du darauf hin, wenn Du F_CPU definiert hast?
Weil du gefragt hast (15:26 Uhr und 17:22 Uhr).
> Ansonsten ist es immer sinnvoll, das komplette Projekt zu posten. Wenn> ich gerade Zeit habe (und andere auch) wird das ggf. mal durchgespielt> und Du bekommst auch Feedback. Bei Fragmenten ist das aber nicht> unbedingt (qualifiziert) möglich.
Welche Settings im AtmelStudio sind relevant? Wie gesagt: ich nutze es
zum ersten Mal.
Dieter F. schrieb im Beitrag #4622235:
> Ah, scheinbar ein Volltreffer ...
Für was genau?
Gruß Dennis
Dennis S. schrieb:>> Hält der Simulator überhaupt bei Deinem Brechpunkt an?> Ja. Wie sonst sollte ich sehen, welchen Wert der Portpin hat?
Das frage ich mich auch.
Dennis S. schrieb:> Welche Warnungen? Welche Definitionen? Bitte vollständige Informationen> liefern da sonst eine Fehlersuche erschwert wird..
Die solltest Du auch bekommen haben (falls Du compiliert hast), wenn
F_CPU nicht definiert ist - beigefügt.
Dennis S. schrieb:>> falls sich diese (u. a. ???) in Deiner "config.h" befinden.> Ähm... das sind Include-Guards.. wo sollen die denn sonst sein?
Das weiß ich nicht, da Du "config.h" nicht (komplett) beigefügt hast.
Dennis S. schrieb:>> Vollständiges Coding vorzuzeigen ist anders ...> Was fehlt dir? Das Programm besteht nur aus den beiden Files die oben> schon gepostet wurden
Du hast keine 2 Files gepostet ...
Dennis S. schrieb:> Ist leider völlig nichtssagend.. man sieht ja an einem Bild nicht ob das> Bit wechselt. Das gleiche Bild habe ich hier ja auch.
Dann weißt Du ja auch, das der erste Toggle-Vorgang erfolgreich war -
willst Du uns veralbern? Ursprünglich war das Bit auf 0 / low. Übrigens
wechselt das beim nächsten Interrupt wieder auf 0.
Veralbern kann ich mich selbst - viel Spaß noch ...
Dieter F. schrieb:> Das frage ich mich auch.
Antwort: es geht (meines Wissens) nicht im Simulator. Siehe (unter
Anderem) im Topic-Titel.
> Dennis S. schrieb:> Die solltest Du auch bekommen haben (falls Du compiliert hast), wenn> F_CPU nicht definiert ist - beigefügt.
Puhhh... reitest du immer noch darauf rum? Nochmals für dich: F_CPU ist
in den Projekteinstellungen definiert. Echt jetzt... Peter II (Gast) hat
das um 17:24 Uhr vestanden.
> Dennis S. schrieb:> Das weiß ich nicht, da Du "config.h" nicht (komplett) beigefügt hast.
Doch: 14:43 Uhr. Die Transferleistung von Datei zu Code-Tags habe ich
jetzt mal vorausgesetzt.
> Dennis S. schrieb:> Du hast keine 2 Files gepostet ...
Doch: 14:43 Uhr. Die Transferleistung von Datei zu Code-Tags habe ich
jetzt mal vorausgesetzt.
> Dennis S. schrieb:> Dann weißt Du ja auch, das der erste Toggle-Vorgang erfolgreich war -> willst Du uns veralbern? Ursprünglich war das Bit auf 0 / low. Übrigens> wechselt das beim nächsten Interrupt wieder auf 0.
Nein.. eben NICHT. Das ist doch das Problem. Und schon gar nicht beim
nächsten Interrupt. Sieht man ja in der ISR.
> Veralbern kann ich mich selbst - viel Spaß noch ...
Ach ehrlich.. du willst dich doch hier nur wichtig machen ohne auch nur
annähernd zu wissen worum es geht. Ich kann auf deine "Hilfe"
verzichten. Vielen Dank für deine Beteiligung.
Gruß Dennis
Dennis S. schrieb:> Ach ehrlich.. du willst dich doch hier nur wichtig machen ohne auch nur> annähernd zu wissen worum es geht. Ich kann auf deine "Hilfe"> verzichten. Vielen Dank für deine Beteiligung.
Laller
Hi,
ich habs mal im Atmel Studio 7.0.790 simuliert und bei mir toggelt PC5.
Der Breakpoint war auf die Nullzuweisung gesetzt.
Brauchst du das Dissasembly zum vergleichen ?
Gruß JackFrost
Dennis S. schrieb im Beitrag #4622371:
> FALLS du fachliche Anmerkungen> hast, beschränk dich bitte darauf.
Das habe ich gepostet - leider verstehst Du die nicht.
Lies doch mal nach, wie der Debugger des Atmel-Studio funktioniert - und
schau Dir danach meine Hardcopies an. Falls Du Englisch nicht verstehst
gibt es ganz gute Übersetzungsprogramme - musst Du halt mal googlen.
Bastian W. schrieb:> ich habs mal im Atmel Studio 7.0.790 simuliert und bei mir toggelt PC5.
Ich schaue mal welche Version ich habe. Auf jeden Fall unter Win7 64
Bit.
> Der Breakpoint war auf die Nullzuweisung gesetzt.
Hatte ich auch. Wie genau bist du vorgegangen?
1 - Breakpoint auf "tick_ms = 0U;"
2 - Menüpunkt "Start Debugging and break"
3 - Wiederholt "continue" (wenn ich es richtig in Erinnerung habe?
> Brauchst du das Dissasembly zum vergleichen ?
Das wäre nett, kann ich aber erst morgen gegenchecken.
Gruß Dennis
Dennis S. schrieb:> 3 - Wiederholt "continue" (wenn ich es richtig in Erinnerung habe?
Warum, wenn es nur einen break-point gibt?
Es dauert ein Weilchen, aber man kann jedes mal die Veränderung (des
PORT-BITs) beobachten.
Zum break-point (in Deinem Fall) hat "tick_ms" natürlich immer den
gleichen Wert.
Ich habe alle Schritte seit dem Toggeln in Screenshots festgehalten -
aber das war ja nur
Dennis S. schrieb im Beitrag #4622356:
> Fein.. und nutzlos.
Für mich war es dann jetzt endgültig - freu Dich Denis S. :-)
Dennis S. schrieb:> Hatte ich auch. Wie genau bist du vorgegangen?> 1 - Breakpoint auf "tick_ms = 0U;"> 2 - Menüpunkt "Start Debugging and break"> 3 - Wiederholt "continue" (wenn ich es richtig in Erinnerung habe?
Bei Punkt 2 habe ich "Start Debugging and break" und "Start Debugging"
gemacht. War kein Unterschied. Sollte auch keinen Einfluss haben.
Dennis S. schrieb:> Ich schaue mal welche Version ich habe. Auf jeden Fall unter Win7 64> Bit.
Ich hab auch Win7 64 Bit.
Gruß JackFrost
Dieter F. schrieb:> Zum break-point (in Deinem Fall) hat "tick_ms" natürlich immer den> gleichen Wert.
Was denn auch sonst. Aber was hat der direkt mit dem Problem zu tun?
Dieter F. schrieb:> Ich habe alle Schritte seit dem Toggeln in Screenshots
Ich habe nie behauptet, dass es bei dir nicht geht. Die Frage war: wieso
funktioniert der gleiche Code nicht bei mir? Gibt es Einstellungen für
den Simulator Linker Compiler die das Verhalten beim Debuggen in der
ISR ändern? Gibt es Knwon-Bugs in AtmelStudio die dies hervorrufen
können? Mache ich etwas bei der Bedienung des Simulators falsch?
Dieter F. schrieb:> Für mich war es dann jetzt endgültig
Vielen Dank. Du magst es nicht gerne hören, aber hier gibt es Leute die
mindestens die gleiche fachliche Kompetenz haben wie du OHNE die
herablassende Art.
Dennis S. schrieb:> Gibt es Einstellungen für> den Simulator Linker Compiler die das Verhalten beim Debuggen in der> ISR ändern?
Lesen kannst Du?
Dieter F. schrieb:> In solchen Fällen schalte ich die Compiler-Optimierung komplett aus und> das Debug-Level auf Maximum.Dennis S. schrieb:> OHNE die> herablassende Art.
Die kennst Du noch nicht :-) gute Nacht