Forum: Compiler & IDEs array ausgabe/ schleife probelm


von frank (Gast)


Lesenswert?

1
int main(void)
2
{
3
char characters[10] = {0b01011111, 0b00000110, 0b00111011, 0b00101111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01100111, 0b00100000};  
4
5
DDRD=0xff;            //segment
6
DDRB=0xff;            //fragment
7
8
PORTD=0x01;
9
10
int i=0;
11
while(1){
12
  PORTD<<=1;
13
  if(PORTD>=0x80) {PORTD=1; i=0;}
14
  PORTB=characters[i++];
15
  };
16
}

es geht mir konkret um die Zeile PORTB=characters[i++];

auf dem Display taucht nur Mist auf. trage ich statt i++ beliebige 
nummern ein (0-9) ist alles io.

von delay () (Gast)


Lesenswert?

frank schrieb:
> auf dem Display taucht nur Mist auf
Es ist schon spät und du bist zu langsam. ;-)

Du benötigst eine Verzögerung nach der Ausgabe, damit der Mensch es 
lesen kann.

von frank (Gast)


Lesenswert?

nein daran liegt es nicht. mit festen werten geht es ja.

das ganze läuft ja in einer endlosschleife. soll heißen erste ziffer 
immer 0 zweite immer 1... daher endet es in einem standbild. nur passt 
es einfach nicht.

und kp woran es liegt :/ (software seitig)

von delay () (Gast)


Lesenswert?

frank schrieb:
> mit festen werten geht es ja

poste mal den code dazu

von frank (Gast)


Lesenswert?

ersetze in obiger funktion i++ durch 0 bis 9
1
PORTB=characters[0];

von DirkB (Gast)


Lesenswert?

Du weist deinem Array characters, das 10 Elemente hat, 11 Elemente zu.

Wo verhinderst du, dass i > 9 wird?

von Helmut (Gast)


Lesenswert?

Hallo,
im Code gehst du davon aus dass du den Wert den du in PORTD 
reinschreibst auch wieder lesen kannst. Das ist aber bei einem 
Spezialregister (hier wohl zur Ausgabe auf einen Port) nicht unbedingt 
der Fall. Das hängt ganz davon ab wie die Hardware gebaut ist.

Deshalb meine Frage: Was passiert wenn du die Abfrage if(PORTD>=0x80) 
ersetzt durch if(i>=8)?

Viel Erfolg!

Helmut

von Rolf Magnus (Gast)


Lesenswert?

frank schrieb:
1
> char characters[10] = {0b01011111, 0b00000110, 0b00111011, 0b00101111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01100111, 0b00100000};

Hier initialisierst du ein Array der Größe 10 mit 11 Werten.

> while(1){
>   PORTD<<=1;
>   if(PORTD>=0x80) {PORTD=1; i=0;}
>   PORTB=characters[i++];
>   };
> }
>

Beim ersten Durchlauf wird hier PORTB nie geschrieben bei gesetztem 
unteren Bit von PORTD. Dafür wird bei allen weiteren Durchläufen PORTB 
nie geschrieben bei gesetztem oberen Bit von PORTD. Es bedeutet auch, 
daß immer nur die ersten 7 deiner 11 Array-Einträge überhaupt genutzt 
werden.

von DirkB (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Beim ersten Durchlauf wird hier PORTB nie geschrieben bei gesetztem
> unteren Bit von PORTD. Dafür wird bei allen weiteren Durchläufen PORTB
> nie geschrieben bei gesetztem oberen Bit von PORTD. Es bedeutet auch,
> daß immer nur die ersten 7 deiner 11 Array-Einträge überhaupt genutzt
> werden.

Das PORTB=characters[i++]; gehört nicht zum if.
Die Klammern/Einrückung sind sehr bescheiden.
1
int main(void)
2
{
3
  ...
4
  int i=0;
5
  while(1){
6
    PORTD<<=1;
7
    if(PORTD>=0x80) {
8
      PORTD=1; 
9
      i=0;
10
    }
11
    PORTB=characters[i++];
12
  };
13
}

von xfr (Gast)


Lesenswert?

Warum überhaupt so verschwurbelt? Man kann nur ahnen, was damit damit 
erreicht werden soll. Vermutlich ist so etwas gemeint:
1
int i = 0;
2
while (1) {
3
  if (i > 7) {
4
    i = 0;
5
  }
6
  PORTD = (1 << i);
7
  PORTB = characters[i];
8
  i++;
9
}

von delay () (Gast)


Lesenswert?

frank schrieb:
> ersetze in obiger funktion i++ durch 0 bis 9
> PORTB=characters[0];

Wie machst du das? Im Debugger? Dann hälst du die Ausgabe ja an und 
bekommst dein delay.

Bitte den code zeigen!

von Rolf Magnus (Gast)


Lesenswert?

DirkB schrieb:
> Das PORTB=characters[i++]; gehört nicht zum if.

Ja, aber das ändert an meiner Aussage doch nichts. Überleg einfach mal: 
Welchen Wert hat PORTD vor dem ersten Schleifendurchlauf. Welchen hat 
er, wenn zum ersten mal PORTB=charactersſ[i++] aufgerufen wird? Welchen 
Wert hat er direkt nachdem das if zugeschlagen hat? Und wenn bei PORTD 
durch die Schiebe-Operation das oberste Bit gesetzt wurde, welchen Wert 
hat es danach beim nächsten PORTB=...-Aufruf?

xfr schrieb:
> Warum überhaupt so verschwurbelt? Man kann nur ahnen, was damit damit
> erreicht werden soll. Vermutlich ist so etwas gemeint:
> int i = 0;
> while (1) {
>   if (i > 7) {
>     i = 0;
>   }
>   PORTD = (1 << i);

Den Registernamen nach zu urteilen handelt es sich um einen AVR. Da 
sollte man das Schieben um eine Variable vermeiden.

>   PORTB = characters[i];
>   i++;
> }

Generell finde ich das immer noch unschön. Wenn da was 8 mal getan 
werden soll, dann doch bitte eine eigene Schleife dafür und nicht den 
Zähler in die umgebende Schleife irgendwie mit reingewurschtelt. Mein 
Vorschlag:
1
while (1)
2
{
3
    PORTD = 1;
4
    for (uint_least8_t i = 0; i < 8; ++i)
5
    {
6
        PORTB = characers[i];
7
        PORTD <<= 1;
8
    }
9
}

von frank (Gast)


Lesenswert?

Hatte ein Brett vorm Kopf. Die Lösung war natürlich das delay.
Dadurch das es fehlte kam es zu Ghosting Effekten.
Durch die hohe Frequenz, war der Effekt so stark das man ihn vom 
gewollten Leuchten nicht unterscheiden konnte.

>im Code gehst du davon aus dass du den Wert den du in PORTD
>reinschreibst auch wieder lesen kannst. Das ist aber bei einem
>Spezialregister (hier wohl zur Ausgabe auf einen Port) nicht unbedingt
>der Fall. Das hängt ganz davon ab wie die Hardware gebaut ist.

geht afaik via assembler eigentlich nicht beim atmega8. C fixed das wohl 
beim assemblieren automatisch. Sieht etwas unsauber aus, aber naja.

von Karl H. (kbuchegg)


Lesenswert?

frank schrieb:

>>Spezialregister (hier wohl zur Ausgabe auf einen Port) nicht unbedingt
>>der Fall. Das hängt ganz davon ab wie die Hardware gebaut ist.
>
> geht afaik via assembler eigentlich nicht beim atmega8.

Technisch geht das grundsätzlich schon. Die entsprechenden Assembler 
Anweisungen existieren und werden auch ausgeführt.

> C fixed das wohl
> beim assemblieren automatisch. Sieht etwas unsauber aus, aber naja.

Nicht naja. Das ganze zurücklesen ist unnötig, wenn man das Programm 
anders aufbaut. Du kriegst für nicht benutztes SRAM von Atmel kein Geld 
zurück. Und so in Speichernot scheinst du nicht zu sein, dass du 
Ausgabeports als Zwischenspeicher benutzen musst.

von frank (Gast)


Lesenswert?

>Und so in Speichernot scheinst du nicht zu sein, dass du
>Ausgabeports als Zwischenspeicher benutzen musst.

wer den pfennig nicht ehrt...!

Spass bei Seite, hat das ganze den einen Nachteil?

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.