Hallo, wie kann man follgendes schreiben: fals am PINC1 ein high anliegt und an PINB1 ein low soll PORTD1 high sein mein kläglicher Versuch sieht so aus: if((PINC & (1 << PINC1)) && (PINB & !(1 << PINB1))){ PORTD |= (1<<PD1); Danke für die Hilfe vG Rocco
Sieht ganz gut aus, aber:
1 | (PINB & !(1 << PINB1)) |
muss
1 | !(PINB & (1 << PINB1)) |
heissen. Außerdem fehlt ein "}" (bzw. das "{" ist zu viel), die Formatierung allgemein ist verbesserungswürdig.
Rocco L. schrieb: > Hallo, > > wie kann man follgendes schreiben: > > fals am PINC1 ein high anliegt und an PINB1 ein low soll PORTD1 high > sein > > mein kläglicher Versuch sieht so aus: > if((PINC & (1 << PINC1)) && (PINB & !(1 << PINB1))){ PORTD |= (1<<PD1); > Der Knackpunkt liegt darin, dass du die Formulierung
1 | an PINB1 ein low |
umformulierst in
1 | an PINB1 kein high |
Warum ist das so? WEil du mittels if( iregendetwas & ( 1 << Pinnummer ) ) aubfragst ob etwas high ist. Ob dieses etwas low ist, ist dann einfach die gegenteilige Bedingung if( !( irgendetwas & ( 1 << Pinnummer ) ) aber die 'Phrase'
1 | irgendetwas & ( 1 << Pinnummer ) |
die musst du so wie sie ist erhalten. Denn die isoliert dir dieses eine bestimmte Bit aus dem irgendetwas. Und erst dann, wenn du dieses Bit hast, kannst du entscheiden und abfragen ob dieses Bit jetzt 0 oder nicht 0 sein soll.
Danke für die schnellen antworten Unb besonderen Dank and die schöne Erklährung von Herrn Buchegger. Diese "irgendwas" Erklährungen liegen mir auch total ;-) Nein erlich - vielen Dank, habe es glaube verstanden und versuche es gleich mal umzusetzen.
irgend was passt trotzdem noch nicht... Ziel sol es sein einen einfachen Motor anzusteuern. Die H-Brücke für den Motor hängt an D0 und D1. Der Atmega bekommt seinen Befehl von einem Weiteren Controler der ihm sagt in welche Richtung der Atmega den Motor drehen lassen soll. Bevor das alles los geht gibt es eine Initialisierung wo der Motor so lange Richtung Kältebad fährt bis ein Arm einen Taster auslöst. Damit soll der Atmega wissen das der Motor nun im Kältebad ist. Also drehe so lange nach links bis B0 ein high bekommt.
1 | //C0 cw in vom Mainframe
|
2 | //C1 ccw in vom Mainframe
|
3 | //
|
4 | //B0 Taster Kältebad
|
5 | //B1 Taster Wärmebad
|
6 | //
|
7 | //D0 cw out zum Motor -> Richtung Kältebad
|
8 | //D1 ccw out zum Motor -> Richtung Wärmebad
|
9 | //D2 LED on als Anzeige das mit dem Beladen begonnen werden kann
|
10 | |
11 | #include <inttypes.h> |
12 | #include <avr/io.h> |
13 | #include <avr/interrupt.h> |
14 | //#define F_CPU 1000000UL
|
15 | //#include <util/delay.h>
|
16 | #include <stdint.h> |
17 | |
18 | |
19 | int main(void){ |
20 | |
21 | DDRB = 0xff; //Ausgänge |
22 | DDRD = 0xff; //Ausgänge |
23 | DDRC = 0x00; //Eingänge |
24 | |
25 | while(1){ |
26 | //Initialiserung - ins Kältebad fahren
|
27 | PORTD |= (1<<PD0); |
28 | // Prüfen ob das Kältebad erreicht wurde
|
29 | if(PINB & (1 << PINB0)){ //fals Taster am Kältebad gedrückt ist |
30 | PORTD &= ~(1<<PB0); //cw off -> Motor aus |
31 | PORTD |= (1<<PD2); //LED ein |
32 | break; |
33 | }
|
34 | if (!(PINB & (1 << PINB0))){ |
35 | PORTD &= ~(1<<PD2); //LED aus |
36 | break; |
37 | }
|
38 | //end if
|
39 | } //Ende while |
40 | |
41 | // Hauptroutine###############################################################
|
42 | while(1){ |
43 | |
44 | //Start des Programms an sich mit einem C1 = logisch 1 vom Mainframe
|
45 | //und PINB1 = logisch 0
|
46 | //fals ccw vom Mainframe und Taster Wärmebad nicht gedrückt -> ccw zum Motor
|
47 | if((PINC & (1 << PINC1)) && !(PINB & (1 << PINB1))){ PORTD |= (1<<PD1);} //ins Wärmebad fahren |
48 | //fals ccw vom Mainframe und Taster Wärmebad gedrückt -> nichts machen
|
49 | if((PINC & (1 << PINC1)) && !(PINB & (1 << PINB1))){ PORTD &= ~(1<<PD1);} //nichts tun |
50 | |
51 | //fals cw vom Mainframe und Taster Kältebad nicht gedrückt -> cw zum Motor
|
52 | if((PINC & (1 << PINC0)) && !(PINB & (1 << PINB0))){ PORTD |= (1<<PD0);} //ins Kältebad fahren |
53 | //fals cw vom Mainframe und Taster Kältebad gedrückt -> nichts machen
|
54 | if((PINC & (1 << PINC0)) && !(PINB & (1 << PINB0))){ PORTD &= ~(1<<PD0);} //nichts tun |
55 | |
56 | } // Ende while |
57 | |
58 | return 0; |
59 | |
60 | }
|
Was jetzt genau dein Problem ist, hab ich auch noch nicht heraus. Da muss ich deine Fehlerbeschreibung noch weiter studieren. Und bitte: Sag nicht 'da passt noch irgendewtwas noch nicht', denn darunter kann sich auf dieser Seite des Monitors keiner etwas vorstellen. Aber eines gleich mal vorweg
1 | while(1){ |
2 | //Initialiserung - ins Kältebad fahren
|
3 | PORTD |= (1<<PD0); |
4 | // Prüfen ob das Kältebad erreicht wurde
|
5 | if(PINB & (1 << PINB0)){ //fals Taster am Kältebad gedrückt ist |
6 | PORTD &= ~(1<<PB0); //cw off -> Motor aus |
7 | PORTD |= (1<<PD2); //LED ein |
8 | break; |
9 | }
|
10 | if (!(PINB & (1 << PINB0))){ |
11 | PORTD &= ~(1<<PD2); //LED aus |
12 | break; |
13 | }
|
14 | //end if
|
15 | } //Ende while |
Frag nicht zuviel ab! Das else ist schon erfunden. Wenn ein bestimmtes Bit nicht 1 ist, dann muss es 0 sein. Eine andere Möglichkeit gibt es nicht! Anstelle das du da haufenweise Bedingungen abprüfst, die man bei der Fehlersuche alle wieder einzeln untersuchen und überlegen muss, schreib doch einfach else, dann ist nämlich alles klar.
1 | while(1){ |
2 | //Initialiserung - ins Kältebad fahren
|
3 | PORTD |= (1<<PD0); |
4 | // Prüfen ob das Kältebad erreicht wurde
|
5 | if(PINB & (1 << PINB0)){ //fals Taster am Kältebad gedrückt ist |
6 | PORTD &= ~(1<<PB0); //cw off -> Motor aus |
7 | PORTD |= (1<<PD2); //LED ein |
8 | break; |
9 | }
|
10 | else { |
11 | PORTD &= ~(1<<PD2); //LED aus |
12 | break; |
13 | }
|
14 | //end if
|
15 | } //Ende while |
und dann sieht man jetzt nämnlich auch: Egal ob das Bit HIgh oder Low ist, du breakst dich in jedem Fall aus der SChleife raus. In diesem Fall wäre es überhaupt besser, auf das break zu verzichten. Mach es doch weniger kompliziert so
1 | LED ein |
2 | Motor ein |
3 | |
4 | while( Endposition nicht erricht ) |
5 | Nichts tun (abwarten und Tee trinken) |
6 | |
7 | Motor aus |
8 | LED aus |
das ist einfach, simpel, überschaubar und man muss nicht dauernd um die Ecke denken, wann und wo jetzt welche Schleife aus welchem Grund verlassen wird. Zudem entspricht das besser dem, wie man wohl als Mensch an die Sache rangehen würde.
1 | if(PINB & (1 << PINB0)){ //fals Taster am Kältebad gedrückt ist |
2 | PORTD &= ~(1<<PB0); //cw off -> Motor aus |
3 | PORTD |= (1<<PD2); //LED ein |
4 | break; |
5 | }
|
6 | if (!(PINB & (1 << PINB0))){ |
7 | PORTD &= ~(1<<PD2); //LED aus |
8 | break; |
9 | }
|
Die beiden "if" haben genau komplementäre Bedingungen und in beiden Code-Blöcken steht ein "break". Also wird die umgebende Endlosschleife nur einmal durchlaufen (außer der Pin ändert genau dazwischen den Zustand). Wohl kaum das, was du eigentlich haben wolltest.
1 | //fals ccw vom Mainframe und Taster Wärmebad nicht gedrückt -> ccw zum Motor
|
2 | if((PINC & (1 << PINC1)) && !(PINB & (1 << PINB1))){ PORTD |= (1<<PD1);} //ins Wärmebad fahren |
3 | //fals ccw vom Mainframe und Taster Wärmebad gedrückt -> nichts machen
|
4 | if((PINC & (1 << PINC1)) && !(PINB & (1 << PINB1))){ PORTD &= ~(1<<PD1);} //nichts tun |
In den Kommentaren stehen unterschiedliche Bedingungen, die if-Bedingungen sind aber identisch. Wie passt das zusammen?
1 | //fals cw vom Mainframe und Taster Kältebad nicht gedrückt -> cw zum Motor
|
2 | if((PINC & (1 << PINC0)) && !(PINB & (1 << PINB0))){ PORTD |= (1<<PD0);} //ins Kältebad fahren |
3 | //fals cw vom Mainframe und Taster Kältebad gedrückt -> nichts machen
|
4 | if((PINC & (1 << PINC0)) && !(PINB & (1 << PINB0))){ PORTD &= ~(1<<PD0);} //nichts tun |
Dito.
ok, habe das mal so weit umgesetzt. das mit dem if und else und dem break verstehe ich auch. Blöd ist nur das Zeile 27 doch dazu führen müste das der Motor erst mal in eine Richtung los dreht so lange der Positionstatster nicht erreicht wurde..aber er dreht gar nicht erst los:
1 | //Initialiserung - ins Kältebad fahren
|
2 | PORTD |= (1<<PD0); <<<<<<<<<<<DAS HIER FUNKTIONIERT NICHT |
3 | // Prüfen ob das Kältebad erreicht wurde
|
4 | if(PINB & (1 << PINB0)){ //fals Taster am Kältebad gedrückt ist |
5 | PORTD &= ~(1<<PB0); //cw off -> Motor aus |
6 | PORTD |= (1<<PD2); //LED ein |
7 | //break;
|
8 | }
|
9 | else{ |
10 | //if (!(PINB & (1 << PINB0))){
|
11 | PORTD &= ~(1<<PD2); //LED aus |
12 | //break;
|
13 | }
|
14 | //end if
|
15 | } //Ende while |
Den 2ten Teil von Stefan verstehe ich nicht so ganz... es sind doch unterschiedliche dinge die ich in den if Bedingungen möchte... Kanst Du mir das genauer erklären wo ich da falsch denke.
Wie Stefan schon schrieb. Bei dem 2.ten Teil des Programms hast du dich durch übermässige unübersichtliche Vergleiche mächtig selbst ausgetrickst. Das würde ich dir empfehlen: SChmeiss es weg und schreib es nochmal neu. Aber trenne diesmal die Dinge. In deinen Abfragen kommt immer wieder der Teil (falls ccw vom Mainframe vor). Daskann man auch durchaus herausziehen
1 | while( Endlos ) { |
2 | |
3 | if( ccw vom Mainframe ) { |
4 | if( Taster Kältbad gedrückt ) |
5 | mach was |
6 | else // Taster nicht gedrückt |
7 | mach was anderes |
8 | }
|
9 | |
10 | if( cw vom Mainframe ) { |
11 | if( Taster Kältebad gedrückt ) |
12 | mach was |
13 | else
|
14 | mach was anderes |
15 | }
|
16 | }
|
tricks dich nicht selber mit übermässig komplexen Abfragen aus! Ein gutes Programm ist nicht eines, bei dem möglichst viel in einer Zeile steht und die man erst 2 Minuten studieren muss um sie zu verstehen und zu entschlüsseln! Ein gutes Programm liest sich wie eine Geschichte und ist leicht zu verstehen.
Rocco L. schrieb: > Blöd ist nur das Zeile 27 doch dazu führen müste das der Motor erst mal > in eine Richtung los dreht so lange der Positionstatster nicht erreicht > wurde..aber er d reht gar nicht erst los: zeig bitte alles! hast du die SChleife noch? WIe sieht die jetzt aus. Wie ich weiter oben schon gesagt habe: Formuliere das alles um! Dein Programm ist viel zu kompliziert und unübersichtlich und die Komplexität erschlägt dich im Moment noch
1 | ...
|
2 | |
3 | int main() |
4 | {
|
5 | ....
|
6 | |
7 | //Initialiserung - ins Kältebad fahren
|
8 | |
9 | PORTD |= (1<<PD0); // Motor ein |
10 | PORTD &= ~(1<<PD2); // Led aus |
11 | |
12 | while( !(PINB & (1 << PINB0)) ) // solange Endposition nicht erreicht |
13 | ; // nichts tun und den Motor fahren lassen |
14 | |
15 | PORTD &= ~(1<<PD0); // Motor aus |
16 | PORTD |= (1<<PD2); // Led ein |
17 | |
18 | while( 1 ) { |
19 | .... die eigentliche Steuerung |
20 | }
|
21 | }
|
Ich werde dem Ratschlag folgen und es noch mal neu probieren. Übung macht je den Meister - und mir kann sie ja nicht schaden. Danke für die Hilfe und bis dann. fG Rocco
Karl heinz Buchegger schrieb: > ; // nichts tun und den Motor fahren lassen ^^das geht? ich meine, ist das C? Möchte noch sagen das ich mir alles selber angelesen habe und es nicht gelernt habe... es soll also keine Verbesserung sein sondern wirklich eine interessierte Frage
Rocco L. schrieb: > Karl heinz Buchegger schrieb: >> ; // nichts tun und den Motor fahren lassen > > ^^das geht? ich meine, ist das C? Ja klar. C kennt die leere Anweisung, also einen einzelnen ; Den Fehler macht wohl jeder mal
1 | if( Bedingung ) ; |
2 | Anweisung die von der Bedingung abhängen soll |
und der einzelne Strichpunkt am Zeilenende vom if verändert die logische Struktur :-) wenn es dir mehr hilft, dann schreibs halt so
1 | while( !(PINB & (1 << PINB0)) ) { // solange Endposition nicht erreicht |
2 | // nichts tun und den Motor fahren lassen
|
3 | }
|
Karl heinz Buchegger schrieb: > wenn es dir mehr hilft, dann schreibs halt so
1 | > while( !(PINB & (1 << PINB0)) ) { // solange Endposition nicht erreicht |
2 | > // nichts tun und den Motor fahren lassen |
3 | > } |
Ggf. hilft es auch dem Compiler. Bei neueren GCC-Versionen bekommt man bei der Variante mit dem Semikolon eine (meiner Meinung nach unsinnige) Warnung, die einem vorschlägt, stattdessen die Klammern zu verwenden.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.