Forum: PC-Programmierung Bitschubserei / Testerei (kein Osterei) in AVR GCC klappt nicht


von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Hallo Forengemeinde,
ich habe so meine Probleme mit testen von Port-Bits.
Folgendes geht:
if ( !(PINB & (1<<PINB4)) - Wenn Bit 4 (0-7) im Port-B Lo ist, dann 
mache..
Das funktioniert ja.

nun benötige ich aber ein Konstrukt, dass z.B. testet:
Wenn Bit 5 im Port-B High ist, dann....
Mein Ansatz:
if ((PINB &= (1<<PINB5)) & Korb_Flag == true)
oder
if ((PINB |= (1<<PINB5)) & Korb_Flag == true)
 - funktioniert nicht
Korb-Flag könnt Ihr ignorieren, oder was weiß ich. Das ist die 2. 
Bedingung

Bitte erklärt mir mal, wie ich ein Bit vom Port teste, ob es High ist.

Danke.

Beitrag #7859943 wurde vom Autor gelöscht.
von Pi S. (knisterbein)


Lesenswert?

schreib das:
if ((PINB & (1<<PINB5)) && Korb_Flag)

von Peter D. (peda)


Lesenswert?

Thomas S. schrieb:
> if ((PINB &= (1<<PINB5)) & Korb_Flag == true)
> oder
> if ((PINB |= (1<<PINB5)) & Korb_Flag == true)

Ganz böses Foul, ein Schreiben auf einen Inputport kann Outputbits 
kippen!
Auf PINx nur dann schreiben, wenn man auch weiß, was man tut.

Und Binärverknüpfung von logischen Ausdrücken ist zumindest unschön, 
wenn nicht sogar falsch.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Thomas S. schrieb:
> Mein Ansatz:
> if ((PINB &= (1<<PINB5)) & Korb_Flag == true)
> oder
> if ((PINB |= (1<<PINB5)) & Korb_Flag == true)
>  - funktioniert nicht

Erkenne den Unterschied zwischen

   & und &=


bzw. zwischen

   | und |=


Hast Du mal in ein C-Buch gesehen?

von Walter T. (nicolas)


Lesenswert?

Thomas S. schrieb:
> Korb-Flag könnt Ihr ignorieren, oder was weiß ich. Das ist die 2.
> Bedingung

Die hoffentlich die gleiche Bitmaske wie Deine Port-Pins hat.

von Rbx (rcx)


Lesenswert?

https://forum.arduino.cc/t/controlling-outputs-by-setting-bits/1046473/3
https://electronoobs.com/eng_arduino_tut130.php
https://www.programiz.com/c-programming/bitwise-operators
https://en.wikipedia.org/wiki/Bitwise_operations_in_C

So ein paar Grundlagen zu erwerben, und mit praktischen Übungen zum 
Erweitern, wären auch sehr hilfreich und machen (jedenfalls mir) etwas 
mehr Spaß ;)

von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Hallo Mitwirkende

@Knisterbein
der Part funktioniert aber trotzdem nicht, so wie ich es will.
Letztendlich will ich eine neg. Flanke aus dem Eingangssignal haben.

so hatte ich das auch schon. bzw. mit ausgeschriebenen ...& Korb_Flag == 
true
1. Wenn PinB5 Lo wird, und das Flag 'False' ist
 . soll das Flag 'High' werden
2. Wenn PinB5 wieder 'High' wird (weil das Eingangsignal weggeht), und 
das Flag 'High' ist, wird die Prozedere ausgeführt
3. Wird PinB5 'Lo', und das Flag False ist, wird das Flag 'High'.
4. Bleibt PinB5 'Lo', ist ja das Flag noch High, bis Der Pin High wird.
Die Pins werden per PullUp hochgehalten, ein Optokoppler zieht den bei 
Signal runter. der Impuls kann bis zu 300 mS dauern, das ist zu lang. 
Deshalb über eine Variable, setzen und löschen, und diese auswerten. Der 
angehängte Part ist so nicht stimmig. Wird der Pin Lo, zählt der 
unaufhörlich hoch. Es darf nur 1 Impuls kommen.

Habe hier mal den betreffenden Part angehängt
1
    if (Spiel_gestartet == true)
2
    {
3
       if ( !(PINB & (1<<PINB5)) & Korb_Flag == false)
4
       {
5
         Korb_Flag = true; // Flankenerzeugung 
6
        // PORTA |= (1<<6);  // Led ein
7
       }
8
      if ((PINB & ~(1<<PINB5)) && Korb_Flag) // Bei fallender Flanke, bzw wenn das Bit Lo ist
9
      {
10
      score ++;
11
      update_Score_Digits(score);
12
      Points_for_Chip ++;
13
      Korb_Flag = false;
14
      //PORTA &= ~(1<<6);  // Led aus
15
      }  
16
      if (Korb_Flag == true)  // Nur Testabfrage
17
      {
18
         PORTA |= (1<<6);    // Led ein
19
      }         
20
      else
21
      { 
22
         PORTA &= ~(1<<6);  // Led aus
23
      }    
24
      
25
      if (Points_for_Chip == Koerbe_Chip)
26
      {
27
      Chips_to_go ++;
28
      Points_for_Chip =0;
29
      }
30
    }

von Harald K. (kirnbichler)


Lesenswert?

Thomas S. schrieb:
> if ( !(PINB & (1<<PINB5)) & Korb_Flag == false)

Und jetzt nimmst Du Dir Dein C-Buch nochmal in die Hand und findest 
raus, was der Unterschied zwischen logischen und bitweisen 
Operatoren ist.

Das steht da nämlich drin.

: Bearbeitet durch User
von Georg M. (g_m)


Lesenswert?

Thomas S. schrieb:
> Letztendlich will ich eine neg. Flanke aus dem Eingangssignal haben.
1
 if(!flag1 && signal)
2
 {
3
   flag1 = 1;
4
 }
5
6
 . . . . . . .
7
 . . . . . . .
8
9
 if(flag1 && no signal)
10
 {
11
   flag1 = 0;
12
   . . . . . . .
13
   . . . . . . .
14
 }

von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Harald K. schrieb:
> Thomas S. schrieb:
>> if ( !(PINB & (1<<PINB5)) & Korb_Flag == false)
>
> Und jetzt...
So funktioniert es

if ((PINB & (1<<PINB5)) && Korb_Flag) // Bei fallender Flanke, bzw wenn 
das Bit Lo ist

Top!!

Sehe die Fehler vor lauter Ostereier nicht mehr. - smile

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Thomas S. schrieb:
> Sehe die Fehler vor lauter Ostereier nicht mehr

Hast Du denn in einem der Ostereier auch dein C-Buch gefunden und Dir 
dort mal die verschiedenen Operatoren angesehen?

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

> if ((PINB & ~(1<<PINB5))

Damit fragst du alle Pins ab, außer PB5.

von Harald K. (kirnbichler)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:
> Damit fragst du alle Pins ab, außer PB5.

Aber auch noch mit der Gemeinheit, daß der Ausdruck wahr wird, sobald 
einer oder eine beliebige Kombination der anderen Pins high ist.

von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:
>> if ((PINB & ~(1<<PINB5))
>
> Damit fragst du alle Pins ab, außer PB5.

Aktuell, wie es funktioniert ist diese:
  if ((PINB & (1<<PINB5)) && Korb_Flag)

Harald K. schrieb:
> Hast Du denn in einem der Ostereier auch dein C-Buch gefunden und Dir
> dort mal die verschiedenen Operatoren angesehen?

Nein habe ich noch nicht gefunden. Bin aber online fündig geworden, auch 
mit hilfe von RBX. Manche Syntax ist mir halt nicht geläufig, und dann 
frag ich halt nach. Ich denke dafür ist dann das Forum da. - smile

Habe auch noch vor Sound entweder mit diesem Atmega32, oder besser mit 
einem Atmega8 an der Seite vom Atmega32 zu erzeugen. Nur Kling-Klang, 
oder wilde Töne, evtl. mit Hallkurve, bzw. anschwellen, abschwellen. Das 
hat in einer Schaltung ein steinalter Pic geschafft, dann sollte es der 
Atmega8 an der Seite auch schaffen.

von Harald K. (kirnbichler)


Lesenswert?

Thomas S. schrieb:
> Manche Syntax ist mir halt nicht geläufig, und dann
> frag ich halt nach.

Ja, warum auch Grundlagen lernen, wenn man doch einfach immer irgendwo 
nachfragen kann?

von Norbert (der_norbert)


Lesenswert?

Bis jetzt knapp fünfzehn Beiträge, welche sich mit einfachsten 
arithmetischen und logischen Ausdrücken beschäftigen. Ohne sichtbaren 
Erfolg.

Thomas S. schrieb:
> Habe auch noch vor Sound entweder mit diesem Atmega32, oder besser mit
> einem Atmega8 an der Seite vom Atmega32 zu erzeugen. Nur Kling-Klang,
> oder wilde Töne, evtl. mit Hallkurve, bzw. anschwellen, abschwellen. Das
> hat in einer Schaltung ein steinalter Pic geschafft, dann sollte es der
> Atmega8 an der Seite auch schaffen.

Möchtest du dem Forenbetreiber zunächst eine zusätzliche große 
Festplatte spendieren? Das kann noch echt lang werden.

von Harald K. (kirnbichler)


Lesenswert?

Norbert schrieb:
> Ohne sichtbaren
> Erfolg.

Sieht er vermutlich anders.

Thomas S. schrieb:
> So funktioniert es
>
> (...)
>
> Top!!

Wir könnten jetzt die alte und immer zutreffendere* Leier über die 
Jugend anstellen, oder aber eine Exitstrategie entwickeln, die uns 
hilft, mit den immer häufiger werdenden Grundlagenverweigereren 
irgendwie klarzukommen.

Ich stelle mir das schwierig vor.

*) vor allem die über deren zunehmende Verblödung, siehe auch hier:
https://www.nytimes.com/2025/04/10/opinion/education-smart-thinking-reading-tariffs.html

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Thomas S. schrieb:
> Manche Syntax ist mir halt nicht geläufig

Lege dir Makros mit sprechenden Namen an. z.B.
1
#define Start_Taster_gedrueckt (PINB & (1<<PB5))
2
#define Start_Taster_losgelassen (!Start_Taster_gedrueckt)

Falls der der HIGH Pegel jedoch bedeutet, daß der Taster los gelassen 
wurde, dann umgekehrt:
1
#define Start_Taster_losgelassen (PINB & (1<<PB5))
2
#define Start_Taster_gedrueckt (!Start_Taster_losgelassen)

Danach kannst du gut lesbare if Ausdrücke schreiben:
1
if (Start_Taster_gedrueckt && Korb_flag==false) {
2
  ...
3
}
4
5
if (Start_Taster_losgelassen && Korb_flag==true) {
6
  ...
7
}

Mache auf jeden Fall immer Klammern um die Ausdrücke hinter #define, 
damit sie innerhalb von komplexen Ausdrücken immer das tun, was man 
erwartet.

Den Namen von Korb_flag würde ich auch nochmal überdenken, denn er sagt 
nicht aus, was das Flag bedeutet. Namen wie Korb_getroffen wären 
aussagekräftiger.
1
if (Start_Taster_gedrueckt && !Korb_getroffen) {
2
  ...
3
}
4
5
if (Start_Taster_losgelassen && Korb_getroffen) {
6
  ...
7
}

Makros helfen auch bei Schaltausgängen:
1
#define Sirene_an PORTC |= (1<<PC1)
2
#define Sirene_aus PORTC &= ~(1<<PC1)
3
4
if ... {
5
  Sirene_an;
6
} else {
7
  Sirene_aus;

Falls dir solche Makros suspekt sind, schreibe stattdessen Funktionen 
mit sprechenden Namen.
1
bool Sabotage_erkannt() {
2
  return PortB & (1<<PB4)
3
}
4
5
void Sirene_an() {
6
  PORTC |= (1<<PC1)
7
}
8
9
if (Sabotage_erkannt()) {
10
  Sirene_an();
11
}

Gerade bei AVR sind Funktionsaufrufe "billig". Außerdem optimiert der 
Compiler solche einzeiligen Funktionen meistens komplett weg, als hätte 
man direkt auf den Pin zugegriffen.

Der entscheidende Punkt ist, lesbare Namen zu verwenden, damit komplexe 
Ausdrücke verständlich bleiben.

: Bearbeitet durch User
von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Sherlock 🕵🏽‍♂️ schrieb:
> Lege dir Makros mit sprechenden Namen an. z.B.

Dann danke ich Dir für die Ausführung hier. Das werde ich überdenken es 
ectl. so umzuschreiben. Das sind im Gegensatz zu den 'Nörglern' hier 
verwertbare Infos, und Tips.

Norbert schrieb:
> Bis jetzt knapp fünfzehn Beiträge, welche sich mit einfachsten
> arithmetischen und logischen Ausdrücken beschäftigen. Ohne sichtbaren
> Erfolg.
Es sind auch ca. 1 Meter Beiträge dabei, die sinnfrei sind, und wo es 
nur ums Meckern geht.

Du brauchst nicht nörgeln. wenn Dir was nicht passt, bleib einfach vor 
der Tür. Ich habe es schon x-mal geschrieben, dass ich kein C-Guru bin. 
Mache es hier und da. Und ich komme auch zum Ziel. Auch mit Hilfe von 
hier, klar.

Habt Ihr ein Problem mit Forenmitgliedern, die nicht auf der sehr hohen 
Programmierschwelle sind wie Ihr? - Dan sagt es. Ich dachte, und denke, 
dafür ist ein Forum da. - Um zu Fragen.

Zur Info: das Modul, um das es hier geht, läuft problemlos.

: Bearbeitet durch User
von Harald K. (kirnbichler)


Lesenswert?

Thomas S. schrieb:
> Ich dachte, und denke,
> dafür ist ein Forum da. - Um zu Fragen.

Es ist nicht dafür da, Fragen von Leuten zu beantworten, die sich 
hartnäckig weigern, Tips zur Selbsthilfe anzunehmen. Es ist nicht 
ChatGPT, das geduldig immer wieder die gleichen Fragen beantwortet, weil 
der Fragende zu faul ist, etwas selbst zu lernen.

Ich habe Dir sinnvolle Hinweise gegeben. Gleich zweimal.

Aber das hast Du vermutlich nicht verstanden, oder nicht verstehen 
wollen, denn meine Hinweise waren ja auch kompliziert und anstrengend, 
nämlich der Hinweis, zwei bestimmte Fragestellungen in einem Buch 
nachzulesen.

Das ist natürlich eine Zumutung, ich hätte ja auch einfach Deine Aufgabe 
lösen können. Nur hättest Du dabei erst recht nichts gelernt.

Niemand verlangt von Dir, wenn Du hier Fragen stellst, daß Du der 
"C-Guru" bist; wärst Du es, müsstest Du ja keine Fragen stellen.

Aber wenn Du Dich hartnäckig weigerst, hilfreiche Hinweise anzunehmen -- 
dann fange ich an, unerfreut zu reagieren.

von Thomas S. (Firma: Chipwerkstatt) (tom_63)


Lesenswert?

Harald K. schrieb:
> Ich habe Dir sinnvolle Hinweise gegeben. Gleich zweimal.
>
> Aber das hast Du vermutlich nicht verstanden,

Das habe ich auch registreiert, und versucht zu verstehen, wo Du mich 
'hinlenken' willst. Ich habe hier einfach nicht den Fehler gesehen.

Nun läuft die Routine auch ferhlerfrei.

Mir ging es nicht um Deine Komentare, aber andere söseln da noch mit 
rein, und dann wird der Tread lang.

Zum Beispiel hier. - Sowas ist überflüssig.
Norbert schrieb:
> Möchtest du dem Forenbetreiber zunächst eine zusätzliche große
> Festplatte spendieren? Das kann noch echt lang werden.

von Norbert (der_norbert)


Lesenswert?

Thomas S. schrieb:
> Zum Beispiel hier. - Sowas ist überflüssig.
> Norbert schrieb:
>> Möchtest du dem Forenbetreiber zunächst eine zusätzliche große
>> Festplatte spendieren? Das kann noch echt lang werden.

Na Thomas, dann setz' das mal in den passenden Kontext.
Du quälst dich damit ein Bit eines Registers abzufragen und planst 
zeitgleich Audiogenerierung mit Hüllkurven auf dem µC. Da sollte ein 
wenig Ironie gestattet sein.

von Obelix X. (obelix)


Lesenswert?

Thomas S. schrieb:
> Nun läuft die Routine auch ferhlerfrei.

Hast du aber auch verstanden was warum der Code von Sherlock 
funktioniert?
Das hilft dir bei deiner nächsten Code-Zeile.

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.