Bit und Bytemanipulation mit Arduino

Gast #3948406
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 ?
#3948421
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?
#3948444
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.
#3948448
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
}
Gast #3948532
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 ?
#3949093
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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren