Forum: Mikrocontroller und Digitale Elektronik Portzustände definieren


von Lokus P. (derschatten)


Lesenswert?

Ich möchte gerne eine bestimmte Anzahl an PIN's von einem PORT 
gleichzeitig definieren.
Also es soll nicht der komplette Port gesetzt werden.

Ich habe das jetzt mal so umständlich gelöst:
1
#define LEDBIT0      0
2
#define LEDBIT1      1
3
#define LEDBIT2      2
4
#define LEDBIT3      3
5
#define LEDBIT4      4
6
#define LEDBIT5      5
7
#define LEDBIT6      6
8
#define LEDBIT7      7
9
10
    switch(val1)
11
    {
12
      case 0:
13
        LED_PORT |= (1<<LEDBIT0);
14
    LED_PORT &= ~(1<<LEDBIT1);
15
    LED_PORT &= ~(1<<LEDBIT2);
16
    LED_PORT &= ~(1<<LEDBIT3);
17
        break;
18
      case 1:
19
        LED_PORT &= ~(1<<LEDBIT0);
20
    LED_PORT |= (1<<LEDBIT1);
21
    LED_PORT &= ~(1<<LEDBIT2);
22
    LED_PORT &= ~(1<<LEDBIT3);
23
        break;
24
      case 2:
25
        LED_PORT &= ~(1<<LEDBIT0);
26
    LED_PORT &= ~(1<<LEDBIT1);
27
    LED_PORT |= (1<<LEDBIT2);
28
    LED_PORT &= ~(1<<LEDBIT3);
29
        break;
30
      case 3:
31
        LED_PORT &= ~(1<<LEDBIT0);
32
    LED_PORT &= ~(1<<LEDBIT1);
33
    LED_PORT &= ~(1<<LEDBIT2);
34
    LED_PORT |= (1<<LEDBIT3);
35
        break;
36
    }
37
38
    switch(val2)
39
    {
40
      case 4:
41
        LED_PORT |= (1<<LEDBIT4);
42
    LED_PORT &= ~(1<<LEDBIT5);
43
    LED_PORT &= ~(1<<LEDBIT6);
44
    LED_PORT &= ~(1<<LEDBIT7);
45
        break;
46
      case 5:
47
        LED_PORT &= ~(1<<LEDBIT4);
48
    LED_PORT |= (1<<LEDBIT5);
49
    LED_PORT &= ~(1<<LEDBIT6);
50
    LED_PORT &= ~(1<<LEDBIT7);
51
        break;
52
      case 6:
53
        LED_PORT &= ~(1<<LEDBIT4);
54
    LED_PORT &= ~(1<<LEDBIT5);
55
    LED_PORT |= (1<<LEDBIT6);
56
    LED_PORT &= ~(1<<LEDBIT7);
57
        break;
58
      case 7:
59
        LED_PORT &= ~(1<<LEDBIT4);
60
    LED_PORT &= ~(1<<LEDBIT5);
61
    LED_PORT &= ~(1<<LEDBIT6);
62
    LED_PORT |= (1<<LEDBIT7);
63
        break;
64
    }

Aber das geht doch sicher einfacher.
Eventuell mit Arrays?
Wie würdet ihr das lösen?

von Lokus P. (derschatten)


Lesenswert?

Gibt es keine Möglichkeit 1Bit zu setzen und gleichzeit 3 andere zu 
löschen? Also am besten in einer Zeile.

von fooo (Gast)


Lesenswert?

erstell dir ein makro
scheller wirds trotzdem nicht

von Thomas E. (thomase)


Lesenswert?

unsigned char val1...
heisst die Variable jetzt VAL1 oder VALL oder VA11?
kleines L, also l, mit 1 zu kombinieren kann schnell zu Verwirrungen 
führen.
Vor allen Dingen dann, wenn man schon 3 Stunden einen Fehler sucht.
Das mal am Rande.

Ist doch ganz einfach. Du legst das auszugebende Bitmuster in ein Array.

unsigned char BitmusterA[] = {
                              0xb00000001,
                              0xb00000010,
                              0xb00000100,
                              usw.
};
Hier ist auch die sonst verpönte 0xb-Schreibweise erlaubt. Rück das 
vernünftig ein, dann bleibt das übersichtlich.

unsigned char BitmusterB[] = {
                              0xb00010000,
                              0xb00100000,
                              0xb01000000,
                              usw.
};

LED_PORT = BitmusterA[Leds1];
LED_PORT |= BitmusterB[Leds2];

Leds2 darf natürlich nicht wie oben val2 von 4 bis 7 zählen, ist ohnehin 
Unsinn, sondern wie Leds1 von 0 bis 3.

So einfach geht es natürlich nur, wenn alle LEDs auf dem selben 
Controllerport liegen. Also alle z.B auf PORTB.

mfg.

von cppler (Gast)


Lesenswert?

Dann bau Dir eine Statemachine und lege die jeweiligen Portzustände wie 
Thomas schon vorgeschlagen hat in ein Array das den jeweiligen Zustand 
darstellt.

von Reinhard Kern (Gast)


Lesenswert?

cppler schrieb:
> lege die jeweiligen Portzustände wie
> Thomas schon vorgeschlagen hat in ein Array das den jeweiligen Zustand
> darstellt.

In jedem Fall schreibst du alle 8 Bits eines Ports gleichzeitig, also 
sind deine vielen Schreibbefehle überflüssig bis auf je einen - du must 
nur vorher irgendwie das Bitmuster für das Port zusammenbasteln, Arrays 
sind eine Möglichkeit. Dann gibt es auch keine vorübergehend verbotenen 
Kombinationen am Port wie bei mehreren Schreibvorgängen.

Ein übliches Verfahren:

Port einlesen oder den Zustand aus einem Register holen.
Per AND die Bits löschen, die Null werden sollen.
Per OR die gewünschten Bits auf 1 setzen.
Neue Kombination in den Port schreiben und ev. in besagtes Register.

Gruss Reinhard

von Lokus P. (derschatten)


Lesenswert?

Reinhard Kern schrieb:
> In jedem Fall schreibst du alle 8 Bits eines Ports gleichzeitig

Eben nicht. Die einzelnen PIN's der Ports werden gleichzeitig getrennt 
ausgegeben.

Pin 1-4, Pin 5-6, Pin 7-8
Darum kann ich auch nicht den kompletten Portzustände ändern.

unsigned char BitmusterA[] = {0xb00000001, 0xb00000010, 0xb00000100, 
0xb00001000}; -> liefert:
../main.c:77: warning: large integer implicitly truncated to unsigned 
type

Was macht 0xb?

von Peter II (Gast)


Lesenswert?

Manfred W. schrieb:
> Was macht 0xb?

nichts sinnvolles, es gibt nur 0x für hex und 0b für binary.

18 = 0x12 = 022 = 0b00010010

von Thomas E. (thomase)


Lesenswert?

Manfred W. schrieb:

> Was macht 0xb?
Natürlich Mist.
Sorry für meinen Tipfehler. das muss natürlich 0b11101110 heissen.

mfg.

von Falk B. (falk)


Lesenswert?

@ Manfred W. (derschatten)

>Eben nicht. Die einzelnen PIN's der Ports werden gleichzeitig getrennt
>angesprochen.

Was für ein Satz.

>Pin 1-4, Pin 5-6, Pin 7-8
>Darum kann ich auch nicht den kompletten Port ansprechen.

Doch, wenn man weiß wie.

>unsigned char BitmusterA[] = {0xb00000001, 0xb00000010, 0xb00000100,
>0xb00001000}; -> liefert:
>../main.c:77: warning: large integer implicitly truncated to unsigned
>type

Du bist ein echter Künstler. Entweder hex oder binär!

0x01 oder 0b00000001

von cppler (Gast)


Lesenswert?

Manfred W. schrieb:
> Reinhard Kern schrieb:
>> In jedem Fall schreibst du alle 8 Bits eines Ports gleichzeitig
>
> Eben nicht. Die einzelnen PIN's der Ports werden gleichzeitig getrennt
> ausgegeben.
>
> Pin 1-4, Pin 5-6, Pin 7-8
> Darum kann ich auch nicht den kompletten Portzustände ändern.
>

Deswegen habe ich Dir ja empfohlen dir eine Statemachine aufzubauen.
Die einzelnen Zustände werden ja nach einem bestimmten Muster erzeugt 
z.B. von Zustand01 (00000001) zum Zustand04 (10001111) ist ein Übergang.
Die Zustände sind ja nur durch einen Wert definiert Dein "val" im 
switch, daher kannst Du auch die Zustände wie schon mehrmals 
angesprochen einfach hintereinander durchgehen.
Mit der Statemachine kannst Du allerdings schöner arbeiten wenn sich was 
grundlegendes ändern sollte.
Lies Dich erstmal ins Thema ein ;-)

von Lokus P. (derschatten)


Lesenswert?

Ok, da ich jetzt komplett auf einen anderen AVR umsteigen mußte. 
ATTiny44.
habe jetzt leider das Problem das ich LED's und Steuer-Ausgänge am 
gleiche Port habe.

PA0-PA3 sind LED's
PA4-PA5 sind Ausgänge um etwas anzusteuern.

von Falk B. (falk)


Lesenswert?

@Manfred W. (derschatten)

>Ok, da ich jetzt komplett auf einen anderen AVR umsteigen mußte.
>ATTiny44.
>habe jetzt leider das Problem das ich LED's und Steuer-Ausgänge am
>gleiche Port habe.

>PA0-PA3 sind LED's
>PA4-PA5 sind Ausgänge um etwas anzusteuern.

Mein Gott bist du lernresistent! Du postest hier schon seit Monaten, 
vielleicht Jahren und hast noch immer nicht die einfachsten Grundlagen 
gelernt! Die da lauten Bitmanipulation. Such dir ein anderes Hobby!

http://de.wiktionary.org/wiki/Tacheles_reden

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.