Forum: Mikrocontroller und Digitale Elektronik ATMEGA8, RN-MiniControl, Lauflicht per CTRL-Stecker


von Archangel (Gast)


Lesenswert?

Eine schöne Tageszeit liebe Gemeinde,

da mein Wissen in Programmierung von Mikrocontrollern noch locker unter 
den Tisch wandert, bitte ich um eine Erklärung und etwaige Tipps von 
Fortgeschrittenen und Experten.

Es geht lediglich um ein Lauflicht: LED-Board, welches an den 
STRL-Stecker vom RN-MiniControl angeschlossen ist. Der Haken dabei ist, 
dass der Stecker nicht jeweils eine Portbezeichnung beinhaltet, sondern 
von PB0 über PC3 bis hin zu PD7 geht.

Wie stelle ich das an, unter Verwendung verschiedener Ports ein 
Lauflicht zu bekommen?

von lll (Gast)


Lesenswert?

Archangel schrieb:
> Wie stelle ich das an, unter Verwendung verschiedener Ports ein
> Lauflicht zu bekommen?

In dem Du einfach jeden einzelnen Pin nacheinander toggelst, dazu 
brauchst Du noch die Zeit die die einzelen LED an sein soll.

von Karl H. (kbuchegg)


Lesenswert?

Archangel schrieb:

> Wie stelle ich das an, unter Verwendung verschiedener Ports ein
> Lauflicht zu bekommen?

Indem du dir zb selber sowas wie einen 'virtuellen Port' bastelst (ein 
hochgestochenes Wort für einfach nur eine entsprechende Variable) und 
dann ausgehend von diesem "virtuellen Port" die Verteilung auf die 
einzelnen µC-Pins programmierst.

So zb würd ich das machen, wenn das Lauflicht komplexere Muster machen 
soll. Wenn es nur eine einzige helle LED ist, die im Kreis läuft, dann 
allerdings würde ich die Pins direkt einfach toggeln.

von Archangel (Gast)


Lesenswert?

Ich fürchte, dass ich immer noch nicht ganz weiterkomme...

Folgender Quelltext ist schonmal entstanden:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void);
5
6
const int8_t numbers[8] =
7
{
8
  // LED: 0-7
9
10
  0b01000000,    // PD6
11
  0b10000000,    // PD7
12
  0b00000001,    // PB0
13
  0b00100000,    // PB5
14
  0b00001000,    // PC3
15
  0b00001000,    // PB3
16
  0b00001000,    // PD3
17
  0b00000100,    // PC2
18
  
19
};
20
21
// wartet ms Millisekunden
22
23
void delay_ms(uint16_t ms)
24
{
25
  for(uint16_t t=0; t<=ms; t++)
26
    _delay_ms(1);
27
}
28
29
int main(void)
30
{
31
  int i=1;
32
  
33
DDRB |= ( 1 << DDB0) | (1<<DDB3) | ( 1<<DDB5);  // PORTB als Ausgang   
34
DDRC |= ( 1 << DDC2) |1<<DDC3);                 // PORTC als Ausgang
35
DDRD |= ( 1 << DDD3) | (1<<DDD6) | ( 1 <<DDD7);  // PORTD als Ausgang
36
  
37
  
38
  while(1)
39
  {
40
  
41
      /*PORTD = numbers[i];
42
      delay_ms(70);
43
      PORTB = numbers[i];
44
      delay_ms(70);
45
      PORTC = numbers[i];
46
      delay_ms(70);*/
47
48
49
  }
50
  
51
  return 0;
52
}


Nur müsste jetzt in die while-Schleife eine ähnliche Form wie die hier 
kommen:
1
PORTB ^= (1<<PB0) | (1<<PB5);

Ich komme aber nicht auf die Syntax für mehrere LEDs drauf :(

Bedanke mich im Voraus

von lll (Gast)


Lesenswert?

Archangel schrieb:
> Ich komme aber nicht auf die Syntax für mehrere LEDs drauf :(
>
> Bedanke mich im Voraus

Wo liegt das Problem, Du schaltest zuerst alle PINs von PortB 
nacheinander durch, dann PortB komplett aus und fängst dann bei PortC 
bzw. PortD von vorne an.
Dein Array benötigst Du nicht, da PB0 nichts anderes als 0 ist wie im 
header vom GCC zu erkennen:
1
/* PORTB */
2
#define PB7  7
3
#define PB6  6
4
#define PB5  5
5
#define PB4  4
6
#define PB3  3
7
#define PB2  2
8
#define PB1  1
9
#define PB0  0
Du kannst also statt PORTB ^= (1<<PB0) auch PORTB ^= (1<<0) schreiben.
Ergo nun einfach zwei verschachtelte for schleifen programmieren, eine 
für die drei Ports und eine für die jeweiligen 8 Pins derselben und das 
war's.

von Archangel (Gast)


Lesenswert?

Das Problem ist, dass die Reihenfolge genau so zu sein hat, wie im Array 
geschrieben. Das wäre die benötigte Reihenfolge der geschalteten LEDs.

von lll (Gast)


Lesenswert?

Archangel schrieb:
> Das Problem ist, dass die Reihenfolge genau so zu sein hat, wie im Array
> geschrieben. Das wäre die benötigte Reihenfolge der geschalteten LEDs.

Dann mach's in Deiner main zu Fuß also z.B. sowas:
1
PORTD ^= (1<<PD6);
2
delay_ms(70);
3
PORTD ^= (1<<PD6);
Halt für alle nacheinander ;-)

von Archangel (Gast)


Lesenswert?

Und wie immer ist die richtige Lösung die einfachste.. Ich hab' schon 
über Interrupts, Timer etc gelesen ;)

Entschuldige, dass es solange dauerte, 1ll, und vielen Dank für deine 
Hilfe.

Wie war das eigentlich mit dem "virtuellen Port" gemeint?

MfG Nik

von Karl H. (kbuchegg)


Lesenswert?

Archangel schrieb:

> Wie war das eigentlich mit dem "virtuellen Port" gemeint?

1
#define SWITCH_LED(on,port,pin)  if(on) port |= (1<<pin); else port &= ~(1<<pin);
2
3
int main(void)
4
{
5
  uint8_t Licht = 0;
6
  
7
  ...
8
  
9
  while(1)
10
  {
11
    // realisiere ein umlaufendes 'Lauflicht'
12
    // indem ein Lichtmuster in der Variablen Licht umläuft
13
    if( Licht == 0 )
14
      Licht = 0x05;
15
    else
16
      Licht = Licht << 1;
17
 
18
    // die Bits entsprechend verteilen
19
    SWITCH_LED( Licht & 0x01, PORTD, PD6 );
20
    SWITCH_LED( Licht & 0x02, PORTD, PD7 );
21
    SWITCH_LED( Licht & 0x04, PORTB, PB0 );
22
    SWITCH_LED( Licht & 0x08, PORTB, PB5 );
23
    SWITCH_LED( Licht & 0x10, PORTC, PC3 );
24
    SWITCH_LED( Licht & 0x20, PORTB, PB3 );
25
    SWITCH_LED( Licht & 0x40, PORTD, PD3 );
26
    SWITCH_LED( Licht & 0x80, PORTC, PC2 );
27
28
    delay_ms(70);
29
  }
30
  
31
  return 0;
32
}

Die 'Musterarbeit' selbst findet in der Variablen 'Licht' statt. Dort 
hast du 8 Bits in der natürlichen Reihenfolge und programmierst diese 
Bits so, dass sie das als Lauflicht realisieren, was du haben willst.
Du tust einfach so, als ob du einen 'Port' hättest, an dem die Led in 
der richtigen Reihenfolge bitweise angeordnet sind.
Und dann verteilst du diese sauber angeordneten Bits mit einem 'Treiber' 
an die entsprechenden physikalischen Pins, wobei die abweichende 
Reihenfolge berücksichtigt wird und die Pins entsprechend umsortiert 
angesteuert werden.

Voila: Wenn es darum geht komplizierte Lauflichtmuster zu realisieren, 
hast du einen 'virtuellen' Port, der sich genau so verhält wie man es 
haben möchte - die gedachten Led sind exakt in der richtigen 
Bitreihenfolge angeordnet. Die Anpassung an die reale Hardware geschieht 
in der 'Treiber'-Schicht.

von Archangel (Gast)


Lesenswert?

Vielen Dank für Eure Hilfe, wirklich ausgiebige Antworten :)

MfG Nik

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.