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.
Ich bekomm es einfach mit dem toggeln nicht hin.
Hier nochmal das was ich machen wollte, ganz simpel eigentlich. Taster
ein > LED ein....Taster ein >LED aus, praktisch wie ein T-Flipflop.
Bitte helft mir.
> 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.
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".
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...
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.
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?
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.
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!
Wieso entprellen, mir gehts erstmal ums erkennen einer steigenden
Flanke. Und ich hab Lust C zu programmieren, sonst würde ich mich damit
doch nicht rumschlagen. Ich wollte ja nur wissen ob es da eine Funktion
bzw. Baustein für gibt sowie bei ST.
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...
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.
> ob jeand sowas schonmal gemacht
Nein, da die Sprach brandneu ist, hat das noch nie jemand gemacht. Über
einfach Addition sind die meisten C-Programmierer noch nicht hinaus.
Hallo!
nur mal Grundsätzlich, ne SPS wird eigentlich interpretiert, Analog
Java..., da wird nix in maschinensprache umgesetzt.
so kenn ich das.
Gruß Stefan
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.
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
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
}
}
}