Forum: Mikrocontroller und Digitale Elektronik AVR unverständliche for Schleife


von Hue \. (hue)


Angehängte Dateien:

Lesenswert?

Hallo,

im Anhang habe ich ein C Programm für den AVR ATmega8.

Ich möchte in dem main() Programm eine for- Schleife verwenden, die ein 
mehrdimensionalen Vektor durchläuft und dessen Werte als Bitmuster auf 
den PortC und PortD ausgibt.

In der Prozedur dimLED ist eine Zählschleife eingebaut, die eine 
Zeitverzögerung bewirkt.

Folgendes Problem:

Wenn ich ohne for Schleife die Prozedur aufrufe kommen leuchten nur die 
ausgewählten LEDs.
Bei der Verwendung der for Schleife, die eigentlich den Vektor 
durchlaufen soll und dann die Bitmuster ausgeben soll, leuchten auf 
einmal ALLE LEDs.

Was kann ich da unternehmen?

MfG

HUE

von (prx) A. K. (prx)


Lesenswert?

Was passiert bei einem µC, wenn main beendet wird?

Leuchten die LEDs bei low oder bei high?

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Wenn die Schleife fertig ist schaltest Du die Ports auf $00.
Wenn die Ausgänge act L sind (dh LEDs nach +) werden sie leuchten.

von Hue \. (hue)


Lesenswert?

Hallo,

die LEDs leuchten bei der Ausgabe von 0xff auf den PortD. Und ebenso auf 
den PortC.

Das Problem liegt aber an der for Schleife.

Wenn diese weggelassen wird, dann habe ich das Bitmuster für die 
Leuchtdauer. Wie gewünscht!

Will ich aber die 15 Werte im Vektor mit der for Schleife durchlaufen, 
dann SPINNEN die LED.

Ich habe den Verdacht, dass die Verzögerung in dimmLED nicht mehr 
funktioniert.

????

HUE

von Oliver J. (skriptkiddy)


Lesenswert?

A. K. schrieb:
> Was passiert bei einem µC, wenn main beendet wird?
Der avr-gcc sorgt standardmäßig dafür, dass ein AVR dann in einer 
Endlosschleife hängen bleibt.

Edit: Also unterm Strich passiert im oben geposteten Code gar nichts 
mehr.

Gruß Oliver

von Micha (Gast)


Lesenswert?

Hue \a schrieb:

> Bei der Verwendung der for Schleife, die eigentlich den Vektor
> durchlaufen soll und dann die Bitmuster ausgeben soll, leuchten auf
> einmal ALLE LEDs.

Scheinbar leuchten alle LEDs. Ist ja auch richtig so....

>
> Was kann ich da unternehmen?

Augen upgraden auf eine Zeitauflösung von 2ms, dann sollte das klappen 
:-)

Änder doch mal die Zeile
1
_delay_us( 2 );

auf
1
_delay_ms( 2 );

und berichte uns, was passiert :-)

von Karl H. (kbuchegg)


Lesenswert?

Hue \a schrieb:

> Ich habe den Verdacht, dass die Verzögerung in dimmLED nicht mehr
> funktioniert.

Das kann gut sein.

Rechne dir doch mal aus, in welchem Tempo das alles abgearbeitet wird. 
(wenn deine Zeiten klappen)

Ein _delay_us mit einem Wert von 2 innerhalb der Schleife, so wie du das 
hast, ist nicht sehr sinnvoll bei einer Taktfrequenz von 1Mhz.

Das us steht für Mykro-Sekunden, also Millionstel Sekunden. Man kann es 
auch so sagen: Bei 1Mhz Taktfrequnz ist eine Verzögerung von 1µs genau 1 
Takt.
Deine ganze Schleifensteuerung drummherum braucht ein Vielfaches davon!

von Sam .. (sam1994)


Lesenswert?

1
    PORTC = 0x00;
2
    PORTD = 0x00;
3
    wait( pause );
Welchen Sinn hat es die Leds 1ms auszuschalten, um sie dann 2µs leuchten 
zu lassen.

PS:
Die Wait geht ohne Hilfsvariable:
1
void wait ( int i )
2
{
3
  while ( i-- )
4
    _delay_us( 2 );
5
}

von Hue \. (hue)


Lesenswert?

Hallo,

ich scheine das Problem gefunden zu haben: die Laufvariable der for 
Schleife kann nicht als Index im Vektor benutzt werden. Die Ergebnisse 
kommen irgendwo her und werden ausgegeben.

Wie kann ich den Vektor noch benutzen, um die ein sequenziellen 
Zugreifen auf dessen Werte zu realisieren?

MfG

HUE

von Karl H. (kbuchegg)


Lesenswert?

Hue \a schrieb:
> Hallo,
>
> ich scheine das Problem gefunden zu haben: die Laufvariable der for
> Schleife kann nicht als Index im Vektor benutzt werden.

Blödsinn

von Joachim D. (Firma: JDCC) (scheppertreiber)


Lesenswert?

Schaltbild wäre nicht schlecht.

von Matthias L. (Gast)


Lesenswert?

Machs doch nicht so kompliziert.

1
uint8_t  PGM_STAR_C [] PROGMEM = { 0x0f, 0x0e, 0x0d, 0x0c, 
2
                                   0x0b, 0x0a, 0x09, 0x08, 
3
                                   0x07, 0x06, 0x05, 0x04, 
4
                                   0x03, 0x02, 0x01 };
5
6
uint8_t  PGM_STAR_D [] PROGMEM = { 0x23, 0xd4, 0xa5, 0xef, 
7
                                   0xbc, 0xf0, 0xe3, 0x1d, 
8
                                   0xdf, 0x3a, 0xb2, 0x0d, 
9
                                   0xf1, 0xd2, 0xdd };
10
11
12
void main ( void )
13
{
14
  //-- Hilfsvariablen ---------------------
15
  uint8_t  u8Idx;
16
  uint8_t  u8Max = (uint8_t) (   sizeof(PGM_STAR_D   )
17
                               / sizeof(PGM_STAR_D[0])  );
18
19
  //-- Port auf Ausgang -------------------
20
  DDRC = 0xFF;
21
  DDRD = 0xFF;
22
23
  //-- Schleife ---------------------------
24
  while (1)
25
  {
26
    u8Idx = 0;
27
    while ( u8Idx != u8Max )
28
    {
29
      PORTC = pgm_read_byte ( PGM_STAR_C[u8Idx] );
30
      PORTD = pgm_read_byte ( PGM_STAR_D[u8Idx] );
31
32
      delay_ms (500);
33
34
      u8Idx++;
35
    }
36
37
  }
38
}

von Karl H. (kbuchegg)


Lesenswert?

Deine ganze Dimmfunktion ist nicht koscher mit dem Timing.

Probier mal diese vereinfachte Version.
1
void dimmLED ( char c, char d, int long counterMax )
2
{
3
  PORTC = c;
4
  PORTD = d;
5
  _delay_ms( 500 );
6
}
jedes deiner Einzel-Muster wird 1/2 Sekunde lang angezeigt. Und dann
überprüf mal, ob deine LED wirklich so eingeschaltet werden, wie du dir
das vorstellst. Wenn deine LED wirklich bei einem 1-Bit eingeschaltet 
sind, dann dürfen die höchstens glimmen. Von Brennen kann bei einem 
Tastverhältnis von 500 zu 1 keine Rede mehr sein.

von klugscheissender Erbsenzähler (Gast)


Lesenswert?

Samuel K. schrieb:
> Die Wait geht ohne Hilfsvariable:void wait ( int i )
> {
>   while ( i-- )
>     _delay_us( 2 );
> }

Ne Hilfsvariable hats trotzdem, nämlich aufm Stack: call by value

von Hue \. (hue)


Lesenswert?

Hallo,

folgender Aufruf macht das von mir gewünschte:

dimmLED( starsOn[0][0], starsOn[1][0], cycleDuration );
dimmLED( starsOn[0][1], starsOn[1][1], cycleDuration );

Die Umschaltung erfolgt ordnungsgemäss und auch die Leuchtdauer von ca. 
1 Sekunde ist OK.

Folgende Anweisung ergibt Blödsinn:

for ( i =0; i < 2; i++)
{
   dimmLED( starsOn[0][i], starsOn[1][i], cycleDuration );
}

Was ist denn da los?

von Matthias L. (Gast)


Lesenswert?

>Folgende Anweisung ergibt Blödsinn:

Kannst du mal dazu den AssemblerCode anhängen.
Also die *.lss Datei.

Vielleicht sieht man da, was schief geht.

von Hue \. (hue)


Angehängte Dateien:

Lesenswert?

Hallo,

jetzt gehts. Danke für den heissen Tipp Lippi.


Gute Nacht.


HUE

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

klugscheissender Erbsenzähler schrieb:
> Samuel K. schrieb:
>> Die Wait geht ohne Hilfsvariable:void wait ( int i )
>> {
>>   while ( i-- )
>>     _delay_us( 2 );
>> }
>
> Ne Hilfsvariable hats trotzdem, nämlich aufm Stack: call by value

Und was hat call-by-value mit Stack zu tun?
Gemäß ABI wird i nicht auf dem Stapel übergeben.

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.