Frage zu einer IF-Bedingung

#1033174
Lesenswert?

In AVR-GCC gibt es auch noch die Makros bit_is_set/bit_is_clear. Das 
sieht dann zum Beispiel so aus:
1
if(bit_is_set(PIND, PIND2)) /* Do anything */;
Am compilierten Code ändert das nichts, ist aber vielleicht besser 
lesbar.

Mathias Obetzhauser wrote:
> Kann mir einer noch sagen wie das aussieht, wenn ich mit einem Taster
> eine LED an- und ausschalten möchte, also wie Stromstoßrelais?

Bei vielen AVRs, aber nicht allen, kann man den Port-Pin toggeln, indem 
man eine "1" an der entsprechenden Position in das Register PINx 
schreibt. Näheres verrät dir das Datenblatt des Prozessors.
Moderator (Firma: Titel) Persönliche Seite #1035633
Lesenswert?

> Taster ein > LED ein....Taster ein >LED aus
Deine Denkweise ist falsch. Du willst eigentlich, dass sich der Zustand 
der LED bei jedem erneuten Tastendruck ändern soll. So etwa:
>> Taster wird gedrückt (=steigende Flanke) --> LED = ~LED;

Was du brauchst ist eine Flankenerkennung. Sinnvollerweise auch eine 
Tasterentprellung. Jetzt such mal mit diesen Stichworten hier im Forum 
ein wenig herum, das Problem hatten andere auch schon.
OP #1036666
Lesenswert?

Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann 
doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue. In 
anderen Programmiersprachen ist das so einfach, da sind es nur 2-3 
Zeilen. Kann mir jemand mal bitte helfen.

Und wieso kann man eigentlich bei GCC kein "true" und kein "false" 
benützen?
Kann mir jemand sonst noch Eigenheiten von GCC nennen. Anscheinend hab 
ich eine andere C-Sprache gelernt so mit "printf" oder "if Taster == 
true".
Gast #1036681
Lesenswert?

Du kannst true und false schon verwenden, du musst einfach die bool.h 
includen (sofern die in deiner Toolchain vorhanden ist). Aber einfache 
#define's lösen dir dieses Problem auch ;)

Also printf gibt es im GCC auch, solange du die stdio.h includest.
Ein if ohne Klammern habe ich jedoch noch nie gesehen...
Moderator Persönliche Seite #1036684
Lesenswert?

Mathias Obetzhauser wrote:

> Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann
> doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue.

Du hast ein ganz anderes Problem: dein Taster muss erstmal entprellt
werden.  Das macht man normalerweise im Timerinterrupt, den man
periodisch alle ca. 10 ms aufruft.

Lösungen dafür gibt's bereits, wenn ich mich recht entsinne, geistert
hier irgendwo eine von Peter Dannegger herum.

Wenn du die Entprellung hast, dann ist auch die Flankenerkennung
kein Problem, du merkst dir einfach den vorigen Zustand am Anfang
eines jeden Timerinterrupts und vergleichst am Ende, ob sich der
Zustand geändert hat.

> In
> anderen Programmiersprachen ist das so einfach, da sind es nur 2-3
> Zeilen.

Besonders in VHDL oder Verilog, nicht wahr? ;-)

> Und wieso kann man eigentlich bei GCC kein "true" und kein "false"
> benützen?

Man kann true und false benutzen, wenn man entweder C++ als
Programmiersprache hat oder bei C entsprechend dem C99-Standard
zuvor den Header <stdbool.h> eingebunden hat.

> Kann mir jemand sonst noch Eigenheiten von GCC nennen.

Das GCC-Manual ist sehr hilfreich im Aufzählen der zahllosen
Erweiterungen gegenüber dem Sprachstandard.  Ansonsten wird erst
einmal vorausgesetzt, dass du die Sprache selbst (die von der ISO
standardisiert worden ist) natürlich kennst.

> Anscheinend hab
> ich eine andere C-Sprache gelernt so mit "printf" oder "if Taster ==
> true".

Das ist Pascal.  In C wäre es, wenn schon, dann:
1
if (Taster == true) ...

Ist aber Unfug.  Offensichtlich ist ja deine Absicht, dass die Variable
Taster vom Typ bool ist (sonst hätte es keinen Sinn, sie gegen true
oder false zu vergleichen), aber ein bool ist natürlich bereits ein
sinnvoller Steuerausdruck für ein if, sodass man dann besser schreiben
kann:
1
if (Taster) ...

Der zusätzliche Vergleich gegen true bringt rein gar nichts außer mehr
Schreibaufwand, besser lesbar oder irgendwie ,,richtiger'' wird die
Formulierung dadurch nicht.

printf gehört zu stdio.  Da du aber (offenbar) auf einem AVR arbeitest,
der keine klassische ,Bedienconsole' hat wie ein Hostcomputer, musst
du vor der Benutzung erst einmal ein wenig Arbeit investieren um dem
stdio zu sagen, womit es denn sein stdout umsetzen soll (Ausgabe
auf LCD, Ausgabe auf UART, Übertragung über Funkmodul, ...).  Wie das
geht, steht im Handbuch der avr-libc, denn stdio ist Sache der
(Standard-)Bibliothek.
Gast #1036717
Lesenswert?

Mathias Obetzhauser wrote:

> Ich hab überall geguckt, hab aber nichts brauchbares gefunden. Das kann
> doch nicht so schwer fallen sein, eine Flankenerkennung ein zu baue. In
> anderen Programmiersprachen ist das so einfach, da sind es nur 2-3
> Zeilen.

Beispiel?

> Kann mir jemand mal bitte helfen.

Eine Taste per Software entprellen ist so schwer ja nun auch nicht. 
Primitiver Ansatz: Die Taste einfach mit einem Delay, der laenger ist 
als die Prellzeit aber kuerzer als die kuerzeste Drueckzeit, 2 mal 
abfragen. Ist der Zustand in diesem Zeitraum gleich, hast du einen 
zuverlaessigen Wert, den du verarbeiten kannst.

> Und wieso kann man eigentlich bei GCC kein "true" und kein "false"
> benützen?

Geht gut bei mir. Wie waer's mal mit einem uebersetzbaren Code-Beispiel, 
dass deine Probleme aufzeigt?
OP #1036738
Lesenswert?

Beispiel für Erkennung einer steigenden Flanke:
1
R_TRIG_1(CLK:=Taster);
2
Taster_R:=R_TRIG_1.Q;

Die Variable Taster ist letztendlich der Eingang wo man wissen, wann 
eine steigende Flanke da ist. Und die Variable Taster_R wird kurz high 
wenn eine steigende Flanke erkannt wurde. R_TRIG ist dafür der 
Funktionsbaustein. So in etwa möchte ich das auch haben. Dies ist 
geschrieben in ST (Strukturierter Text) und wird verwendet beim 
programmieren von SPSen.


Mein eigentliches Anliegen ist: mit einem Taster eine LED an- und 
ausschalten, wie eine Art Stromstoßrelais.
Gast #1036793
Lesenswert?

Wenn du kein Bock auf C lernen hast, dann lass es halt und bleib bei ST.
Wenn du aber doch C lernen möchtest, dann musst du auch akzeptieren, 
dass es eine andere Sprache ist, und dich nicht beschweren, dass nun 
aufeinmal alles anders ist als in ST!
Gast #1036813
Lesenswert?

Auf "keine Lust" reagiert mein Chef immer etwas allergisch. Vor allem, 
wenn er das Gefuehl hat, ich habe keine Lust zum Denken.

bool NewState = INPUT_PIN;
bool TriggerUp = ( LastState == 0) && ( NewState == 1);
LastState = NewState;

Vieleicht habe ich da ja irgendwas nicht verstanden, aber ich bin ja nur 
Informatiker...
Moderator Persönliche Seite #1036827
Lesenswert?

Mathias Obetzhauser wrote:

> Außerdem wollte ich nur wissen ob jeand sowas schonmal gemacht hat bzw.
> ob es dafür eine Funktion gibt.

Ja, gibt es, wie dir bereits mehr als einer geschrieben hat: die
Methode heißt Tastenentprellung.  Wenn du diese hast (such danach),
und wenigstens das Prinzip verstanden hast, dann ergibt sich die
Taste-Gedrückt-Erkennung praktisch von allein.
OP #1036856
Lesenswert?

Ich brauche erstmal keine Tastenentprellung, ich will nur den Taster 
abfragen   ob er von 0 nach 1 gewechselt ist oder 1 nach 0. Ich will 
nicht die Zustände 1 oder 0 abfragen. Wie zb bei einer 
Zweihand-Verriegelung. Da wird auch abgefragt ob eine Steigende Flanke 
da war oder nicht. Sonst könnte man ja einfach auf die Taster Tesafilm 
kleben und das wärs. Nur dann ergibt die Verriegelung kein Sinn mehr.
Gast #1036874
Lesenswert?

Im Prinzip ist deine Frage doch schon beantwortet worden!
Sogar mit einem Code-Beispiel!

Im Gegensatz zur SPS ist der µC vermutlich deutlich schneller und erfaßt 
deshalb auch das mechanische Tasten-Prellen - du drückst einmal und der 
µC sieht 2-5 mal eine Flanke...
Dadurch ist es eher Zufall, ob die simple Flankenerkennung ein 
funktionierendes Tast-Relais produzieren kann.

Aber: Du willst lernen, also bau' dir diese Funktionalität schrittweise 
auf und erfahre selbst, wo die Probleme stecken.

Also erstmal "Taste gedrückt --> LED toggelt",
dann Flankenerkennung dazu,
dann die richtige Entprellung ("bullet-proof" v. Peter Danegger, kann 
ich sehr empfehlen)

Viel Spaß!

Ahoi, Martin
Gast #1036935
Lesenswert?

Hier mal etwas das toggelt und das Tastenprellen schön zeigt.

Taster an PORTB0 gegen GND
Eine LED von +5V mit Vorwiderstand an PORTB6
Eine LED von +5V mit Vorwiderstand an PORTB7
MCU: Irgend einen Atmel

/* Toggel-Taster */
#include <avr/io.h>

int main(void)
{
  DDRB  |= (1<<DDB6)|(1<<DDB7); // PB6 und PB7 als Ausgang Rest Eing.
  PORTB |= (1<<PB0);            // internen Pull-Up an PB0 aktivieren
  PORTB |= (1<<PB6);            // LED6 aus, LED7 an

  while(1)
  {
    if (!(PINB & (1<<PINB0)))
    {
      PORTB ^= (1<<PB6);  // LED an Port PB6 an bzw. ausschalten
      PORTB ^= (1<<PB7);  // LED an Port PB7 an bzw. ausschalten
    }
  }
}

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