ATMEGA8 eingeschaltete LED Zählen

Gast #3799306
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
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.
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
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
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
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
#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
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
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.
Gast
stefan us schrieb:
> Es geht noch kompakter, aber ich finde es weniger gut lesbar:
> uint8_t count=0;
> for (uint8_t mask=1; mask<128; mask<<=1) {
>   count++;
> }
> printf("count=%i",count);

Wo fragst du hier den Port ab? Ich denke, da fehlt noch was, oder :-)
Gast
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
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
uint8_t count = 0;
  if((PORTB&0x0C)|(PORTC&0xF2)==0xFE) {
    restartGame();
  }

das programm springt jetzt in den resart. allerdings nicht, wenn alle 7 
LED an sind, sondern beim drücken von bestimmten tastern
(Firma: Vescomp)
Karl Heinz schrieb:
> 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.
 Atmel sagt, 1 NOP zwischen OUT und IN ist nötig.

>  Aber das dürfte hier keine Rolle spielen.
 Ja. Ich meine Nein. Ich meine du hast Recht.
Gast
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
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
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
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
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)
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.
Gast
Karl Heinz vielen Dank.

Es besteht noch das Problem, dass der Restart erst ausgeführt wird, wenn 
ich alle LED ausschalte. Was muss ich ändern, sodass dieser ausget wird, 
wenn alle an sind?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 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.