Guten morgen habe mal ne Frage und zwar kann ich ja mit PORTD &= ~(1 << PD3); //PD3 auf high PORTD &= ~(0 << PD2); //PD2 auf low PORTD &= ~(1 << PD1); //PD1 auf high einzelne Ports setzten, aber wie kann ich einen vereinzelten Port abfragen ? ich kenn das bisher nur mit if(PORTA == 0xFE)..... bzw. if(PORTA == 0b11111110)..... habe es schon mit if(PORTA |= ~(1 << PA0)) und if(PORTA &= ~(1 << PA0)) vrsucht, aber beides geht nicht, auch wenn ich anstellle der 1 ne 0 setzte, Kennt einer von euch die richtige Syntax für den befehl ?? weil mit if(PORTA == 0xFE)..... bzw. if(PORTA == 0b11111110)..... beziehe ich ja auch immer die anderen anschlüsse eines portes mit in die bedingung, was ich nicht machen möchte, klar ich könnte es über ne switch-case bedingung machen, aber das für jeden port, macht den source code auch nicht übersichtlich (kurz und knapp sollte er sein ) :) !! Dank euch
> PORTD &= ~(1 << PD3); //PD3 auf high Eher: PORTD |= (1 << PD3); > PORTD &= ~(0 << PD2); //PD2 auf low Eher: PORTD &= ~(1 << PD2); > wie kann ich einen vereinzelten Port abfragen ? Ich glaube, Du solltest Dich erst einmal damit beschäftigen, was die Befehle, die Du benutzt, wirklich bedeuten: Du hast einen PortD mit den Bits xxxxxxxx. Der Klammerausdruck (1 << PD3) setzt das letzte Bit und schiebt es an die Position der Wahl: 00000001 wird zu 00001000. Der Operator |= macht nun ein logisches Oder von Port und dem anderen Byte und schreibt es wieder in den Port. foo |= bar ist eine Kurzschreibweise von foo = foo | bar D.h. bei PORTB |= (1 << PB3) wird das eine Bit auf jeden Fall gesetzt, die anderen bleiben, wie sie sind: xxxxxxxx | 00001000 = xxxx1xxx Zum Zurücksetzen invertiert man mit der Tilde ~ den Ausdruck und macht dann ein logisches UND: xxxxxxxx & 11110111 = xxxx0xxx > habe es schon mit > if(PORTA |= ~(1 << PA0)) und if(PORTA &= ~(1 << PA0)) Vorsicht! |= und &= verändern den Port! Erst einmal solltest Du Dir sicher sein, über welches Register Du bei Deinem µC auf Eingangsports zugreift. Beim AVR z.B. wäre das nicht PORTA, sondern PINA. Die Abfrage wäre also z.B.: if (PINA & (1 << PA0)) ... Das einfache '&' bildet nur das logische UND, ohne dabei etwas zu verändern. Bitte in Zukunft vor dem blinden Übernehmen von fremdem Code und wildem Ausprobieren erst mit den übernommenen Sprachkonstrukten beschäftigen! Sonst funktioniert es vielleicht durch Zufall im Einzelfall und später läuft man in noch viel größeres Chaos ...
Ja klar meinte ja auch PINA, hatte es nur in der Eile hier so falsch geschrieben,habe es im programm auch mit PINA stehen.... |= (bitor), || (log oder) ... ist mir auch bekannt,nur das mit der ~ war mir neu, super,also Besten dank
Hi, bin nun endlich zuhause und konnte das mal ausprobieren, geht aber leider nicht.... habe da noch was anderes gefunden, was aber nur unter CodeVision funktioniert nicht aber beim programmers notepad, hier mein code ...... //if (PIND & (1 << PD0)) //if(PIND.0 == 1) if(PIND == 0b11111110) //das geht { if(i == 0) .......... als einzigstes funktioniert if(PIND == 0b11111110) //das geht.... ist ja auch klar, nur leider keines der anderen beispiele.... ich weiss sind für euch echt doof klingende fragen, aber wenn man grad mal mit uc-proggen angefangen ist, ist man dankbar über jede hilfe die man bekommt und in diesem forum wird einem ja auch echt gut geholfen, hab bisher ne ganze menge von euch hier gelernt, also gebt mich nicht auf :) dann kann ich später auch mal endlich jemandem (neuling) vielleicht helfen ;) also wie soll's an der stelle aussehen ?
> als einzigstes funktioniert
Logisch.
Ist ja auch ganz was anderes.
//if (PIND & (1 << PD0))
Wie sieht hier die Maske aus
1 << PD0
Also: da nehmen wir eine 1 binaer 00000001
und die wird PD0 mal
nach links geschoben.
PD0 hat den Wert 0.
Also wird 0 mal geschoben.
Das Ergebnis binaer 00000001
//if(PIND.0 == 1)
Hier wird ganz einfach geprueft ob das Bit 0
im PIND eine 1 ist. Im Grunde ist das ganz genau
dieselbe Abfrage wie PIND & (1 << PD0).
Auch hier wird geprueft ob Bit 0 eine 1 enthaelt.
Ueber die Maske werden alle anderen Bits definitiv
auf 0 gesetzt (das macht die & Verknuepfung) und
das Endergebnis haengt dann nur noch vom Bit 0 ab.
Das hier
if(PIND == 0b11111110)
ist aber ganz was anderes. Hier muss Bit 0 eine
0 enthaelten, damit der Vergleich wahr wird.
Wenn letzteres bei Dir geht und Dein Schalter am Bit 0
haengt, dann hast Du ihn gegen Masse geschaltet. Das
heist: Ist der Schalter nicht betaetigt, dann siehst Du
am Pin eine 1. Ist der Schalter betaetigt, dann ist
dort eine 0.
So. Der erste Schritt ist (wie immer) mal dafuer zu
sorgen, dass nur das interessierende Bit uebrig bleibt
und alle anderen Bits auf einen defineirten Wert kommen
(unabhaengig davon ob extern an moeglichen Schaltern
gedreht wurde). D.h. aber auch, wir muessen sie ausmaskieren.
Was Du also brauchst ist eine Moeglichkeit in einem Byte
alle Bits, bis auf das interessierende zu loeschen (auf
0 zu setzen). Ein binaeres UND macht das wunderbar.
Bei Wert & Maske
bleiben nur die Bits in 'Wert' heil bei denen an der
korrespondierenden Stelle in 'Maske' eine 1 steht. Dort
wo in 'Maske' eine 0 steht, wird im Endergebnis mit
Sicherheit auch eine 0 auftauchen, egal ob jetzt 'Wert'
an dieser Stelle eine 1 oder eine 0 enthaelt.
D.h.
PIND & 0b00000001
laesst von PIND nur das Bit 0 uebrig, alle anderen Bits
sind definitiv auf 0 gesetzt. D.h. das Endergebnis dieser
UND Verknuepfung kann nur 0 (wenn Bit 0 gleich 0) oder 1
(Wenn Bit 0 gleich 1 ) ist. Ist Bit 0 gleich 0, dann war
Dein Taster gedrueckt.
Also alles zusammengesetzt
if( ( PIND & 0b00000001 ) == 0 )
{
/* Taster gedrueckt */
}
Anstatt dieses binaeren Monsters, kann man dann noch
schreiben
if( ( PIND & ( 1 << PD0 ) ) == 0 )
{
/* Taster gedrueckt */
}
Da ja der Ausdruck 1 << PD0 und 0b00000001
gleichwertig sind.
(1<<PD0) verschiebt die 1 um PD0 Stellen. Müsste also, sofern PD0 = 0 ist, hinterher so aussehen: 0b00000001 PIND & (1<<PD0) fragt also ab, ob sich eine 1 an der Stelle 0 befindet. Annahme: PIND = 0b01100100 dann ist PIND & (1<<PD0) = 0b00000000 (bitweise Und-Verknüpfung) Ergebnis des Vergleichs: 0, also nicht wahr. Annahme: PIND = 0b01100101 dann ist PIND & (1<<PD0) = 0b00000001 Ergebnis des Vergleichs: 1, somit !=0, also wahr. mit dem (1<<PDx) maskiert man das x-te Bit eines Bytes aus. Der Vergleich unter CodeVisio mit PIND.0 == 1 ist eigentlich nichts anderes, ausser, dass die 1 wirklich nur den Zustand eines Bits beschreibt, und nicht wie bei AVR-gcc ein komplettes Byte. Dein Vergleich (PIND == 0b11111110) funktioniert nur, wenn wirklich nur dieses Bitmuster am PIND anliegt; liegt ein weiteres Bit auf 0 ist er hinfällig. Um herauszufinden, ob der angenommene Taster an PIND.0 betätigt ist, und den Pin auf Masse (log. 0) herunterzieht, muß man ein bißchen binäre Logik anwenden: Vorraussetzung: Taster gilt als betätigt, wenn PIND.0==0. 1. Fall: if (~PIND & (1<<PD0)) ... 2. Fall: if (!(PIND & ~(1<<PD0))) ... Vielleicht hilft dir das noch: bei jeder Operation in C wird ein Wert zurückgegeben. Alle Werte ausser 0 gelten in einer Abfrage als wahr. So kann man auch ziemlich einfach feststellen, ob irgendwas != 0 ist: if (x) Aktion für x!=0; else Aktion für x ==0; andersherum: if (!x) Aktion für x == 0; else Aktion für x!=0; Schönen Gruß Rahul Gruß Rahul
Super, habe es verstanden, besten Dank an Dich Karl Heinz Buchegger. wirklich gut und ausführlich erklärt, vielen vielen Dank !!! Das mit den Tatsern an Masse oder +5V wusste ich auch nicht, aber ist ja logisch, das dann jedes mal was anderes am port hängt, habe ich mir aber bisher keine gedanken drüber gemacht !! Also nochmals besten Dank !!! Erstelle mir aus dem ganzen Basiswissen über uc - programmierung grad ne "Formelsammlung", welche dn Einstig erleichtern soll, werde sie natürlich veröffentlichen, wenns fertig ist !! Bis dann
Ist das wirklich notwendig? Hier steht doch alles: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
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.