ATMEGA8 eingeschaltete LED Zählen

Gast #3799306
Lesenswert?

1
if(PORTC & (BIT_1)){
2
   if( count <= 6 )
3
   count++;
4
   }else{
5
   if( count>8  )
6
   count--; }
7
 if(PORTB & (BIT_2)){
8
  if( count <= 6 )
9
    count++;
10
    }else{
11
    if( count>8  )
12
    count--; }
13
 if(PORTB & (BIT_3)){
14
   if( count <= 6 )
15
   count++;
16
   }else{
17
   if( count>8  )
18
   count--; }
19
 if(PORTC & (BIT_4)){
20
   if( count <= 6 )
21
   count++;
22
   }else{
23
   if( count>8  )
24
   count--; }
25
if(PORTC & (BIT_5)){
26
   if( count <= 6 )
27
   count++;
28
   }else{
29
   if( count>8  )
30
   count--;}
31
 if(PORTC & (BIT_6)){
32
   if( count <= 6 )
33
   count++;
34
   }else{
35
   if( count>8 )
36
   count--;}
37
 if(PORTC & (BIT_7)){
38
   if( count <= 6 )
39
   count++;
40
   }else{
41
   if( count>8 )
42
   count--; }
43
   
44

45
if( count >= 1){
46
return 7;
47
if(count<=7){
48
  restart

Kann ich meine eingeschalteten LED so zählen?
oder habt ihr einen anderen Vorschlag?
Ich habe 7 LED und ich möchte einen bestimmten Vorgang "restart" 
einleiten, wenn 7 oder mehr LED an sind
#3799326
Lesenswert?

Peter schrieb:

Was soll denn der ganze Palawatsch mit ...

>    if( count <= 6 )
>    count++;
>    }else{
>    if( count>8  )
>    count--; }

Zähl halt einfach, wieviele Bits auf 1 sind
1
  count = 0;
2

3
  if( PORTB & (BIT_2) )
4
    count++;
5

6
  if( .... )
7
    count++;
8

9
  ...

nachdem du alle Bits geprüft hast, hast du die Anzahl der brennenden 
LEDs.

> Ich habe 7 LED und ich möchte einen bestimmten Vorgang "restart"
> einleiten, wenn 7 oder mehr LED an sind

Ja dann mach das doch
1
   if( count >= 7 )
2
     restart

wo ist denn da jetzt das Problem, bzw. warum muss man da so kompliziert 
rumtricksen während man die Portbits abklappert?

Ich persönlich würde ja ganz einfach bei jedem Einschalten einer LED 
einfach einen Zähler erhöhen bzw. beim jeweiligen Ausschalten der LED 
den Zähler wieder verringern, so dass ich zu jedem Zeitpunkt die Anzahl 
der brennenden LED in dieser globalen Zählvariable vorliegen habe. Aber 
das kann jeder halten wie er will.
#3799330
Lesenswert?

Karl Heinz schrieb:

> Ich persönlich würde ja ganz einfach bei jedem Einschalten einer LED
> einfach einen Zähler erhöhen bzw. beim jeweiligen Ausschalten der LED
> den Zähler wieder verringern, so dass ich zu jedem Zeitpunkt die Anzahl
> der brennenden LED in dieser globalen Zählvariable vorliegen habe. Aber
> das kann jeder halten wie er will.



Überlesen. Aus dem OT
> Ich habe 7 LED und ich möchte einen bestimmten Vorgang
> "restart" einleiten, wenn 7 oder mehr LED an sind

Das ist eine extrem komplizierte Umschreibung für: Wenn alle LED 
brennen.
Das lässt sich aber leicht feststellen. Du kennst die Portbits aller LED 
und die müssen alle (offenbar) auf 1 sein. Ohne Ausnahme. Das ist eine 
simple Abfrage. Da muss man noch nicht einmal zählen.
Gast #3799332
Lesenswert?

Eingänge liest man über das Register PINC!
1
uint8_t mask=1;
2
uint8_t count=0;
3
for (uint8_t i=0; i<=6; i++) {
4
  if (PINC & mask) count++;
5
  mask<<=1;
6
}
7
printf("count=%i",count);

Was hast Du dir dabei gedacht?:
1
if( count>8 )
2
   count--;

Die Einrückungen sind sehr irreführend. Der Code mach beim zweiten 
hinschauen etwas ganz anderes, als auf den ersten Blick. Im Sinne der 
lesbarkeit rate ich Dir dazu, den Code so zu formatieren, dass die 
Einrückung der Klammerung entspricht - also so, wie es auch jeder Editor 
mit Auto-Format macht.

So ist es besser:
1
if(PORTC & (BIT_6)){
2
   if( count <= 6 ) {
3
     count++;
4
   }
5
}else{
6
   if( count>8 ) {
7
     count--;
8
   }
9
}
Gast #3799339
Lesenswert?

Mir ist gerade noch eine elegante Variante eingefallen, die mit einer 
Variablen weniger auskommt:
1
uint8_t mask=1;
2
uint8_t count=0;
3
do {
4
  if (PINC & mask) count++;
5
  mask<<=1;
6
}
7
while (mask<128);
8
printf("count=%i",count);

Es geht noch kompakter, aber ich finde es weniger gut lesbar:
1
uint8_t count=0;
2
for (uint8_t mask=1; mask<128; mask<<=1) {
3
  count++;
4
}
5
printf("count=%i",count);
Gast #3799352
Lesenswert?

1
uint8_t count = 0;
2

3
  if(PINB & (BIT_2)) count++;
4
  if(PINB & (BIT_3)) count++;
5
  if(PINC & (BIT_1)) count++;
6
  if(PINC & (BIT_4)) count++;
7
  if(PINC & (BIT_5)) count++;
8
  if(PINC & (BIT_6)) count++;
9
  if(PINC & (BIT_7)) count++;
10
    
11
    return count; 
12

13
if(count==7){
14
  restartGame();
15
}


Habe es nun so, aber es funktioniert dennoch nicht.

Habe ich irgendwo noch einen Fehler?
Gast #3799361
Lesenswert?

#define BIT_1 (1 << PC1)
#define BIT_2 (1 << PB2)
#define BIT_3 (1 << PB1)
#define BIT_4 (1 << PC3)
#define BIT_5 (1 << PC2)
#define BIT_6 (1 << PC4)
#define BIT_7 (1 << PC5)

das sind die Definitionen der Bits
#3799363
Lesenswert?

Marc Vesely schrieb:
> Peter schrieb:
>> Habe ich irgendwo noch einen Fehler?
>
>  Ja.
>  PORTB und PORTC, nicht PINB und PINC.

Ich fände PORTx auch naheliegender, ist aber in diesem Fall egal. Im PIN 
Register spiegelt sich die Bitposition der PORT Register wieder, wenn 
die Pins auf Ausgang geschaltet sind. Es gibt beim setzen oder löschen 
eines Bits eine kleine Verzögerung von, wenn ich mich recht erinnere, 1 
oder 2 Takten. Aber das dürfte hier keine Rolle spielen.
Gast #3799365
Lesenswert?

Naja. Karl Heinz hat ja schon gesagt, dass man nicht mal zählen muß.
Also hier das nicht-zählen:
1
if ((PINC & 0xF7) == 0xF7) {
2
  restartGame();
3
}


Was Deine Frage betrifft:

>Habe ich irgendwo noch einen Fehler?

So ist die Antwort: Ja.
#3799374
Lesenswert?

Peter schrieb:
> #define BIT_1 (1 << PC1)
> #define BIT_2 (1 << PB2)
> #define BIT_3 (1 << PB1)
> #define BIT_4 (1 << PC3)
> #define BIT_5 (1 << PC2)
> #define BIT_6 (1 << PC4)
> #define BIT_7 (1 << PC5)
Wenn das so ist funktioniert meine Lösung aus dem ersten Post nicht.

P.S: Ich finde es so verwirrend... Ich glaube so gut wie jeder hat 
gedacht, das BIT_1 (1<<1), BIT_2 (1<<2),..., BIT_n (1<<n) ist. 
Korrigiert nicht wenn ich falsch liege…

Peter schrieb:
> leider wird der restart nicht durchgeführt, die LEDs bleiben an.
> wenn ich den restart direkt an den Anfang der while schelife setze,
> funktioniert er aber, also muss es noch ein Problem geben
Setzt das return nach dem if
Gast #3799386
Lesenswert?

Max H. schrieb:
> P.S: Ich finde es so verwirrend... Ich glaube so gut wie jeder hat
> gedacht, das BIT_1 (1<<1), BIT_2 (1<<2),..., BIT_n (1<<n) ist.
> Korrigiert nicht wenn ich falsch liege…

Habe ich auch erst gedacht, aber wenn er seine LEDs so verdrahtet hat, 
dann ist es eben so. Vielleicht sollte man dann die Definitionen nicht 
"BIT_1" "BIT_2" usw. nennen, sondern "LED_1" "LED_2". Das bringt weniger 
Verwirrung.
Gast #3799397
Lesenswert?

Marc, dieser Code gibt 2 Fehler aus,

Error  1  lvalue required as unary '&' operand  C:\Dokumente und 
Einstellungen\sams\Desktop\Interaktive LED\Programm\interaktive LED.c 
255  24  interaktive LED

Error  2  expected ';' before '{' token  C:\Dokumente und 
Einstellungen\sams\Desktop\Interaktive LED\Programm\interaktive LED.c 
255  45  interaktive LED
#3799405
Lesenswert?

Peter schrieb:
> Marc, dieser Code gibt 2 Fehler aus,

Zeig doch mal, was du geschrieben hast.
Marcs Code ist ok. Ist im Grunde derselbe wie vorher, nur dass die 
Vergleichswerte andere sind und den tatsächlichen Bitpositionen 
entsprechen (wenn ich mich im Kopf nicht vertan habe)

Man könnte das auch noch ein wenig anders schreiben, so dass die Gefahr 
sich an dieser Stelle in den Bits zu vertun etwas gemildert ist, aber 
syntaktisch ist da erst mal alles in Ordnung in Marcs Code.
Gast #3799413
Lesenswert?

uint8_t count = 0;
  if(!((PORTB&0x06)==0x06) && ((PORTC&0x3E)==0x3E)) {
    restartGame();
  }

der Code startet das Spiel neu, wenn man erst alle LED an macht und dann 
wieder aus, also schon mal sehr gut, nur dass es bereits geschehen soll, 
wenn alle LED an sind
#3799428
Lesenswert?

Peter schrieb:
> #define BIT_1 (1 << PC1)
> #define BIT_2 (1 << PB2)
> #define BIT_3 (1 << PB1)
> #define BIT_4 (1 << PC3)
> #define BIT_5 (1 << PC2)
> #define BIT_6 (1 << PC4)
> #define BIT_7 (1 << PC5)


ehe da beim Umrechnen der Bitpositionen noch mehr Fehler passieren.

Ergänze da mal
1
...
2
#define BIT_7 (1 << PC5)
3

4
#define ALL_ON_B   ( BIT_2 | BIT_3 )
5
#define ALL_ON_C   ( BIT_1 | BIT_4 | BIT_5 | BIT_6 | BIT_7 )

und in der Funktion heisst es dann
1
void checkForRestart()
2
{
3
  if( ( ( PORTB & ALL_ON_B ) == ALL_ON_B ) &&
4
      ( ( PORTC & ALL_ON_C ) == ALL_ON_C ) )
5
    restartGame();
6
}

WEnn dann der Restart immer noch nicht ausgelöst wird, obwohl alle LED 
brennen, solltest du dir mal überlegen, ob deine LED wirklich genau dann 
brennen, wenn am Port ein 1 Bit ausgegeben wird oder ob das nicht 
umgekehrt ist.
(Firma: Vescomp) #3799438
Lesenswert?

Karl Heinz schrieb:
> void checkForRestart()
> {
>   if( ( ( PORTB & ALL_ON_B ) == ALL_ON_B ) &&
>       ( ( PORTC & ALL_ON_C ) == ALL_ON_C ) )
>     restartGame();
> }
>
> WEnn dann der Restart immer noch nicht ausgelöst wird, obwohl alle LED
> brennen, solltest du dir mal überlegen, ob deine LED wirklich genau dann
> brennen, wenn am Port ein 1 Bit ausgegeben wird oder ob das nicht
> umgekehrt ist.

 Ich glaube, er schaltet die LEDs in restartGame() nicht aus. Da fehlt
 ganz einfach so etwas wie AllLedOff(), oder so.

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