>PORTC&=~(1<<PC0);// LED an PB0 ausschalten (high-aktiv)
9
>//PORTC |= (1 << PC0); // LED an PB0 ausschalten (low-aktiv)
10
>}
11
>
Das wird allerdings ein kurzes 'Blinken' wenn die Taste gedrückt wird.
Ich bezweifle, dass man das sehen wird. Kein Mensch kann eine LED, die
nur µs auf 'aus' geht, von einer durchgehend leuchtenden LED
unterscheiden :-)
PORTC&=~(1<<PC0);// LED an PB0 ausschalten (high-aktiv)
11
//PORTC |= (1 << PC0); // LED an PB0 ausschalten (low-aktiv)
12
}
13
}
Solange die if-Bedingung erfüllt ist, wird die LED im 1/5 Sekunden Takt
getoggled. Wenn nicht erfüllt, wird sie halt ausgeschaltet.
Die Endlosschleife hab ich drumrum gesetzt, damit hier überhaupt eine
wiederkehrende Aktion ausgeführt werden kann.
Manfred W. schrieb:
> Die LED leuchtet ständig bei gedrückter Taste.>
1
>if(!(PINB&0x01))// Wenn Taste PortB.0 auf HIGH
2
>{
3
>PORTC^=(1<<PC0);// LED an PC0 umschalten
4
>_delay_ms(200);
5
>}
6
>PORTC=0;
7
>
Logisch.
Von Magnetus gabs ja auch noch ein Update, welches das Problem behebt.
Im Übrigen solltest du tatsächlich verstehen, warum es da überhaupt ein
Problem gibt.
>> So gehts aber:>>
Karl heinz Buchegger schrieb:
> Von Magnetus gabs ja auch noch ein Update, welches das Problem behebt.>> Im Übrigen solltest du tatsächlich verstehen, warum es da überhaupt ein>> Problem gibt.
Weil sich der Status von PortC nie ändert.
Manfred W. schrieb:
> Ja, weil die Schleife nie verlassen wird bei gedrückter Taste.
Welche Schleife?
Da ist keine Schleife!
Ein 'if' ist eine bedingte Verzweigung aber keine Schleife.
ALso noch mal die Frage:
Warum 'blinkt' in diesem Beispiel die LED nicht bei gedrückter Taste?
1
...
2
3
while(1){
4
if(!(PINB&0x01))// Wenn Taste PortB.0 auf HIGH
5
{
6
PORTC^=(1<<PC0);// LED an PC0 umschalten
7
_delay_ms(200);
8
}
9
PORTC=0;
10
}
arbeite das Programm mit dem Finger auf den Programmzeilen durch und
spiele Computer.
(Tatsächlich blinkt die LED schon. Aber sie ist 200ms auf ein und ein
paar µs auf aus. Zu kurz auf aus, als das man das sehen könnte. Mit
einem Oszi würde man das allerdings detektieren können. Von daher ist
die Aussage 'blinkt nicht' nicht zu halten. "Ergibt kein sichtbares
blinken" würde die Sache eher beschreiben. Aber wir wollen jetzt keine
Haare spalten)
Manfred W. schrieb:
>> Weil sich der Status von PortC nie ändert.
Wenn das tatsächlich deine Antwort ist (die vorher noch anders gelautet
hat), dann kann ich nur sagen:
Such dir ein anderes Hobby. Du hast offenbar nicht das Zeug, das man
benötigt um zu programmieren. Das ist nichts Schlechtes und auch nicht
abwertend gemeint. Viele Leute haben nicht das Zeug dazu. Sie können es
einfach nicht. Das ist so, wie manche Männer beim Bund beim Marschieren
einfach nicht den Schritt halten können.
Deswegen ist man nicht dumm oder so etwas.
Programmieren ist ganz einfach nicht das, was dir liegt oder jemals
liegen könnte. Du wirst es immer nur als Qual empfinden.
Nunja wenn man bestimmte Controller zugrunde legt, dann geht schon dass
man Bits "togglen" kann egal welchen Zustand sie vorher hatten, aber
welchen Zustand soll denn der Blinker bekommen wenn die Taste nicht
länger gedrückt wird?
Bei neueren Atmels bewirkt ein Schreiben einer logischen 1 auf den "PIN"
Port dass selbiger Ausgang den Zustand wechselt.
Nachdem hier nicht bekannt ist in welcher Umgebung sich das ganze
abspielt bleibt wohl nur das konventionelle Setzen von 0/1.
Aber das alles steht ja schon in dem Artikel den Karlheinz in der 1.
Antwort genannt hat.
Christian H. schrieb:
> int main(void) // besser "void main(void)" (siehe unten)> {
nicht ganz.
int main ist schon richtig.
So ist das im C-Standard vorgeschrieben, und so sollte man das auch
machen. Im C Standard gibt es ein paar erlaubte Formen für main(). Sie
unterscheiden sich in den Argumenten. Gemeinsam ist ihnen aber allen,
dass sie einen int retournieren.
Wenn in einem freestanding Environment der Returnwert keinen Sinn macht,
dann weiß das der Compiler, der auch um die Sonderrolle von main weiß
und baut sich das entsprechend zurecht.
@Karl heinz Buchegger:
Klar, kann man beides machen.
In einem PC-Programm ist "int main(void)" aber auch nicht 100%ig
korrekt. Es müsste "int main(int argv, char **argc)" heißen, obwohl
viele Compiler auch was anderes annehmen.
Ich mache es aber trotzdem bei einem µP so, da damit erkennbar ist, dass
main keine Rückgaben hat. Dass der Compiler auch die andere Variante
versteht und dann alles unnötige Weboptimiert, ist löblich.
Das ist in diesem Fall aber nur Kosmetik. Ansonsten stimmt ich Dir zu.
Christian H. schrieb:
> @Karl heinz Buchegger:>> Klar, kann man beides machen.
Nein.
Der springende Punkt ist:
man kann eben nicht.
Der Returnwert von main() ist immer int!
Wenn einzelne Compiler void main() akzeptieren, bedeutet das noch lange
nicht, dass es deswegen korrekt ist.
> In einem PC-Programm ist "int main(void)" aber auch nicht 100%ig> korrekt.
doch, ist es
> Es müsste "int main(int argv, char **argc)" heißen, obwohl> viele Compiler auch was anderes annehmen.
Im C-Standard steht explizit, welche Formen von main() erlaubt sind.
Wenn du mir nicht glaubst, dann lies im Standard nach.
Diese, und nur diese, Formen von main sind richtig.
Anders als bei anderen Funktionen steht es dir als Programmierer nicht
zu, dich darüber hinwegzusetzen. In einem freestanding Environment wirst
du damit durchkommen, weil main im Regelfall nie retourniert. Hast du
aber ein Runtimesystem, so schreibt dir dieses vor, wie es den Aufruf
machen wird und es liegt nicht in deiner Macht dies zu ändern. Der
Compiler kennt aber sowohl den Aufruf als auch die Argumentliste in
deinem main und kann das anpassen.
Karl heinz Buchegger schrieb:
> Im C-Standard steht explizit, welche Formen von main() erlaubt sind.
Kommt drauf an, welchen Standard du meinst. In C99, ist das korrekt
(habe gerade nachgeschaut).
Ich kenne aber noch die älteren Standards (hatte mit K&R angefangen). In
C90/C95 war "void main()", soweit ich auf die Schnelle sehen kann, noch
in Ordnung (oder gar einfach "main()").
Einigen wir uns darauf, dass ich teilweise noch nach pre-C99
programmiere.
Da ich zur Zeit C nur für µP nutze (und das auch nicht intensiv), ist
mir das wohl noch nicht aufgefallen.
Christian H. schrieb:
> Kommt drauf an, welchen Standard du meinst. In C99, ist das korrekt> (habe gerade nachgeschaut).> Ich kenne aber noch die älteren Standards (hatte mit K&R angefangen). In> C90/C95 war "void main()", soweit ich auf die Schnelle sehen kann, noch> in Ordnung (oder gar einfach "main()").
OK. Jetzt gehen wir in Haarspalterein, drum wird das auch mein letzter
Beitrag zum Thema:
Nein, in keinem ISO Standard war void main() je erlaubt.
Zu K&R Zeiten gab es noch keinen Standard und es herrschte Wildwuchs.
Dann kamen die Microsoft Compiler, die in ihren Dokubeispielen überall
void main() benutzten. Von da an war void main() nicht mehr zu halten
und verbreitete sich rasend schnell, obwohl es schon längst einen
Standard gab.
Ich kenne aber noch die älteren Standards (hatte mit K&R angefangen). In
C90/C95 war "void main()", soweit ich auf die Schnelle sehen kann, noch
in Ordnung (oder gar einfach "main()").
war es nicht so das ein main() ebend kein void main() sondern ein int
main() bedeutet hat?
Mir mar so ewas in erinnerung das jede variable( funktion ) ohne
Datentyp als int angenommen wird (worden ist).
Ok, ok.
Habe ich ja schon gesagt, ich war wohl falsch informiert. Ich mache es
so, wie ich geschrieben habe, schon länger und der gcc hat es nie
angemeckert.
Ob K&R ein Standard war oder nicht, ist nebensächlich.
Ich konnte das Problem inzwischen mit Hilfe von einigen Leuten hier so
lösen:
1
cntTicks++;
2
if(cntTicks==nFireTime)// Ist Variable <nFireTime> mal 10ms
3
{
4
repeatFire^=0x01;// Wechselt PortC.0 nach Zeit von 0 auf 1
5
cntTicks=0;
6
}
Das ganze läuft nun als Timer Interrupt und wird daher permanent
getoggelt.
Mein problem zur Zeit ist jedoch immer noch, das ich nicht weiß wie ich
das Togglen nur bei gedrückter Taste in zusammenhang mit meiner
Portbeschaltung auslöse.
Wie ich schon in einem anderen Beitrag gepostet habe, wird anhand einer
Tabelle ein Eingang einen bestimmten Ausgang zugeordnet:
In der momentanen Situation wird das Toggeln sofort ausgelöst sobald die
Variable nFire auf 1 ist.
Was ich jedoch gerne hätte ist das der Zustand nur bei gedrückter Taste
ausgelöst wird.
Leider komme ich da nicht ohne Hilfe weiter.
Vielleicht erbarmt sich ja jemand um Vorschläge, Tips, ...
danke!
Manfred W. schrieb:
> Was ich jedoch gerne hätte ist das der Zustand nur bei gedrückter Taste> ausgelöst wird.
Was hindert dich daran, die Bedingung im if zu erweitern, sodass
'gedrückte Taste' mit berücksichtigt wird?
Dauerfeuer soll also dann stattfinden
wenn( ( nfire ungleich 0 ) UND ( Taste gedrückt ) )
Karl heinz Buchegger schrieb:
> Dauerfeuer soll also dann stattfinden>>>> wenn( ( nfire ungleich 0 ) UND ( Taste gedrückt ) )
Das "Taste gedrückt" ist das Problem.
Die wird oben schon abgefragt:
Manfred W. schrieb:
> Karl heinz Buchegger schrieb:>> Dauerfeuer soll also dann stattfinden>>>>>>>> wenn( ( nfire ungleich 0 ) UND ( Taste gedrückt ) )>> Das "Taste gedrückt" ist das Problem.> Die wird oben schon abgefragt:>>
>> Das können ja mehrere sein und vor allem auch gleichzeitig.
Schon.
Aber nur eine davon wird die Feuertaste sein.
Und die fragst du halt noch ein 2-tes mal ab.
Karl heinz Buchegger schrieb:
> Aber nur eine davon wird die Feuertaste sein.>> Und die fragst du halt noch ein 2-tes mal ab.
Im Prinzip ja, aber die kann je nach ausgewählter Konfiguration
variieren.
Der Ausgang ist immer gleich. Die Feuertaste selbst nicht.
Manfred W. schrieb:
> Karl heinz Buchegger schrieb:>> Aber nur eine davon wird die Feuertaste sein.>>>> Und die fragst du halt noch ein 2-tes mal ab.>> Im Prinzip ja, aber die kann je nach ausgewählter Konfiguration> variieren.
Sogar dir hätte ich jetzt schon zugetraut, dass du eventuell auf die
Idee kommen könntest, das man sich dann halt bei der jeweiligen
Konfiguration einen Eintrag macht, der das beschreibt.
Schliesslich werden ja auch je nach Konfigration andere LEDs geschaltet
Es ist zum Haare raufen :-)