array ausgabe/ schleife probelm

Gast #2901108
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.
Gast #2901130
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)
Gast #2901207
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
Gast #2901231
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.
Gast #2901266
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
}
Gast #2901303
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
}
Gast #2902060
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
}
Gast #2902504
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.
#2902572
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren