PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino -wofür 16-Bit int?



tholan
06.03.2013, 13:24
Hallo liebe Roboter :)
Ich versuche mich gerade an einem "Arduino Uno smd"
und habe einen Taster an "digital pin 8" (PB0) angeschlossen.
Ich wundere mich etwas über den mit der Arduino IDE mitgelieferten Beispielcode
zum Abfragen eines Portpins (Button.ino).
Die globale Deklaration und Initialisierung sieht hier so aus:


const int buttonPin = 2;

Danach wird noch eine Variable für einen einzelnen Portzustand
wieder in 2Byte global deklariert und initialisiert:


int buttonState = 0;

Werden hier wirklich 2 Byte, bzw. 16 Bit Variablenplatz im RAM
einer 8 Bit MCU (Atmega328 ) für je ein einzelnes Bit genutzt?

ichbinsisyphos
06.03.2013, 16:49
Gute Frage. Es gibt eine boolean Datentyp, der nur 1 byte belegt. Oder gleich den Datentyp "Byte". Schonmal probiert?

Klebwax
06.03.2013, 19:09
Gute Frage. Es gibt eine boolean Datentyp, der nur 1 byte belegt. Oder gleich den Datentyp "Byte". Schonmal probiert?

Das hilft bei einer fertigen Library wenig. Außerdem:


6.2.5. Datentyp bool
C sieht keinen eigenen Datentyp für logische Werte vor.
Logische Ausdrücke und Vergleiche liefern stattdessen einen Wert vom Typ int:

Solange das RAM nicht knapp wird, ist doch alles gut.

MfG Klebwax

ichbinsisyphos
06.03.2013, 19:40
Aber beim Arduino gibts einen "boolean"-Typ der 1byte Länge hat, und den Typ "Byte". Ob die Bibliotheken das annehmen und womit sie intern arbeiten ist eine andere Frage, aber 16bit für einen 1bit-Wert das wär wirklich ziemlich schwachsinnig.

edit: ja, laut "O'Reilly Arduino Cookbook" kann man zum Auslesen und Beschreiben der digitalen pins boolean-Werte nehmen.

tholan
06.03.2013, 21:02
Das es das Format "Byte" gibt, ist mir bekannt.
Eigentlich kenne ich das vom avr-gcc als "uint8_t".
Das ist auch eindeutiger, da "Byte" nichts darüber aussagt,
ob das Format vorzeichenbehaftet ist (was immer das ..._t bei uint8_t am Ende auch bedeuten mag.)
Ich habe extra den Beispielcode zitiert und meine Frage ist eigentlich auch,
ob es einen, mir nicht zugänglichen Sinn hat, hier 16 statt 8 Bit zu bemühen.

Solange das RAM nicht knapp wird, ist doch alles gut.
Ich hab noch keine Ahnung, wie knapp das werden wird,
aber das Problem ist ja nicht nur der RAM Speicher.
Der Mega328 ist doch nur ein 8-Bitter.
Der muß doch ziemlich unnötige Verrenkungen machen um mit 16-Bit Variablen
umzugehen, wenn es nicht nötig ist.
Ich benutze ja keine RISC-MCU, um sie dann mit ungeschicktem
Code zu kastrieren :) .

Das habe ich mittlerweile in der Arduino Referenz gefunden:

On the Arduino Uno (and other ATMega based boards) an int stores a 16-bit (2-byte) value.
Ein paar Zeilen weiter:

The Arduino takes care of dealing with negative numbers for you,
so that arithmetic operations work transparently in the expected manner.
There can be an unexpected complication in dealing with the bitshift right operator (>>) however.

http://arduino.cc/en/Reference/Int
Logisch, wenn ich das Vorzeichenflag mitschiebe, zudem wirds ja bei nem 8-Bitter
vermutlich auch keinen Überlauf unter das LSBit des oberen Bytes eines int geben :) .
Naja, das wird mir allerdings langsam suspekt.
Bitoperationen sind ja nun mein Hobby :) .

ichbinsisyphos
06.03.2013, 21:17
Ich glaub, dass bei der Arduino-Dokumentation vieles so ist, wie es ist, weil man die typische Zielgruppe möglichst nicht mit zu vielen unterschiedlichen Konzepten abschrecken will.

Nur zum Zwischenspeichern von pin states spricht meiner Meinung nach garnichts gegen 8bit. Wie gesagt, der Herr O'Reilly schreibt da booleans (http://arduino.cc/en/Reference/BooleanVariables) rein und raus. Wenn du auf den Wert irgendwelche weiteren Operationen anwenden willst, musst du dir das halt im Detail ansehen.

edit
...
typedef uint8_t boolean;
typedef uint8_t byte;

void init(void);

void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);

...

Button.h verwendet aus irgendwelchen Gründen das C++-eigene "bool", auch 1 byte.

tholan
06.03.2013, 23:47
Ja, ich danke Dir.
Mein "uint8_t" ist ja da, hatte ich noch garnicht probiert.
Werd morgen mal gucken, ob ich auch direkt auf die Pinregister zugreifen kann,
ala: DDRD = 0xf0;
PORTD |= (1<<4);
usw;
Ich lese halt auch gerne mal im Datenblatt,
aber das wird bestimmt ein schönes Durcheinander mit den Pinbezeichnungen.
PB0 ist z.B. "digital pin 8".
Na ja, wozu gibts "#define"? :)

Wenn ich das Beste aus zwei Welten im Arduino unter einen Hut bringen kann,
bin ich jedenfalls glücklich.
Danke. :)

oderlachs
07.03.2013, 09:19
......

Der Mega328 ist doch nur ein 8-Bitter.
Der muß doch ziemlich unnötige Verrenkungen machen um mit 16-Bit Variablen
umzugehen, wenn es nicht nötig ist.
Ich benutze ja keine RISC-MCU, um sie dann mit ungeschicktem
Code zu kastrieren :) .

...

....war das nicht mit dem "8-Bitter" nur was in Sachen Befehlsbus...?? also max 255 Befehle...?? Das hat doch nix mit Variablenlängen usw. zu tun denke ich, aber Prozessortopologie ist schon ein paar Jahrzehte her bei mir.

Gerhard

oberallgeier
07.03.2013, 10:55
... "8-Bitter" nur was in Sachen Befehlsbus...?? also max 255 Befehle ...Nein. 8Bitter ist der m328 weil er ein Rechenwerk mit (nur) 8 Bit Breite hat. Daher kann er fast ausnahmslos nur jeweils ein Byte mit einem anderen zusammen verrechnen, addieren, multiplizieren etc. 1) Ein word wird dann eben mit den üblichen Tricks verrechnet wie Carry etc. Mit dem Befehlsbus hat das nix zu tun. Ausserdem könnte er 255 Befehle haben - hat aber nur rund die Hälfte, weil es ein RISC-Prozessor ist (Reduced Instruction Set Computer), also einer Designphilosophie folgt, bei der vorzugsweise die schnellsten verfügbaren Befehle benutzt werden. Übrigens ist der Befehlsbus bei seiner Harvardarchitektur nicht mehr das Nadelöhr, das er noch bei der Von-Neumann-Architektur gewesen ist.

1) Leicht anders funktioniert der bei vielen megas integrierte Hardware-Muliplizierer.

oderlachs
07.03.2013, 11:10
Danke JoeamBerg , wieder was dazugelernt, bzw. Speicher im Kopf aufgefrischt....Refresh @ll ;)

Gerhard

oberallgeier
07.03.2013, 11:55
Danke JoeamBerg , wieder was dazugelernt ...Ich freu mich ja, wenn ich mal denke, dass ich irgendetwas weiß. Und Du wusstest das ja auch schon mal.

Im Übrigen ist es nicht so ganz nachvollziehbar, was der Threadersteller meint mit
... benutze ja keine RISC-MCU, um sie dann mit ungeschicktem Code zu kastrieren ...... denn in meinem PingPong in C habe ich ja in word-variablen bitweise geschaltet. Das geht recht easy, auch wenn das Compilat dann ein paar Zeilen mehr macht - was solls.

Hier meine Bitoperation im Word-Feld:
L[rPr] |= ((uint16_t)1<<4); // Setze LEDBit rPr (rechtes Poti)


Im Einzelnen läuft das so:
...
volatile uint16_t L[20]; // LED-Reihe 1 bis 10, Rest ist Dummy
...
// Aus dieser Codezeile
L[rPr] |= ((uint16_t)1<<4); // Setze LEDBit rPr (rechtes Poti)

// macht der Compiler dann diesen Maschinencode
L[rPr] |= ((uint16_t)1<<4); // Setze LEDBit rPr (rechtes Poti)
404: e0 91 b0 00 lds r30, 0x00B0
408: f0 e0 ldi r31, 0x00 ; 0
40a: ee 0f add r30, r30
40c: ff 1f adc r31, r31
40e: ef 54 subi r30, 0x4F ; 79
410: ff 4f sbci r31, 0xFF ; 255
412: 80 81 ld r24, Z
414: 91 81 ldd r25, Z+1 ; 0x01
416: 80 61 ori r24, 0x10 ; 16
418: 91 83 std Z+1, r25 ; 0x01
41a: 80 83 st Z, r24

HeXPloreR
07.03.2013, 11:59
Hallo,

um nochmal auf die Eingangsfrage zurück zu kommen: Das hört sich nach einer Overlay-Technik an, wo mit es dem Programmierer einfacher gemacht werden soll, die beiden Ports abzufragen. Würde ja gut ins Konzept der Arduions passen ;)

ichbinsisyphos
07.03.2013, 14:31
Auf Wikipedia les ich grad, dass 8-bit-Prozessoren trotzdem meist 16-bit-Register haben, zur Verarbeitung dann halt 2 Takte brauchen.

Also so schlimm werden die Tricks nicht sein, die nötig sind um auf 8-Bit-Architekturen mit 16-bit-Zahlen zu rechnen.