Forum: Mikrocontroller und Digitale Elektronik Atmega8515 Alternative Portadressierung


von Christian R. (bqzero)


Lesenswert?

Halli Hallo

Hab mal ne frage.

ich würde gerne wissen wie ich die ports ansteuern kann.

habe sie bereits als ausgänge in den datenregister eigetragen.
nun wüsste ich gerne, ob es möglich ist folgenden quelltext irgendwie 
schlau auszugeben.


  lichter[0]=(1<<PA0);
  lichter[1]=(1<<PB7);
  lichter[2]=(1<<PC3);
  lichter[3]=(1<<PA2);
  lichter[4]=(1<<PD5);
  lichter[5]=(1<<PB6);
  lichter[6]=(1<<PC4);
  lichter[7]=(1<<PA4);
  lichter[8]=(1<<PD6);

ich sollte dieses array mittels einer for schleife ausgeben, respektive 
die pins auf high setzen. hat mir da jemand ne idee?

mit PORTA¦=lichter[1]; funktioniert das ja nicht. wie kann ich 
unabhängig ohne PORTA oder so den Pin ansteuern?

Wäre um hilfe froh.

von Niels H. (monarch35)


Lesenswert?

Wenn ich dich richtig verstanden habe, ist das auch unsinn. 
Beispielsweise sind PA0, PB0 und PC0 vom Wert her absolut identisch. 
Nämlich sind alle drei 0. Du kannst also von dem Wert den du ins 
Lichter[]-Array geschrieben hast nicht auf den Port rückschliessen.

von Christian R. (bqzero)


Lesenswert?

aha okay danke für den hinweis. wie kann ich dann alle pins auf 
verschiedenen ports einzeln ansteuern?

von Niels H. (monarch35)


Lesenswert?

Vieleicht solltest du mal genauer erklären, warum du unbedingt aus einem 
Array herraus die PortBits adressieren möchtest; vieleicht gibts einen 
besseren weg. Bisher fällt mir nämich nur sowas ein:
1
struct
2
{
3
    uint8_t *port;
4
    uint8_t bit;
5
    uint8_t value;
6
} portbits[9];
7
8
portbits[0].port=PORTB;
9
portbits[0].bit= PB0;
10
portbits[0].value=0;
11
12
13
portbits[1].port=PORTC;
14
..
15
..
16
17
for (int cou=0;cou<9;cou++)
18
{
19
    if (portbits.value)
20
       portbits[cou].port|=(1<<portbits[cou].bit);
21
     else
22
       portbits[cou].port&=~(1<<portbits[cou].bit);
23
}

Das wäre allerdings ein resourcenmonster und nicht wirklich schön....

von Christian R. (bqzero)


Lesenswert?

also es geht mir darum alle PORTS zu nutzen sprich jeden PIN. die werden 
dann mittels eines zufallsscript angesteuert. also die reihenfolge etc. 
ist willkürlich. wie ich das sonst machen kann weis ich leider nicht

von Karl H. (kbuchegg)


Lesenswert?

Christian Rutschmann wrote:
> also es geht mir darum alle PORTS zu nutzen sprich jeden PIN. die werden
> dann mittels eines zufallsscript angesteuert. also die reihenfolge etc.
> ist willkürlich. wie ich das sonst machen kann weis ich leider nicht

so vielleicht?

  while( 1 ) {
    tmp = rand() % 4;    // weil 4 Ports: A, B, C, D

    if( tmp == 0 )
      PORTA = rand();
    else if( tmp == 1 )
      PORTB = rand();
    else if( tmp == 2 )
      PORTC = rand();
    else
      PORTD = rand();
  }


oder musst du die Sequenz unbedingt zwischenspeichern?

von Niels H. (monarch35)


Lesenswert?

Christian Rutschmann wrote:

> also es geht mir darum alle PORTS zu nutzen sprich jeden PIN.

Und wieso sagst du das nicht gleich?! grummel *seuftz*

von Christian R. (bqzero)


Lesenswert?

ne muss ich nicht unbedingt. Aber ich sollte mit sicherheit alle pins 
angesteuert haben in einer bestimmten zeit. und so ist die wüllkür am 
wüten

von Niels H. (monarch35)


Lesenswert?

@iqzero:
> Aber ich sollte mit sicherheit alle pins
> angesteuert haben in einer bestimmten zeit. und so ist die wüllkür am
> wüten

Auf die Erklärung, was das jetzt bedeuten soll, bin ich mal 
gespannt....oder hat den jemand verstanden?

von Kai G. (runtimeterror)


Lesenswert?

Alle Pins auf Zufall:
1
while (1)
2
{
3
    PORTA = rand();
4
    PORTB = rand();
5
    PORTC = rand();
6
    PORTD = rand();
7
}

Zufälliger Pin auf Zufall (von Karl heinz geborgt):
1
while (1)
2
{
3
  tmp = rand() & 3;    // weil 4 Ports: A, B, C, D
4
5
  if (tmp == 0)
6
    PORTA ^= 1 << (rand() & 7);
7
  else if (tmp == 1)
8
    PORTB ^= 1 << (rand() & 7);
9
  else if (tmp == 2)
10
    PORTC ^= 1 << (rand() & 7);
11
  else
12
    PORTD ^= 1 << (rand() & 7);
13
}

zumindest, wenn "^=" in C existiert...

Wenn C das kann geht auch ein
1
switch (rand() & 3) ...

Bin mir aber immer noch nicht sicher, ob ich verstanden habe, was du 
eigentlich brauchst...

ps:
>Auf die Erklärung, was das jetzt bedeuten soll, bin ich mal
>gespannt....oder hat den jemand verstanden?

nö ;)

von Kai G. (runtimeterror)


Lesenswert?

Der zweite Code tut nicht, was er soll. Bitte ignorieren. Auf Wunsch 
korrigiere ich den.

von Karl H. (kbuchegg)


Lesenswert?

Christian Rutschmann wrote:
> ne muss ich nicht unbedingt. Aber ich sollte mit sicherheit alle pins
> angesteuert haben in einer bestimmten zeit.

Das macht ein Lauflicht auch :-)

Ich geh schon mal Popcorn holen. Wenn der Thread nur die
Hälfte von dem hält was ich mir jetzt schon davon verspreche ...

von Christian R. (bqzero)


Lesenswert?

also so was ist na dran. aber im prinzip sollte die random funktion den 
bereich 0-7 zwar als bereich haben, aber die randoms sollten bei jedem 
durchlauf nur einmal den gleichen wert liefern und dafür jeden einmal.

von Karl H. (kbuchegg)


Lesenswert?

Wie wäre es wenn du mal erzählst was das Ganze denn werden soll.
Dann kann man sich nämlich mehr drunter vorstellen.
Und wer weiß, vielleicht kommt ja der eine oder andere
brauchbare Vorschlag.

von Christian R. (bqzero)


Lesenswert?

>
1
while (1)
2
> {
3
>   tmp = rand() & 3;    // weil 4 Ports: A, B, C, D
4
>   if (tmp == 0)
5
>     PORTA ^= 1 << (rand() & 7);
6
>   else if (tmp == 1)
7
>     PORTB ^= 1 << (rand() & 7);
8
>   else if (tmp == 2)...
9
> }

also sowas ist nicht schlecht, aber es ist nicht gegeben das jeder wert 
nur einmal vorkommt, dafür sicher.

von Niels H. (monarch35)


Lesenswert?

> also sowas ist nicht schlecht, aber es ist nicht gegeben das jeder wert
> nur einmal vorkommt, dafür sicher.

Häh?
Das Zufallsprinzip schliesst NIE aus, daß eine Fall nur einmal vorkommt. 
Vieleicht solltest du mal zur Sache kommen und mal detailiert 
beschreiben, was du überhaupt bauen möchtest. Was soll es werden, wenns 
fertig ist?

Sonst raten wir uns hier noch die Lottozahlen zusammen.....

von Christian R. (bqzero)


Lesenswert?

das ganze wäre für  eine lichtersteuerung eines modells. ich habe eine 
bestimmte zeit in der ich alle lichter brennen haben will dan soll ein 
zufälliger übergang folgen, der ebenfalls eine bestimmte dauer hat. in 
dieser zeit sollen alle lichter ausschalten. danach ist nichts an und 
die sache läuft rückwerts.
im prinzip ist es eine tag nacht simulation. und die 4 ports mit je 8 
pins brauche ich, da ich 32 lichter brauche

von Niels H. (monarch35)


Lesenswert?

Christian Rutschmann wrote:
>
> [...] zeit in der ich alle lichter brennen hab [...]

dessen bin ich mir bereits im Klaren. Und zwar in jeden Sinne.

> zufälliger übergang folgen, der ebenfalls eine bestimmte dauer hat. in

Was ist ein "zufälliger Übergang"?

> dieser zeit sollen alle lichter ausschalten. danach ist nichts an und
> die sache läuft rückwerts.

Bis hin wo du "alle Lichter am brennen" hast?

> im prinzip ist es eine tag nacht simulation. und die 4 ports mit je 8
> pins brauche ich, da ich 32 lichter brauche

Wenn du meinst....

von Kai G. (runtimeterror)


Lesenswert?

Also ein Dithering?

- Jedem Port I/O einen zufälligen Grenzwert verpassen
- Ein Zähler, der runter-/hochzählt
- Für jeden I/O den Zähler mit dem Grenzwert vergleichen und das 
Ergebnis dem I/O zuweisen.

Dann gehen nacheinander zufällig irgendwelche Lichter aus.

Meint er das? Übersetz mal einer!

von Christian R. (bqzero)


Lesenswert?

zufälliger übergang heisst hier das in einer unbestimmten reihenfolge 
jedes einzelne licht angehen soll.
also was ein dithering ist weis ich ja nicht.

von Karl H. (kbuchegg)


Lesenswert?

Kai Giebeler wrote:

> Meint er das? Übersetz mal einer!

Stell dir ein Hochhaus vor.
Abends wenn es dunkel wird, gehen nacheinander die Lichter
an, und zwar so lange bis alle Lichter brennen.
Danach gehen sie alle wieder einzeln aus, bis wieder alle
aus sind.

Man kann aber die Reihenfolge nicht vorher sagen.

von Troll B. (blaubeer)


Lesenswert?

Karl heinz Buchegger wrote:

> Ich geh schon mal Popcorn holen. Wenn der Thread nur die
> Hälfte von dem hält was ich mir jetzt schon davon verspreche ...

Ja??? - Wer ruft mich da??

MfG, BlauBär

von Kai G. (runtimeterror)


Lesenswert?

>Stell dir ein Hochhaus vor.
>Abends wenn es dunkel wird, gehen nacheinander die Lichter
>an, und zwar so lange bis alle Lichter brennen.
>Danach gehen sie alle wieder einzeln aus, bis wieder alle
>aus sind.

Dann hab' ich's richtig (oder zumindest genauso) verstanden und der 
obige Algorithmus sollte seinen Dienst erfüllen. Die Übersetzung in C 
überlasse ich wer will...

Popcorn und Cola wär' jetzt echt 'ne Maßnahme...

von Karl H. (kbuchegg)


Lesenswert?

Christian Rutschmann wrote:
> das ganze wäre für  eine lichtersteuerung eines modells. ich habe eine
> bestimmte zeit in der ich alle lichter brennen haben will dan soll ein
> zufälliger übergang folgen, der ebenfalls eine bestimmte dauer hat. in
> dieser zeit sollen alle lichter ausschalten. danach ist nichts an und
> die sache läuft rückwerts.

Hmm.
Da könnte man auch eine Steuerung über die Zeit machen.

Für jedes Licht gibt es eine Variable, die angibt wie lange
dieses Licht noch hell bzw. dunkel sein soll. Nach Ablauf
der Zeit wechselt das Licht dann in den anderen Zustand.

Ich skizziere mal (für den Fall, dass bei gesetzten 1 Bit ein
Licht leuchtet und die Lichter nacheinander eingeschaltet
werden sollen)
1
   uint16_t Remaining[32];    // weil 32 Lichter
2
3
   ...
4
5
6
   // für jedes Licht mal eine zufällig Zeitdauer festlegen
7
   for( i = 0; i < 32; ++i )
8
     Remaining[i] = rand();
9
10
   // mal alles aus
11
   PORTA = 0;
12
   PORTB = 0;
13
   PORTC = 0;
14
   PORTD = 0;
15
16
   // und jetzt die Zeiten abarbeiten
17
   // das Inkrement müsste man anpassen, damit die Gesamtdauer
18
   // in etwa hinkommt
19
   for( Now = 0; Now < RAND_MAX; ++Now ) {
20
21
     // welche der 32 Lichter müssen eingeschaltet sein, weil
22
     // ihre Schaltzeit bereits erreicht ist.
23
     // ich mach das in 4 Gruppen, damit die Portzugriffe
24
     // einfacher werden
25
26
     for( i = 0; i < 8; ++i )    // alle am Port A
27
       if( Remaining[i] < Now )
28
         PORTA |= ( 1 << i );
29
30
     for( i = 0; i < 8; ++i )    // alle am Port B
31
       if( Remaining[i + 8] < Now )
32
         PORTB |= ( 1 << i );
33
34
     for( i = 0; i < 8; ++i )    // alle am Port C
35
       if( Remaining[i + 16] < Now )
36
         PORTC |= ( 1 << i );
37
38
     for( i = 0; i < 8; ++i )    // alle am Port D
39
       if( Remaining[i + 24] < Now )
40
         PORTD |= ( 1 << i );
41
42
     _delay_ms( 10 );   // 10 ms * 32767 ( = RAND_MAX ) = 327 Sekunden,
43
                        // also etwas über 5 Minuten
44
  }

von Christian R. (bqzero)


Lesenswert?

sieht auf den ersten blick nicht schlecht aus, ausser das halt die ports 
der reihe nach angehen und nicht noch die ports vermischt angehen.

von Karl H. (kbuchegg)


Lesenswert?

Christian Rutschmann wrote:
> sieht auf den ersten blick nicht schlecht aus, ausser das halt die ports
> der reihe nach angehen und nicht noch die ports vermischt angehen.

Woraus schliesst du das?

Die Leds gehen in der Reihenfolge an den jeweiligen Ports
an, so wie sie ihnen hier:

   // für jedes Licht mal eine zufällig Zeitdauer festlegen
   for( i = 0; i < 32; ++i )
     Remaining[i] = rand();

in Form einer Wartezeit vorgegeben wurde. Und da wird für jede Led
eindeutig eine Zufallszahl vergeben.

Da kann es durchaus sein, dass sich mal 10 Sekunden überhaupt
nichts an den Led rührt und dann gehen 5 Led wild durcheinander
innerhalb von 2 Sekunden an.
Wie im richtigen Leben halt.

von Christian R. (bqzero)


Lesenswert?

okay hast ja recht habs noch nicht ganz kappiert gehabt. aber leuchtet 
ein. ist noch genial das script.

von Kai G. (runtimeterror)


Lesenswert?

Danke für die Übersetzung in C! Sollte mich doch irgendwann mal mit der 
Sprache auseinandersetzen...

von Karl H. (kbuchegg)


Lesenswert?

Kai Giebeler wrote:
> Danke für die Übersetzung in C!

Gern geschehen :-)

Das schöne ist, dass dieses Schema noch soviel Potential
für eine Spielwiese ohne Ende hat :-)

Einfach nur die Lichter nacheinander einschalten ist doch
fad. Die können auch mit einem Glitzereffekt sich
einschalten (wie die Blitzlichfotografen in einem Sportstadion)
oder ein / aus dimmen oder ...
Noch eine Software-PWM auf alle 32 Led gelegt, für jede Led
noch ein paar zusätzliche Parameter wie Leuchtdauer, Helligkeit
im Zustand aus, Helligkeit im Zustand ein, ...
und dem Spass ist Tür und Tor geöffnet.

von Niels H. (monarch35)


Lesenswert?

Christian Rutschmann wrote:

> ist noch genial das script.

Script?! Mir klingeln die Ohren!

von Niels H. (monarch35)


Lesenswert?

Meine Idee wäre:
1
uint8_t *port;
2
DDRA=DDRB=DDRC=DDRD=255;
3
PORTA=PORTB=PORTC=PORTD=0;
4
do 
5
{
6
  switch (rand()&3)
7
  {
8
      case 0:
9
         port=PORTA;
10
         break ;
11
      case 1:
12
         port=PORTB;
13
         break;
14
      case 2:
15
         port=PORTC;
16
         break;
17
      default:
18
         port=PORTD;
19
         break;
20
   }
21
   port|=(1<<(rand()&7));
22
   delay_ms (50);
23
24
} while (PORTA!=255 || PORTB!=255 || PORTC!=255 || PORTD!=255) ;

Bin mir nur gerade nicht sicher, ob die defintion "uint_8 *port;" 
stimmt. Sollte sich aber herrausfinden lassen...

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.