Forum: Mikrocontroller und Digitale Elektronik Programm steht beim dimensionieren von Arrays?


von Stephan H. (stiph5)


Lesenswert?

Hey Leute!

Ich habe mal wieder ein Problem! Es handelt sich dabei um das 
Dimensionieren eines Arrays. Ich weiß eigentlich eine einfach Sache und 
keinen Foren beitrag wert. Doch mein Problem liegt vermutlich etwas 
tiefer. Entweder habe ich einen extremen Denkfehler, oder ich habe etwas 
in den Einstellungen von AVR Studio 4 so verändert, dass das 
Dimensionieren von Arrays nicht mehr funktioniert.

Mein Code:

uint8_t pwmdata[20];

So weit so gut. Build des Codes ist kein Fehler vorhanden. Doch beim 
Debuggen bleibt das Programm immer genau an dieser Stelle stehen. Was 
könnte das sein? Es hat ja vor einiger Zeit immer funktioniert, doch 
jetzt funktionieren die alten Programme auch nicht mehr.
Hat vielleicht jemand eine Idee?

Vielen Dank im Voraus:
Stephan

von Karl H. (kbuchegg)


Lesenswert?

Stephan Hochmüller schrieb:

> Mein Code:
>
> uint8_t pwmdata[20];
>
> So weit so gut. Build des Codes ist kein Fehler vorhanden. Doch beim
> Debuggen bleibt das Programm immer genau an dieser Stelle stehen. Was
> könnte das sein?

Eine Fehlinterpretation von dir bezüglich deer Debuggerausgabe.

Wenn der Optimizer eingeschaltet ist, darfst du nicht jede Zeilen, die 
dir im Debugger angezeigt ist, für bare Münze nehmen. Der Optimizer des 
Compilers hat den Code umgestellt und der Debugger hat dann das Problem, 
dass der Code den er gerade ausführt keine 1:1 Entsprechnung mehr mit 
dem Text hat, den der Programmierer geschrieben hat.

> jetzt funktionieren die alten Programme auch nicht mehr.
> Hat vielleicht jemand eine Idee?

Du hast Fehler im Programm, die sich in den älteren Compilerversionen 
nicht ausgewirkt haben aber jetzt durch Verbesserungen im Optimizer zum 
Vorschein kommen.


Mit der Arraydefinition hat das alles nichts zu tun. Die ist sauber und 
ist auch nicht die Ursache.

von Stephan H. (stiph5)


Lesenswert?

Hmm den Optimizer habe ich eigentlich nicht verstelle und ich arbeite 
auch noch immer mit der gleichen AVR-Studio-Version. Ich habe beim 
letzten Versuch mit Floatingpoints etwas an den Projekteinstellungen 
verändert, ist aber leider schon zu lange her, um mich noch genau daran 
zu erinnern was ich geändert habe… Jetzt habe ich das Programm neu 
installiert. Hat aber leider auch keine Abhilfe gebracht…

Bin gerade total ratlos, da ich auch nicht glaube, dass es einen 
Zusammenhang mit meinen Versuchen mit den Floatingpoints und meinem 
aktuellen Problem gibt.

von Noname (Gast)


Lesenswert?

Ganz ruhig, Brauner.
Auch wenn Du denkst, Du hast an den Optimierungen nichts verstellt, guck 
trotzdem mal nach.

von Stephan H. (stiph5)


Lesenswert?

Optemization: -OS. Habe aber auch schon die restlichen Möglichkeiten 
gecheckt. Leider auch nicht.

Ach Ja hier noch mal mein ganzer Code. Vielleicht findet jemand einen 
dummen Fehler, was aber das nichtfunktionieren der Alten Programme nicht 
erklären würde.

Ein Tiny 13 Sollte einen Sinus aus dem PWM-Ausgang erzeugen. Bis jetzt 
ist nur ein Teil der welle fertig, da ich bei meiner 
Arraydimensionierung hänge :(.

#include <avr/io.h>
#include <util/delay.h>





int main (void){
TCCR0A |= (1<<COM0A1)|(1<<WGM00)|(1<<WGM01);
TCCR0B |= (1<<CS00);
OCR0A = 255;
DDRB|=(1<<PB0);



uint8_t pwmdata[20];

pwmdata[0]=128;
pwmdata[1] =150;
pwmdata[2]=171;
pwmdata[3]=191;
pwmdata[4]=209;
pwmdata[5]=225;
pwmdata[6]=238;
pwmdata[7]=247;
pwmdata[8]=253;
pwmdata[9]=255;
pwmdata[10]=105;
pwmdata[11]=84;
pwmdata[12]=63;
pwmdata[13]=46;
pwmdata[14]=33;
pwmdata[15]=17;
pwmdata[16]=8;
pwmdata[17]=2;
pwmdata[18]=0;



while(1){

for(uint8_t i = 0; i==10; i++){
OCR0A = pwmdata[i];
_delay_us(500);
}



}


return 0;
}

von Karl H. (kbuchegg)


Lesenswert?

> for(uint8_t i = 0; i==10; i++){

Lies mal nach, was die einzelnen Bestandteile beim for machen. Speziell 
was der mittlere macht und wie er zu formulieren ist.


Eines kann man mit Sicherheit sagen: Dieses Programm hat noch nie 
funktioniert.

von Vlad T. (vlad_tepesch)


Lesenswert?

hmm also der Code sieht ok aus.
Die Konforguration der Register scheint auch zu stimmen.

Abgesehen, dass arrayinitialisierungen auch schöner gehen:
1
uint8_t pwmdata[] ={ 128, 150, 171, 191, 209, 225, 238, 247,
2
                     253, 255, 105,  84,  63,  46,  33,  17,
3
                       8,   2,   0};

bist du sicher, dass du den korekten Processor im Compiler und 
Simulator eingestellt hast?

PS benutze das nächste mal bitte die Code-Tags zu posten von Quellcode,

von Karl H. (kbuchegg)


Lesenswert?

Und wenn du dann deine for-Schleife richtig hast, dann schreibst du die 
Arrayinitialisierung um
1
uint8_t pwmdata[20] = 
2
{
3
  128, 150, 171, 191, 209, 225, 238, 247, 253, 255,
4
  105,  84,  63,  46,  33,  17,   8,   2,   0,   0
5
};

deiser Wust an Zuweisungen verstellt dir doch den Blick aufs 
Wesentliche: den eigentlichen Programmtext.

von Karl H. (kbuchegg)


Lesenswert?

Und Einrückungen würden deinem Code auch gut tun.

von Noname (Gast)


Lesenswert?

Interessant das sich manche Fehlerarten zeitlich zu konzentrieren 
scheinen. Das mit der falsch formulierten Bedingung in der For-Schleife 
hatten wir doch kürzlich erst.

Wenn ich noch einen Rat geben darf: Du spartst Dir Schreibarbeit (wenn 
es auch nur das ergänzen der Indizes ist) wenn Du initialisierungen von 
Arrays so machst:
1
uint8_t pwmdata[20] = {128, 150, 171, ectpp. };

von Vlad T. (vlad_tepesch)


Lesenswert?

Oh, da hette der Karl mal wieder die besseren Augen.
Ich mab mich so sehr auf die Register konzentiert, dass ich den 
offensichtlichsten Fehler übersehen habe

von Noname (Gast)


Lesenswert?

Uups. Zu langsam. :-)

von Vlad T. (vlad_tepesch)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und Einrückungen würden deinem Code auch gut tun.

gut, die vernichtet die Forensoftware, wenn man keine Code-Tags benutzt.

von Matthias L. (Gast)


Lesenswert?

oder du ersetzt die for-Schleife durch:
1
uint8_t i = 0;
2
3
while ( i != 10 )
4
{
5
  OCR0A = pwmdata[i++];
6
7
  _delay(500);
8
}

von Stephan H. (stiph5)


Lesenswert?

Das ist natürlich ein kleiner dummer Fehler. Das Problem ist, das ich 
aus dem Bascombereich komme und hier würde es heißen

>for i = 0 to i=10
>Next

Jetzt habe ich es auch gecheckt :D. Danke für eure Hilfe. Jetzt läuft 
es.
Und danke für die vielen anderen Ratschläge. Ich werde euch den Code 
Präsentieren wenn er fertig ist und funktioniert.

von Karl H. (kbuchegg)


Lesenswert?

Matthias Lipinsky schrieb:
> oder du ersetzt die for-Schleife durch:

Das ist gut. Lass uns die for-Schleife durch die equivalente while 
Schleife ersetzen, vielleicht erkennt der TO dann seinen Fehler

ALso
   for( i = 0; i == 10; i++ ) {
     ...
   }

ist gleichwertig zu

   i = 0;

   while( i == 10 ) {
     ...
     i++;
   }

und jetzt sieht man eigentlich sehr schön, warum diese Schleife eine 
Nicht-Schleife war und vom Optimizer komplett entfernt wurde. Wodurch 
dann in der Hauptschleife nix mehr übrig blieb und genau das hat man 
dann auch im Debugger gesehen.

von Stephan H. (stiph5)


Lesenswert?

So hier der Code, Funktioniert wunderbar ;) Danke noch mal für eure 
Hilfe!
1
///Sinusgenerator///////////////
2
///Hochmüller Stephan/////////
3
///AVR-Studio 4
4
///Beschaltung: RC-Glied an PB0
5
///             R=1k
6
///             C=680µ
7
/// RC-Glied je nach Ausgangsfrequenz um dimensionieren.
8
9
#include <avr/io.h>
10
#include <util/delay.h>
11
12
#define F_CPU 9600000 
13
#define F_sin 50  // Ausgangsfrequenz.
14
#define time  1000000/F_sin/36 
15
16
17
18
19
int main (void){
20
21
/////////////////// Timer im PWM- Mode mit F_CPU/256Hz////////
22
TCCR0A |= (1<<COM0A1)|(1<<WGM00)|(1<<WGM01); //Fast PWM-Mode 
23
TCCR0B |= (1<<CS00); //Vorteiler = 0
24
DDRB|=(1<<PB0); //PORTB0 = Ausgang
25
///////////////////////////////////////////////////////////////
26
27
// PWM-Sinuswerte //
28
uint8_t pwmdata[20]=
29
{
30
128,150,171,191,209,225,238,247,
31
253,255,105,84,63,46,33,17,8,2,0
32
};
33
////////////////////
34
35
36
37
while(1){
38
39
///////// Positive Halbwelle /////////////////////
40
for(uint8_t i = 0; i<9; i++){
41
OCR0A = pwmdata[i];
42
_delay_us(time);
43
}
44
45
for(uint8_t i =8; i>0; i--){
46
OCR0A = pwmdata[i];
47
_delay_us(time);
48
}
49
50
/////////////////////////////////////////////////
51
52
//////////// Negative Halbwelle /////////////////
53
54
for(uint8_t i = 10; i<18; i++){
55
OCR0A = pwmdata[i];
56
_delay_us(time);
57
}
58
59
for(uint8_t i =17; i>10; i--){
60
OCR0A = pwmdata[i];
61
_delay_us(time);
62
} 
63
64
////////////////////////////////////////////////////
65
66
}
67
68
69
return 0;
70
}

von Stephan H. (stiph5)


Angehängte Dateien:

Lesenswert?

Hier noch ein Foto ;)

von Matthias L. (Gast)


Lesenswert?

>Hier noch ein Foto ;)

Ziemlich dunkel das Bild. Du solltest die Helligkeit von Strahl etwas 
aufdrehen ;-)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Schade, das du delay hart verdrahtest. Mit einem Timer hätte man einen 
schönen variablen Frequenzgenerator gehabt.

von jb (Gast)


Lesenswert?

>Ziemlich dunkel das Bild. Du solltest die Helligkeit von Strahl etwas
>aufdrehen ;-)

Und jetzt am besten 2 Wochen in Urlaub und dann haste deinen Sinusstrahl 
für immer aufm Oszi ;)

Schon mal dein Oszibildschirm a bissel!

Gruß Jonas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.