Forum: Mikrocontroller und Digitale Elektronik Portansteuerung


von René G. (gess12)


Lesenswert?

Hallo an Alle,

ich kämpfe hier mit meinem Halbwissen und ein paar Dingen die ich mir 
gar nicht erklären kann.

Ich habe einen Schrittmotor, dieser wird über eine Kombination von L297 
und L298 angesteuert. Dabei benötige ich vom µC nur drei Signale, 
Enable, Drehrichtung und Clockimpuls.
Der Schrittmotor läuft. Alelrdings habe ich ein paar unerklärliche 
Probleme bei der Portansteuerung für Enable und Drehrichtung.

Bevor ich den Sourcecode poste, einmal eine grundsätzliche Frage.

wenn ich schreibe.
PORTB |=(Richtung<<PB1) ; bedeutet das für mich, dass der Pin1 des 
PortsB auf eins gesetzt wird, die anderen bleiben so wie sie sind.
Oder sehe ich das falsch?

Was ist der Unterschied zu
PORTB =(Richtung<<PB1) ; // also ohne Or

Hier jetzt mal der Sourcecode mit dem Problem.
1
 void Schrittmotor ()
2
{
3
    lcd_clear();
4
      lcd_setcursor(2, 1 );
5
      lcd_string("Belichtungstest 1");
6
      lcd_setcursor(7, 3 );
7
      lcd_string(":   min");
8
9
    lcd_setcursor(6, 3 );
10
    lcd_data(M + 48);
11
    lcd_setcursor(8, 3 );
12
    lcd_data(S10 + 48 );
13
    lcd_setcursor(9, 3 );
14
    lcd_data(S +48);
15
16
  while(1)
17
   {
18
   if (M >=1)
19
    Richtung=links;
20
    else
21
    Richtung=rechts;       
22
    
23
    PORTB |=(Richtung<<PB1) ;            // Drehrichtung
24
      
25
    if (Schritte <= 1200)
26
     {
27
     PORTB =(1<<PB0) ;
28
     
29
     _delay_ms(0.020);              // SM Enable bevor Timer2 eingeschaltet wird
30
       TIMSK = (1<<6) | (1<<2);            // Timer2 einschalten solange Schritte kleiner 1200 ( 1200 = Anzahl Schritte)
31
     }              // Ende if
32
    else
33
     {
34
         TIMSK = 0x04;                    // Timer2 ausschalten wenn eingestellte Schritte erreicht sind.
35
       _delay_ms(0.020);              // Zeitschleife für Timer2 Enable ausschalten                   
36
     PORTB = (0<<PB0);              // SM Enable off kurz nach dem ausschalten des Timers2
37
     Schritte=1;                    // Zurücksetzen von Schritte
38
     Intervall=0;
39
     Start ();                      // Nach Bewegung des Schrittmotors zurück zu Start und den nächsten Intervall abwarten
40
     }              // Ende else
41
    }                // Ende while
42
  
43
}
44
45
46
ISR( TIMER2_OVF_vect )
47
48
{
49
  
50
  Schritte++;
51
  schritte++;
52
          
53
PORTB ^= (1<<PB2);
54
TIFR = (1<<6);
55
}

Fällt Jemanden etwas auf in der Programmierung was die Portanschaltung 
angeht.
Bei PB0 habe ich anstatt 5V nur 2,5V anliegen, bei der Drehrichtung 1,2V 
wenn auf High geschalten.

Über Hilfe wäre ich sehr Dankbar.

René

von Plov (Gast)


Lesenswert?

Was für ein µC und wo werden die Ports auf Ausgang geschaltet?

von Hein Mück (Gast)


Lesenswert?

Hi, ich habe deinen Quellcode nur so überflogen.

Mir ist aufgefallen, diese Konstruction ist doch etwas merkwürdig.
PORTB |=(Richtung<<PB1) ;
Wo ist rechts & links definiert?

Besser so:
PORTB |= (1 << 3); // Portleitung setzen
PORTB &= ~(1 << 3); // Portleitung löschen

von Lehrer (Gast)


Lesenswert?

René Geßner schrieb:
> wenn ich schreibe.
>
> PORTB |=(Richtung<<PB1) ; bedeutet das für mich, dass der Pin1 des
>
> PortsB auf eins gesetzt wird, die anderen bleiben so wie sie sind.
>
> Oder sehe ich das falsch?

Aber nur, wenn Richtung 1 ist - wenn Richtung Null ist, ändert sich gar 
nichts.

von Hein Mück (Gast)


Lesenswert?

Und natürlich musst du im DDRB die Ports die du als Ausgang verwenden 
willst setzen:

DDRB |= (1 << 7) | (1 << 5) | (1 << 3); // PB7, PB5, PB3 als Output

von Falk B. (falk)


Lesenswert?

@  René Geßner (gess12)

>PORTB |=(Richtung<<PB1) ; bedeutet das für mich, dass der Pin1 des
>PortsB auf eins gesetzt wird, die anderen bleiben so wie sie sind.
>Oder sehe ich das falsch?

Falsche Syntax. Eher so.
1
PORTB |=(1<<Richtung);

Dann stimmt deine Aussage, siehe Bitmanipulation.

>Was ist der Unterschied zu
>PORTB =(Richtung<<PB1) ; // also ohne Or

Das seht NUR das einzelen Bit, der Rest wird auf Null gesetz.

1
    if (M >=1)
2
    Richtung=links;
3
    else
4
    Richtung=rechts;       
5
    
6
    PORTB |=(Richtung<<PB1) ;            // Drehrichtung

Funktioniert nicht. Eher so.
1
    if (M >=1)
2
       PORTB |=(1<<PB1);  // links
3
    else
4
      PORTB &=~(1<<PB1);  // rechts

Denn du musst das Bit expizit setzen UND löschen, je nach Richtung. Dazu 
braucht man zwei verschiedene Logikoperationen, siehe 
Bitmanipulation.

Das Konzept von deinem Programm ist auch konfus, das mit dem Timer macht 
man anders.

von René G. (gess12)


Lesenswert?

Erst einmal vielen Dank für die reichlichen Antworten.

Nun versuche ich mal die offenen Fragen zu beantworten.

Was für ein µC und wo werden die Ports auf Ausgang geschaltet?

Es handelt sich um einen ATMega32, DDRB wird in der Main auf Ausgang 
gesetzt.
DDRB = 0xff;

links und rechts sind natürlich definiert

#define links    0
#define rechts    1

Aus euren Antworten kann ich entnehmen das ich nicht so falsch lag. Wir 
haben das leider etwas anders gelehrt bekommen, auf die altmodische Art.
z.B. PORTB = PORTB | 0x01


Jetzt habe ich allerdings ein anderes Problem.
Nachdem ich jetzt die entsprechenden Ausgänge für Enable und 
Drehrichtung Verodert habe, funktioniert das. Dafür verschluckt sich 
jetzt mein Schrittmotor während er sich dreht.

PORTB ^= (1<<PB2); Das ist ja XOR am Pin2 am PORTB
Bezieht sich das jetzt nur auf den PIN2 oder hat das auch Auswirkung auf 
die anderen PINs wie bei PORTB = (1<<PB2).

Wenn ich z.B. das Enable- und Richtunssignal auf einen anderen PORT lege
gibt es beim Schrittmotor überhaupt keine Probleme, zumindest 
verschluckt er sich nicht so massiv.

Kann mir da Jemand helfen?

Vielen Dank
René

von Karl H. (kbuchegg)


Lesenswert?

René Geßner schrieb:

> Aus euren Antworten kann ich entnehmen das ich nicht so falsch lag. Wir
> haben das leider etwas anders gelehrt bekommen, auf die altmodische Art.
> z.B. PORTB = PORTB | 0x01

Na dann.

    xyz |= 0x01;

ist identisch zu

   xyz = xyz | 0x01;


oder allgemeiner gilt für alle Zuweisungsoperatoren, die es auch mit 
einem Prefix gibt


   xyz op= expression;

ist identisch zu

   xyz = (xyz) op (expression)

anstatt also den Ausdruck links vom = auf der rechten Seite noch mal 
hinzuschreiben, genügt es dem Compiler dies auzutragen, indem man die 
Zuweisung modifiziert.

> Jetzt habe ich allerdings ein anderes Problem.
> Nachdem ich jetzt die entsprechenden Ausgänge für Enable und
> Drehrichtung Verodert habe, funktioniert das. Dafür verschluckt sich
> jetzt mein Schrittmotor während er sich dreht.
>
> PORTB ^= (1<<PB2); Das ist ja XOR am Pin2 am PORTB
> Bezieht sich das jetzt nur auf den PIN2 oder hat das auch Auswirkung auf
> die anderen PINs wie bei PORTB = (1<<PB2).

Das bezieht sich nur auf den einen Pin.
Alle Bit-Operationen arbeiten auf die 8-Bit eines Wertes einzeln!
Drum heissen sie auch Bitoperationen.


> Kann mir da Jemand helfen?
Hmm. Meine Glaskugel ist schon im Wochenende!
Wenn du allerdings deinen Code posten würdest, dann würde ich keine 
Glaskugel brauchen. Alternativ kannst du auch deine Hand auf den Scanner 
legen, dann lese ich dir aus der Hand. Ist aber nicht ganz so 
zuverlässig wie eine Glaskugel.

von Karl H. (kbuchegg)


Lesenswert?

Allerdings:

Wenn das im wesentlichen das Programm von da oben ist ... das wird so 
nix.
Da sind ein paar ordentliche Denkfehler drinnen. So baut man kein 
Programm auf. Die Endlosschleife hat da drinn schon mal überhaupt nichts 
verloren und der Aufruf von Start() muss da auch raus.
Die Funktion ruft kein Start() auf. Die Funktion macht ihr Sache und 
wenn sie fertig ist, dann returniert sie zum Aufrufer.
Und den Timere ... lass ihn in Ruhe einfach durchlaufen, ansatt ihn 
dauern ein/aus zuschalten. Das ist ein Irrtum wenn man meint, man muss 
Timer laufend ein/ausschalten. Meistens handelt man sich da mehr Fehler 
ein, als wie wenn man in der ISR einfach prüft ob es etwas zu tun gibt 
und falls es nichts zu tun gibt dann einfach ... nichts tut und den 
Timer in Ruhe weiter zählen lässt.


Wenn dein Programm eine bestimmte Anzahl Schritte mittels Timer erzeugen 
soll, dann geht das so
1
volatile uint16_t Schritte;
2
3
void Schrittmotor()
4
{
5
  uint16_t temp;
6
7
  // Richtung einstellem
8
  if (M >=1)
9
    PORTB |= ( 1<<PB1 );
10
  else
11
    PORTB &= ~( 1<<PB1 );
12
13
  // Anzahl Schritte setzen
14
  cli();
15
  Schritte = 1200 * 2;
16
  sei();
17
18
  // warten bis der Timer die entsprechenden Schritte abgearbeitet hat
19
  do {
20
    cli();
21
    temp = Schritte;
22
    sei();
23
  } while( temp > 0 );
24
}
25
26
ISR( ... )
27
{
28
  if( Schritte > 0 ) {
29
    Schritte--;
30
    PORTB ^= (1<<PB2);
31
  }
32
}

fertig.
Da muss kein Timer gestartet oder gestoppt werden.
Ob du in der Funktion aktiv darauf wartest, bis die vorgeschriebenen 
Schritte abgearbeitet sind, oder ob du in der Zwischenzeit was anderes 
machst, ist dann dir überlassen. Fix ist: solange die Variable Schritte 
einen Wert größer als 0 enthält, arbeitet der Timer noch die Schritte 
ab. Daran kann man erkennen, ob die letzte Bewegung bereits vollständig 
abgearbeitet wurde oder nicht.

von René G. (gess12)


Lesenswert?

@kbuchegg

Danke für deine Antwort.
Der Sourcecode ist der von weiter oben, dieser ist jetzt nur abgeändert 
in dem ich das OR noch eingefügt habe.

Wenn ich perfekt programmieren würde, würde ich bestimmt nicht 
nachfragen müssen.
Und das ich nicht perfekt programmiere weiß ich. Ich bin nach wie vor 
Anfänger, aber ich lerne. Deinen Hinweis alles in Funktionen zu packen 
habe ich konsequent umgesetzt und habe damit einigermaßen Struktur rein 
bekommen.

Wenn sich das XOR nur auf den PIN2 auswirkt, was ist dann falsch am 
Programm?
Der Motor dreht sich nicht korrekt wenn die beiden Signale Enable und 
Drehrichtung mit auf dem selben PORT liegen. Also muss das Programm wohl 
die Störung verursachen.
Das selbe Programm, nur Enable und Richtung auf PORTC gelegt, 
funktioniert.

Was mache ich also falsch??

Ich springe in die Schrittmotorfunktion, wenn M<1 ist, ist Richtung auf 
1
und der Timer2 wird eingeschaltet, durch die ISR wird Schritte 
hochgezählt und in der ISR wird der Impuls auf PORTB2 gegeben.
Was läuft falsch???
1
void Schrittmotor ()
2
{
3
    lcd_clear();
4
      lcd_setcursor(2, 1 );
5
      lcd_string("Belichtungstest 1");
6
      lcd_setcursor(7, 3 );
7
      lcd_string(":   min");
8
9
    lcd_setcursor(6, 3 );
10
    lcd_data(M + 48);
11
    lcd_setcursor(8, 3 );
12
    lcd_data(S10 + 48 );
13
    lcd_setcursor(9, 3 );
14
    lcd_data(S +48);
15
16
  while(1)
17
   {
18
   if (M >=1)
19
    Richtung=links;
20
    else
21
    Richtung=rechts;       
22
    
23
    PORTC |=(Richtung<<1) ;            // Drehrichtung
24
      
25
    if (Schritte <= 1200)
26
     {
27
     PORTC |=(1<<0) ;
28
     
29
     _delay_ms(0.020);              // SM Enable bevor Timer2 eingeschaltet wird
30
       TIMSK = (1<<6) | (1<<2);            // Timer2 einschalten solange Schritte kleiner 1200 ( 1200 = Anzahl Schritte)
31
     }              // Ende if
32
    else
33
     {
34
         TIMSK = 0x04;                    // Timer2 ausschalten wenn eingestellte Schritte erreicht sind.
35
       _delay_ms(0.020);              // Zeitschleife für Timer2 Enable ausschalten                   
36
     PORTC &= ~(1<<0);              // SM Enable off kurz nach dem ausschalten des Timers2
37
     Schritte=1;                    // Zurücksetzen von Schritte
38
     Intervall=0;
39
     Start ();                      // Nach Bewegung des Schrittmotors zurück zu Start und den nächsten Intervall abwarten
40
     }              // Ende else
41
    }                // Ende while
42
  
43
}
44
45
ISR( TIMER2_OVF_vect )
46
47
{
48
  
49
  Schritte++;
50
  schritte++;    // nur Hilfsvariable zum zählen der ISR-Aufrufe
51
52
  PORTB ^= (1<<PB2);
53
54
  TIFR = (1<<6);
55
}

von Karl H. (kbuchegg)


Lesenswert?

René Geßner schrieb:


> Was mache ich also falsch??


Zum Beispiel das hier

>     PORTC |=(Richtung<<1) ;            // Drehrichtung
>

>      Schritte=1;                    // Zurücksetzen von Schritte
>      Intervall=0;

Zum Beispiel das hier
>  while(1)
>   {

Zum Beispiel das hier

>      Start ();                      // Nach Bewegung des Schrittmotors
> zurück zu Start und den nächsten Intervall abwarten

Du denkst noch zu sehr in Form von
mach das, dann mach das und dann spring irgendwo anders hin!

Das ist die falsche Ansicht!
Das main() gibt einen "Auftrag" an die Funktion, etwas zu machen. Und 
wenn die Funktion damit fertig ist, dann kehrt sie auf ganz normalem Weg 
zurück und springt nicht irgendwo hin. main() entscheidet wie es dann 
weiter geht und nicht die Funktion!

Ich hab dir doch ein Beispiel geschrieben. Studier es und überleg dir, 
wo da jetzt der wesentliche Unterschied liegt. Es ist ein 
konzeptioneller Unterschied und nichts was man an 2 Anweisungen fest 
machen kann. Der ganze konzeptionelle Aufbau ist anders!

von René G. (gess12)


Lesenswert?

@ kbuchegg

den zweiten Teil deiner Antwort hatte ich leider nicht gesehen.
Deswegen meine Antwort dazu jetzt.

Ich benutze den Timer um eine Frequenz zu erzeugen, die Notwendig ist um 
den Schrittmotor drehen zu lassen.
1
volatile uint16_t Schritte;
2
3
void Schrittmotor()
4
{
5
  uint16_t temp;
6
7
  // Richtung einstellem
8
  if (M >=1)
9
    PORTB |= ( 1<<PB1 );
10
  else
11
    PORTB &= ~( 1<<PB1 );
12
13
  // Anzahl Schritte setzen
14
  cli();
15
  Schritte = 1200 * 2;
16
  sei();

Diesen Teil verstehe und bedarf keiner Erklärung.
Dafür aber für den folgenden Teil.
1
  // warten bis der Timer die entsprechenden Schritte abgearbeitet hat
2
  do {
3
    cli();
4
    temp = Schritte;
5
    sei();
6
  } while( temp > 0 );
7
}

Ich schalte den Timer ein und aus, weil im Hintergrund noch ein zweiter 
Timer läuft der für die Zeit verantwortlich ist. Mit cli() würde ich den 
doch dann auch auschalten bzw. Interrups unterbinden? Oder???

René

von Karl H. (kbuchegg)


Lesenswert?

René Geßner schrieb:


> Diesen Teil verstehe und bedarf keiner Erklärung.
> Dafür aber für den folgenden Teil.
>
>
1
> 
2
>   // warten bis der Timer die entsprechenden Schritte abgearbeitet hat
3
>   do {
4
>     cli();
5
>     temp = Schritte;
6
>     sei();
7
>   } while( temp > 0 );
8
> }
9
>
>
> Ich schalte den Timer ein und aus, weil im Hintergrund noch ein zweiter
> Timer läuft der für die Zeit verantwortlich ist.

Und?
Der läuft ja weiter.

> Mit cli() würde ich den
> doch dann auch auschalten bzw. Interrups unterbinden? Oder???

Nach dem Auslesen der Variable 'Schritte' folgt ja sofort wieder der 
zugehörige sei(). Die Interrupts sind genau so lange gesperrt, wie es 
dauert 2 Bytes aus dem Speicher zu lesen. Was denkst du was das für den 
Rest des Programms bedeutet, wenn ein Interrupt mal um 0.1µs später 
kommt als er kommen könnte?

von René G. (gess12)


Lesenswert?

Die Funktionen sind sozusagen verschachtelt.
Das Programm ist so umfangreich geworden das ich leider nicht alles 
posten kann.
Ich springe in die Start() weil dort eine Zeit abläuft die auf einem 
Display ausgegeben wird und nach 30 Sekunden wird der Schrittmotor um 
eine bestimmte Anzahl Schritte bewegt und das geht so 6min lang. Von der 
Start() springe ich sozusagen aller 30 Sekunden in die Schrittmotor() 
und von da wieder zurück zur Start bis zum Ende.

René

von Karl H. (kbuchegg)


Lesenswert?

René Geßner schrieb:
> Die Funktionen sind sozusagen verschachtelt.

OK.
Dann bin ich raus.

Du wirst dann schon sehen, was alles passiert, wenn dir der Stack 
überläuft.
Wer nicht hören will, muss es eben auf die harte Tour lernen.

von René G. (gess12)


Lesenswert?

@kbuchegg

Ich danke dir für deine Hilfe. Glaube mir, ich versuche deine 
Gedankengänge zu verstehen und auch umzusetzen. Und unbelehrbar bin ich 
nicht. Unwissend mit wenig Erfahrung trifft es besser.
Und genau aus diesem Grund habe ich mich in diesem Forum angemeldet, um 
zu lernen von Leuten die wesentlich mehr Wissen und Erfahrung haben als 
ich.
Du urteilst ziemlich schnell. Aber ich kann das verstehen.

Danke für deine Mühen.
Ich werde euch nicht mehr belästigen. Wenn hier nur Profis erwünscht 
sind, dann bin ich hier falsch.

René

von Karl H. (kbuchegg)


Lesenswert?

René Geßner schrieb:


> Ich werde euch nicht mehr belästigen. Wenn hier nur Profis erwünscht
> sind, dann bin ich hier falsch.

Keineswegs.
Aber was soll ich mit wem, der sowieso keinen Rat annimmt und lieber 
seinen Stiefel weiterprogrammiert, weil er nicht wahrhaben will, dass 
man klein anfangen muss. Die Zeit kann ich mir auch sparen.

von René G. (gess12)


Lesenswert?

Wie ich schon sagte, ich programmiere so wie es mein Wissen zulässt.
Wenn man aber einem Nichtschwimmer, der sich gerade mal über Wasser 
halten kann, vom Beckenrand aus erzählt wie geschwommen werden muss um 
bei Olympia dabei zu sein und er dann als unbelehrbar erklärt wird nur 
weil er es nicht gleich so umsetzen kann.
Ich halte das etwas anders, ich bin ein gelernter Teamplayer, (ich war 
mal Leistungssportler in einer Mannschaftssportart), und als solcher 
stand und stehe ich noch heute denen bei die Probleme haben. Weil leider 
eine Schwalbe nun mal keinen Sommer macht.
Und in diesem Fall bin ich der Nichtschwimmer und Derjenige der die 
Probleme hat. Aber ich werde noch schwimmen lernen im übertragenen 
Sinne.
René

von Karl H. (kbuchegg)


Lesenswert?

> Wenn man aber einem Nichtschwimmer, der sich gerade mal über
> Wasser halten kann, vom Beckenrand aus erzählt wie geschwommen
> werden muss um bei Olympia dabei zu sein und er dann als
> unbelehrbar erklärt wird nur
> weil er es nicht gleich so umsetzen kann.

Du verwechselst da was.

Du magst der Nichtschwimmer sein.
Aber nicht ich bin es, der dir vom Beckenrand aus Anweisungen zuruft, 
sondern du bist es, der sich nach seinem ersten 5 Meter im Hunderlstil 
einbildet, er könne zu Olympia fahren und fragt, was er dazu tun müsse.

Du hast Halbwissen?
Tu was dagegen!
Aber nicht in der Form, dass du dir ein Projekt aufreisst, dass 10 
Nummern zu groß für dich ist.

Sorry. Da mussten wir ALLE ausnahmslos durch. Jeder von uns hat klein 
angefangen und nicht mehr vom Kuchen abgebissen als er schlucken konnte. 
Und ja - das dauert seine Zeit. 2, 3 Jahre sind da gar nichts.

Aber es ist ok.
Wer radfahren lernen will, muss auch runterfallen.
Die selbst gemachte Erkenntnis 'so gehts nicht' ist oft mehr wert als 
eine vorgekaute Lösung.

von René G. (gess12)


Lesenswert?

Der Mensch wächst mit seinen Aufgaben.
Mein Projekt ist mit Sicherheit nicht zu hoch angesiedelt.
Und wie ich dir schon einmal geschrieben habe, ich bin keine 18 mehr. 
Ich weiß meine Fähigkeiten ganz gut einzuschätzen und auch nicht zu 
überschätzen.
Ach, übrigens. Olympia war wirklich mal mein Ziel. Und ich bin nicht 
daran zerbrochen das es nicht geklappt hat.

Wenn ich mal noch eine Frage los werden darf. Wie lange programmierst du 
schon µC?

René

von Hmm (Gast)


Lesenswert?

>Der Mensch wächst mit seinen Aufgaben.
Aber Du nicht. Wenn man Dir die Richtung zeigt in der Du wachsen 
solltest, dann bestehst Du darauf klein zu sein.

Das ist der ganze Tenor, deiner letzten Beiträge.

Mach es einfach und diskutiere hier nicht 'rum.
Wenn Du vernünftig und bescheiden nachfragst, warum Du das so machen 
sollst und nicht anders wird man Dir ebenso antworten.
Aber diese Rumgesülze, das Du es nicht besser kannst, ist nichts weiter 
als das versteckte: Ich will nicht anders.

>Und wie ich dir schon einmal geschrieben habe, ich bin keine 18 mehr.
Was hat das für eine Relevanz?

>Ich weiß meine Fähigkeiten ganz gut einzuschätzen und auch nicht zu
>überschätzen.

Im Gartenbau, oder in welchem Aufgabengebiet?

>Wenn ich mal noch eine Frage los werden darf. Wie lange programmierst du
>schon µC?

Karl Heinz so gefühlte hundertmal solange wie Du! Da darfst Du ruhig 
d'rauf wetten.

Mann, ich krieg echt 'nen Anfall, wenn ich lese wie Leute wie Karl Heinz 
sich hier von irgendwelchen Möchtegerns ans Bein pinkeln lassen müssen.

Das ist nicht sein Problem, sondern DEINES! Kapier das endlich Du 
Sülzkopf!

von René G. (gess12)


Lesenswert?

@Hmm
Schreib wenigsten deinen Namen drunter, wenn du schon mit Beleidigungen 
um dich wirfst. So aus der Anonymität ist das recht einfach. Und wenn du 
vom Sachverhalt keine Ahnung hast, sei einfach still. Ich möchte hier 
niemanden ans Bein pissen, dem Karl Heinz schon gar nicht. Ich weiß wie 
Respekt geschrieben wird und bringe diesen auch anderen Menschen 
entgegen. Du ja wohl nicht.

René

von Hmm (Gast)


Lesenswert?

>Ich weiß wie Respekt geschrieben wird...

Und Du meinst, wer es schreiben kann, versteht auch den Sinn? Du 
respektierst ja nicht mal Dich selbst. Heulst hier herum wie so ein 
kleines Kind.

von René G. (gess12)


Lesenswert?

Zum Thema keinen Beitrag aber beleidigen.
Ich frage mich wer hier Kuchen gesagt hat, das sich jetzt auf einmal die 
Krümel melden.
Übrigens du hast einen Teil bei deinem Zitat vergessen.
>und bringe diesen auch anderen Menschen entgegen.

Wenn man schon zitiert sollte man es richtig tun und nicht nur heraus 
picken was einem passt.
Und damit sollte Schluss sein mit dieser Diskusion, es bringt Niemanden 
hier weiter.
René

von Hmm (Gast)


Lesenswert?

Na dann: Gute Nacht.

von Karl H. (kbuchegg)


Lesenswert?

>>Wenn ich mal noch eine Frage los werden darf. Wie lange programmierst du
>>schon µC?
>
> Karl Heinz so gefühlte hundertmal solange wie Du! Da darfst Du ruhig
> d'rauf wetten.

Weis ich nicht.

Meine ersten Programme (damals noch auf dem Papier, weil ich keinen 
Computer zur Verfügung hatte) sind 1980 entstanden. Tatsächlich laufen 
lassen konnte ich die ersten Programme 1981. In die 
Industrieprogrammierung bin ich dann so um 1988 gekommen. Man könnte 
also durchaus sagen: 7 Jahre Lehrzeit, wenn man so will. Obwohl sich das 
jetzt dramatischer anhört als es war :-) AUf jeden Fall war die Zeit 
damals nicht mit den Möglichkeiten vergleichbar, die man heute hat.

So um 2002 rum hatte ich das erste mal einen AVR in den Fingern.

Aber was hat das damit zu tun, dass dein Programmaufbau nicht stimmt? 
Ein Programmaufbau, den man in mindestens 20 kleineren Programmen vorher 
trainiert hat? Funktionen sind keine Hexerei. Und wenn man da auf die 
übliche Weise in die Sache reinwächst, dann kommt man gar nicht auf die 
Idee ein rekursives System nach dem Muster
1
void foo()
2
{
3
  ...
4
  bar();
5
}
6
7
void bar()
8
{
9
  ...
10
  foo();
11
}
aufzubauen.
Solche (ähnliche) Konstruktionen gibt es zwar in der Informatik, das 
nennt sich indirekt rekursive Funktionen, aber die sind mit Sicherheit 
nichts für einen Anfänger. Die kann er nicht beherrschen.

Dein Problem sitzt an einer anderen Stelle. Du setzt 'Funktion aufrufen' 
mit 'Mach dort weiter' gleich. Du ignorierst dabei, dass eine Funktion 
auch wieder zurückkommen muss. Denn jeder Funktionsaufruf speichert sich 
die Stelle von wo er aufgerufen wurde. Bei entsprechend vielen 
Funktionsaufrufen, die nie mit einem Return abgeschlossen wurden, kommt 
es dann eben dazu, dass diese gespeicherte Rückkehrinformation alles 
andere 'überwuchert'. Und dann machts Peng.

Aber: All das steht in jedem noch so grindigem C-Buch drinnen. Das ist 
nichts was man dir hier im Forum erklären muss bzw. müssen sollte. Und 
wenn man dem Pfad eines Lehrbuchs folgt und seine Übungen dazu macht, 
dann stellt sich diese Problematik das erste mal genau dann, wenn es um 
rekursive Funktionen geht. Und nicht früher. Rekursive Funktionen würde 
ich aber schon in den Bereich 'fortgeschrittener Programmierer' 
einstufen. Das ist nichts worüber ein Neuling sich in den ersten 2 
Jahren den Kopf zerbrechen muss oder soll.

> Mein Projekt ist mit Sicherheit nicht zu hoch angesiedelt.
Doch, das ist es.
Deine Probleme in deinem Programm stammen nicht daher, dass irgendein 
Detail nicht stimmt oder dass du irgendwo einen dummen Fehler gemacht 
hast. Deine Probleme (die du wahrscheinlich noch gar nicht bemeerkt 
hast) stammen unter anderem daher, dass der ganze Unterbau, der ganze 
Aufbau nicht stimmt. Das Problem beim schiefen Turm von Pisa ist nicht, 
dass ganz oben ein paar Ziegeln schief eingesetzt wurden. Das Problem 
beim schiefen Turm beginnt unten, im Fundament.

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.