AVR unverständliche for Schleife

OP #2642491
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
Angehängte Dateien:
OP
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
Gast
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 :-)
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!
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
}
OP
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
Gast
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
}
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.
OP
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?
Gast
>Folgende Anweisung ergibt Blödsinn:

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

Vielleicht sieht man da, was schief geht.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.