Forum: Mikrocontroller und Digitale Elektronik Bit und Bytemanipulation mit Arduino


von ArduinoNeuling (Gast)


Lesenswert?

Ich möchte die Zahlen 0 - F (Hex) auf einem 7-Segment Display ausgeben.
Ich verwende ein V40511 (DDR-Produktion) als Decoder, das dieser noch 
die
HexZahlen A - F ausgeben kann.
Nun zu meinem Problem:
Wie kann ich in der Arduino-IDE 4 Portpins als Byte Array so definieren, 
das ich durch schreiben in dieses Array die Portpins wie ein hex-Ausgang 
verhalten?
Mein ursprünglicher Ansatz (funktioniert auch) war so:
1
byte PA = 8; 
2
byte PB = 9; 
3
byte PC = 10; 
4
byte PD = 11;
5
void setup() {
6
7
/*
8
pin  8 = E3 40511
9
pin  9 = E2 40511
10
pin 10 = E1 40511
11
pin 11 = E0 40511
12
13
*/
14
{
15
   pinMode(PA,OUTPUT);
16
   pinMode(PB,OUTPUT);
17
   pinMode(PC,OUTPUT);
18
   pinMode(PD,OUTPUT);
19
   
20
}
21
22
}
23
/*
24
im Loop angegebene Kommentare entsprechen der ausgegebenen Zahl
25
*/
26
void loop() 
27
{
28
  digitalWrite(PA, LOW); //0
29
  digitalWrite(PB, LOW);
30
  digitalWrite(PC, LOW);
31
  digitalWrite(PD, LOW);
32
  delay (500);
33
  digitalWrite(PA,LOW); //1
34
  digitalWrite(PB,LOW);
35
  digitalWrite(PC,LOW);
36
  digitalWrite(PD,HIGH);
37
  delay (500);
38
 digitalWrite(PA,LOW); //3
39
  digitalWrite(PB,LOW);
40
  digitalWrite(PC,HIGH);
41
  digitalWrite(PD,HIGH);
42
  delay (500);
43
/...
44
}

mein Ziel ist etwa so:
...
AusgabePort = 7 // PD=0,PC=1,PB=1,PA=1 entspricht bin=0111

- damit das klappt muß Pin8,9,10 und 11 irgendwie als "AusgabePort" 
deklariert werden.
Wie macht man das ?

von Karl H. (kbuchegg)


Lesenswert?

Wenn du nicht allsozuseh vom Arduino typischen digitalWrite wegwillst, 
dann ist deine vernünftigste Option, dir dafür eine Funktion zu 
schreiben
1
void putToPort( uint8_t value )
2
{
3
  digitalWrite( PD, ( value & 0x08 ) ? HIGH : LOW );
4
  digitalWrite( PC, ( value & 0x04 ) ? HIGH : LOW );
5
  digitalWrite( PB, ( value & 0x02 ) ? HIGH : LOW );
6
  digitalWrite( PA, ( value & 0x01 ) ? HIGH : LOW );
7
}

also im Grunde mit einer Ausmaskierung jeweils ein Bit zu betrachten, 
und je nachdem ob es 1 oder 0 ist, dann am jeweiligen Pin die Ausgabe 
von HIGH bzw. LOW zu machen.

Schnell ist was anderes. Dafür funktioniert das aber auch, wenn die 
einzelnen Pins auf beliebigen physikalischen Ports beliebig verteilt 
sind, weil sich digitalWrite darum kümmert.

> - damit das klappt muß Pin8,9,10 und 11 irgendwie als "AusgabePort" deklariert 
werden.

Was gefällt dir an deinen 'pinMode' nicht?

: Bearbeitet durch User
von ArduinoNeuling (Gast)


Angehängte Dateien:

Lesenswert?

Ich muss umständlich jeder Zahl einzeln eingeben. So kann man aber nicht 
mit Arrays arbeiten.(Siehe Anhang)

von Karl H. (kbuchegg)


Lesenswert?

ArduinoNeuling schrieb:
> Ich muss umständlich jeder Zahl einzeln eingeben. So kann man aber nicht
> mit Arrays arbeiten.(Siehe Anhang)

?

Was ist jetzt an
1
void loop()
2
{
3
  putToPort( 0 );
4
  delay (500);
5
6
  putToPort( 1 );
7
  delay (500);
8
9
  putToPort( 2 );
10
  delay (500);
11
12
...
13
}

umständlich?

Oder auch
1
void loop()
2
{
3
  uint8_t i;
4
5
  for( i = 0; i < 15; i++ )
6
  {
7
    putToPort( i );
8
    delay (500);
9
  }
10
}

Der Schlüssel besteht darin, dass du dir EINE Funktion machst, die dir 
genau den lästigen Teil des auseinandernehmens der Bits erledigt. Und 
schon kannst du sie entsprechend mit beliebigen Ziffern aufrufen, je 
nachdem wie du das brauchst.

Mit einem Array könnte man das auch machen
1
struct Bits_
2
{
3
  uint8_t BitD;
4
  uint8_t BitC;
5
  uint8_t BitB;
6
  uint8_t BitA;
7
};
8
9
Bits_ digitBits[16] =
10
{
11
  {  LOW,  LOW,  LOW,  LOW },   // 0
12
  {  LOW,  LOW,  LOW, HIGH },   // 1
13
  {  LOW,  LOW, HIGH,  LOW },   // 2
14
  {  LOW,  LOW, HIGH, HIGH },   // 3
15
...
16
};
17
18
void putToPort( uint8_t value )
19
{
20
  digitalWrite( digitBits[value].BitD );
21
  digitalWrite( digitBits[value].BitC );
22
  digitalWrite( digitBits[value].BitB );
23
  digitalWrite( digitBits[value].BitA );
24
}

aber eigentlich ist das schon ziemlich von hinten durch die Brust ins 
Auge. Die Bitzerlegung von oben ist einfacher.

: Bearbeitet durch User
von ArduinoNeuling (Gast)


Lesenswert?

Danke, nun ist der Groschen gefallen...

von Karl H. (kbuchegg)


Lesenswert?

Ah. Sehe gerade, dass bei dir A bis D genau verkehrt rum läutf.
Dann musst du eben alles umdrehen
1
void putToPort( uint8_t value )
2
{
3
  digitalWrite( PA, ( value & 0x08 ) ? HIGH : LOW );
4
  digitalWrite( PB, ( value & 0x04 ) ? HIGH : LOW );
5
  digitalWrite( PC, ( value & 0x02 ) ? HIGH : LOW );
6
  digitalWrite( PD, ( value & 0x01 ) ? HIGH : LOW );
7
}

von ArduinoNeuling (Gast)


Lesenswert?

Hatte ich schon geändert...
mir ist aufgefallen, (warscheinlich ist es "Alten Hasen" bewußt) daß ich 
nicht
1
...
2
  putToPort( A );
3
  delay (500);
4
... 
5
eingeben kann, statt dessen muß
6
7
  putToPort( 10 ); // entspricht hex A
8
  delay (500);
9
10
eingegeben werden???

oder habe ich etwas übersehen? Kann man in der ArduinoIDE Hexwerte und 
Dezimalwerte mischen ?

von Gregor H. (gregor_h)


Angehängte Dateien:

Lesenswert?

Karl Heinz schrieb:
> ArduinoNeuling schrieb:
>> Ich muss umständlich jeder Zahl einzeln eingeben. So kann man aber nicht
>> mit Arrays arbeiten.(Siehe Anhang)
>
> ....
>
1
> void loop()
2
> {
3
>   uint8_t i;
4
> 
5
>   for( i = 0; i < 15; i++ )
6
>   {
7
>     putToPort( i );
8
>     delay (500);
9
>   }
10
> }
11
>
>

es muß heissen
 for( i = 0; i < 16; i++ )
sonst zählt die Schleife  nur bis hex E

: Bearbeitet durch User
von Walter (Gast)


Lesenswert?

ArduinoNeuling schrieb:
> Kann man in der ArduinoIDE Hexwerte und
> Dezimalwerte mischen ?

the running gag ;-)

natürlich, aber A ist keine Zahl die der Compiler versteht, aber er kann 
0xA

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
Noch kein Account? Hier anmelden.