-
Hi mic,
jepp... dachte du hast meinen Beitrag nicht mehr gesehen, daher hatte ich ihn gelöscht... :-) Hat doch geklappt. Besten Dank dafür.
Kurze Frage zu den wohl wichtigsten Zeilen aus Deinem Beispiel:
DDRA &= ~3; // ADC0+1 auf Eingang und
PORTA |= 3; // PullUps einschalten
x=PINA & 3;
Du hast die Zeilen zwar gut dokumentiert, aber so richtig verstehen kann ich das noch nicht was da abläuft. Habe mir gerade in einem C-Tutorial die Bit-Operationen angeschaut, aber der "Versteh-Durchbruch" kam dadurch leider noch nicht.. :-)
Kannst Du vielleicht dazu noch ein paar erklärende Sätze verfassen? Wäre super...
thx
mfg
benx
-
Hallo
Zu den Ports: Ein Port wird über drei Register angesprochen. Das Datenrichtungsregister entscheidet zwischen Ein- oder Ausgangsfunktion, mit dem Portregister kann man den Port (und den PullUp) steuern, mit PIN liest man den Status des Ports ein.
Jeder Port hat 8 Pins die man immer gleichzeitig liest oder schreibt, jeder Pin entspricht dann einem Bit im Datenwort. Pin(Bit)0 hat die Wertigkeit 1, Pin7(Bit)7 hat 128. Im Beispiel mit den ADCs verwenden wir Pin0 und Pin1, das sind die Werte 1 und 2. Binär dargestellt sieht das so aus:
0b00000001 für Bit 0
0b00000010 für Bit 1
0b00000011 für beide Bits
Zuerst setzen wir die Datenrichtung für Port A. (Obwohl die Datenrichtung nach einem Reset Eingang sein sollte machen wir das zur Übung selbst) Eine 0 in dem entsprechenden Register definiert den Pin als Eingang, also müssen wir Bit0 und Bit1 löschen. Dazu verwenden wir eine Bitmaske mit der wir das aktuelle Datenrichtungsregister mit UND verknüpfen. Eine 1 in der Maske erhält dabei den alten Zustand, eine 0 löcht das betreffende Bit. Die Maske müßte also so aussehen: 0b11111100. Alternativ verwendet man hier gerne die Tilde ~ die das Einerkomplement(1 wird 0, 0 wird 1) erzeugt. Unsere Maske würde man dann so darstellen: ~0b00000011 (oder kurz ~3:) Und so setzt man dann schließlich das Datenrichtungsregister:
DDRA = DDRA & ~3; oder kurz DDRA &= ~3;
Da die Datenrichtung nun stimmt können wir den PullUp einschalten. Dazu müssen wir im Port das entsprechende Bit setzen. Da wir dabei die anderen Pins des Ports nicht verändern wollen verwenden wir wieder eine Maske, die diesmal allerdings mit ODER verküpft wird. Ein 1 in der Maske setzt dann den Pin auf High (PullUp ein), eine 0 ändert hingegen nichts:
PORTA |= 3;
Nun können wir den Status des Port einlesen. Da uns nur Pin0 und Pin1 interessieren blenden wir die anderen Bits im Wert aus, natürlich wieder mit einer UND-Maske:
x=PINA & ~3;
Ächz, reicht das schon als Erklärung?
Gruß
mic
-
Also mir reichts :)
Ich programmiere zwar schon eine Zeitlang, aber C ist für mich dennoch eine neue Programmiersprache, da sind so Hinweise wie |=... OR und &=... AND ziemlich hilfreich um den Code zu verstehn. Ich wollte gestern schon fast ein neues Thema starten wegen so einem Ausdruck :P
-
Eine Frage hätte ich noch zu dem Code, es wird ständig uint8_t und uint16_t verwendet. Heißt das Unsigned Integer 8/16 bit?, für was steht das "t" und gibt es auch signed Integers in dem Format?
Ist dieser Variablentyp in irgendeiner Library definiert, oder ein Standard?
-
Hallo
Wo das festgelegt wird (GCC?) weiß ich auch nicht. Wie du richtig vermutest, uint steht für unsigned integer:
int8_t - char
uint8_t - unsigned char
int16_t - integer
uint16_t - unsigned int
Das t steht vielleicht für Type? Ich weiß es nicht...
Gruß
mic