Forum: Mikrocontroller und Digitale Elektronik ATMEGA8 eingeschaltete LED Zählen


von Peter (Gast)


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

von Max H. (hartl192)


Lesenswert?

Peter schrieb:
> Ich habe 7 LED und ich möchte einen bestimmten Vorgang "restart"
> einleiten, wenn 7 oder mehr LED an sind
Wie können bei 7 LEDs mehr als 7 an sein?
Wenn die Zahl der LEDs unwichtig ist und es nur interessant it ob alle 7 
an sinf oder nicht sind geht es so schnellet
1
if(PORTB&0x0C)|(PORTC&0xF2)==0xFE)
2
  restart();

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> if( count>8 )
>    count--; }

 Kann niemals wahr werden.

Peter schrieb:
> if( count >= 1){
> return 7;
> if(count<=7){
>   restart

 Wie willst du die untere Abfrage erreichen ?

 Und wo fängt was an, wo endet es ?

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von stefan us (Gast)


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
}

von Max H. (hartl192)


Lesenswert?

stefan us schrieb:
> Eingänge liest man über das Register PINC!
Aber nur die an PORTC, die LEDs an PORTB kann er damit nicht einlesen. 
Wenn er die LEDs erst in Software durch setzten des entsprechenden bits 
in PORTx einschaltet kann er sie auch über das PORTx Register abfragen.

von Karl H. (kbuchegg)


Lesenswert?

stefan us schrieb:
> Eingänge liest man über das Register PINC!

Das passt schon.
Er will wissen, wieviele Ausgänge vom Rest des Programms auf 1 gesetzt 
wurden. Das kann er mit dem jeweiligen PORT Register machen.

von stefan us (Gast)


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);

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

stefan us schrieb:
> Eingänge liest man über das Register PINC!

 Ne, er schaltet die LEDs selber.

Karl Heinz schrieb:
> Das ist eine extrem komplizierte Umschreibung für: Wenn alle LED
> brennen.

 Ja.
 (PORTB & 0xFE) == 0xFE

von stefan us (Gast)


Lesenswert?

> Aber nur die an PORTC, die LEDs an PORTB kann er damit nicht einlesen.

Ach, das habe ich ja ganz übersehen...

von Max H. (hartl192)


Lesenswert?

Marc Vesely schrieb:
> Ja.
>  (PORTB & 0xFE) == 0xFE
Die LEDs an PORTC kann er damit nicht erfassen...
1
if((PORTB&0x0C)|(PORTC&0xF2)==0xFE)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Max H. schrieb:
> Die LEDs an PORTC kann er damit nicht erfassen...

 Ja, du hattest natürlich schon bei deiner ersten Antwort recht...
 Ich war ganz einfach verblüfft über die Unsinnigkeit - war aber
 nicht der einzige, Karl Heinz hat es auch erwischt ;-))

von Peter (Gast)


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?

von Max H. (hartl192)


Lesenswert?

Peter schrieb:
> Habe es nun so, aber es funktioniert dennoch nicht.
Was funktioniert nicht?
Wie ist BIT_2,... definiert?

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:

>     return count;
>
> if(count==7){
>   restartGame();
> }
>
>
>
> Habe es nun so, aber es funktioniert dennoch nicht.
>
> Habe ich irgendwo noch einen Fehler?

überleg mal, wie die Funktion wohl jeh zur Auswertung auf 7 kommen soll, 
wenn vorher ein return statt findet?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> Habe ich irgendwo noch einen Fehler?

 Ja.
 PORTB und PORTC, nicht PINB und PINC.

von Peter (Gast)


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

von Karl H. (kbuchegg)


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.

von Bitflüsterer (Gast)


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.

von Karl H. (kbuchegg)


Lesenswert?

Bitflüsterer schrieb:
> 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
> }
4
>
>

haut nicht hin. Er hat die LED auf 2 Ports verteilt. Ganz oben ist schon 
mal eine saubere Abfrage gepostet worden.

von npn (Gast)


Lesenswert?

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 :-)

von Peter (Gast)


Lesenswert?

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

von Max H. (hartl192)


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

von Bitflüsterer (Gast)


Lesenswert?

Karl Heinz schrieb:
> Bitflüsterer schrieb:
> <Irgendwas Falsches>
> haut nicht hin.

Danke für den Hinweis. Sorry.

von Peter (Gast)


Lesenswert?

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

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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.

von npn (Gast)


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.

von Karl H. (kbuchegg)


Lesenswert?

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

weil zuvor ein return steht!

Lies doch mal deinen Code

von Peter (Gast)


Lesenswert?

Karl Heinz, das return habe ich bereits gelöscht, dank deinem Hinweis :)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> if((PORTB&0x0C)|(PORTC&0xF2)==0xFE) {
>     restartGame();

 if((PORTB&0x06)==0x06) & ((PORTC&0x3E)==0x3E) {

von Peter (Gast)


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

von Max H. (hartl192)


Lesenswert?

So sollten die Klammern passen:
1
if(((PORTB&0x06)==0x06) && ((PORTC&0x3E)==0x3E))

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

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

 Ja, dann schreibe es doch richtig, ich wollte dir nur zeigen
 welche Werte du vergleichen must...

von Daniel H. (Firma: keine) (commander)


Lesenswert?

Wie wäre es so?
1
uint8_t i;
2
uint8_t count = 0;
3
4
for(i = 0; i < 8; i++) {
5
    count += (PORTB >> i) & 1;
6
}

von Karl H. (kbuchegg)


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.

von Peter (Gast)


Lesenswert?

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


7 LEDs brennen, es passiert nichts..

von Max H. (hartl192)


Lesenswert?

Daniel H. schrieb:
> Wie wäre es so?
> uint8_t i;
> uint8_t count = 0;
>
> for(i = 0; i < 8; i++) {
>     count += (PORTB >> i) & 1;
> }
Die LEDs sin immer noch auf PORTB und PORTC verteilt.

von Daniel H. (Firma: keine) (commander)


Lesenswert?

Max H. schrieb:
> Die LEDs sin immer noch auf PORTB und PORTC verteilt.

Autsch, hatte ich übersehen, danke.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Max H. schrieb:
> if(((PORTB&0x06)==0x06) && ((PORTC&0x3E)==0x3E))

 Also, wenn ich die Klammern für ihn zählen muß...
 Aber, AndAlso habe ich wirklich übersehen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> 7 LEDs brennen, es passiert nichts..

 Wie ware es, wenn du die LEDs auch mal ausmachst ?

von Peter (Gast)


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

von Karl H. (kbuchegg)


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.

von Marc V. (Firma: Vescomp) (logarithmus)


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.

von Peter (Gast)


Lesenswert?

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?

von Max H. (hartl192)


Lesenswert?

Wie hast du die LEDs verschalten?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Peter schrieb:
> 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?

 Er wird ausgeführt, nur du merkst es nicht, weil du die LEDs in Restart
 nicht ausmachst.
 Meiner Meinung nach.

von Karl H. (kbuchegg)


Lesenswert?

Marc Vesely schrieb:

>  Er wird ausgeführt, nur du merkst es nicht, weil du die LEDs in Restart
>  nicht ausmachst.
>  Meiner Meinung nach.

Klingt vernünftig.

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.