Forum: Mikrocontroller und Digitale Elektronik Brauche Hilfe beim Multiplexen mit Schieberegister (74hc595)


von T0m (werwolf92)


Angehängte Dateien:

Lesenswert?

Moin,

vorab bitte keine Kritik an der Schaltung selbst (außer sie hilft bei 
meinem Problem). (funktioniert btw hervorragend)
Die Schaltung habe ich mit Absicht so gewählt, weil ich mit den 
Bauelementen und den Programmiercode so üben möchte.
(Wenn ichs schnell und leicht haben wollte, würde ich auch andere 
Komponenten wählen).

So zu meinem Problem.
Das was die Schaltung aktuell kann ist das alle 5 RGB LEDs den selben 
Farbwechsel haben.
Was ich aber noch zusätzlich möchte ist das jede RGB LED einen eigenen 
Farbwechsel hat. Quasi LED1 geht grad von blau zu lila, LED 2 von rot zu 
gelb usw.

Allerdings wie kann ich denn sowas am besten "maskieren"?
Sowie ich es aktuell habe, habe ich es ja sehr leicht, da die Maske dazu 
einfach ist, da sich alle ändern und somit ich alle Pins gleichzeitig 
lösche oder setze.

Wie stelle ich es denn am schlauesten an, das jede LED ihr eigenes PWM 
mit Farbwechsel über die Schieberegister bekommt?

Ich suche btw keine fertige Lösung sondern nur den Ansatz dazu. Der 
Groschen fällt aktuell noch nicht.

Ich hoffe ich habe es verständlich erklärt.

Vielen Dank schonmal!

Gruß
T.

Edit: Am Atmega ist ein 20MHz Quarz

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Betrachte die beiden SRs einfach als 16-Bit-Port.
Als Portregister legst du eine unsigned int Variable an.
Schreib dir eine ISR, die im Hintergrund diese Variable auf die SRs 
schiebt. Erst das Highbyte, dann das Lowbyte sendet und dann den Latch 
Up macht. Die Übertragung mußt du nach der Initialisierung nur einmal 
anschubsen. Die SPI-Geschwindigkeit setzt du soweit runter, daß noch 
genug Rechenzeit übrig bleibt für die anderen Sachen. Bei Fullspeed 
kommt er praktisch gar mehr raus aus dem Interrupt.

Deine Leds sind jetzt Bitpositionen in deinem Portregister. Das benutzt 
du genau so, wie du jeden anderen Port auch benutzt. Abgesehen davon, 
daß der jetzt 16 Bit breit ist.

Ob da SRs hinterhängen oder kleine grüne Männchen Kerzen anzünden, 
interessiert dich ab jetzt überhaupt nicht mehr.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Du hast 5 LEDs.

Behandle alle 5 LEDs parallel in eigenem Code, mit einer 3-Bit-Struktur 
(oder auch bytes, wenn RAM egal;
1
typedef struct
2
{
3
unsigned char rot;
4
unsigned char gruen;
5
unsigned char blau;
6
}TLed;
7
TLed L1, L2, L3, L4, L5;
8
9
/* code fuer L1 */
10
   L1.rot = 0;
11
   ....
12
   L1.gruen = 1;
13
   ... 
14
/* dito fuer L2 */
15
16
/* Dann packe am Ende die Bits in eine 16-Bit struktur */
17
18
typedef struct
19
{
20
   unsigned char L1_rot  :1;
21
   unsigned char L1_gruen:1;
22
   unsigned char L1_blau :1;
23
24
   unsigned char L2_rot  :1;
25
   unsigned char L2_gruen:1;
26
   unsigned char L2_blau :1;
27
   ...
28
   unsigend char L5_blau :1;
29
}TLeds;
30
31
TLeds Leds;
32
33
   Leds.L1_rot   = L1.rot;
34
   Leds.L1_gruen = L1.gruen;
35
   ...
36
   Leds.L5_blau  = L5.blau;
37
38
   und versende die 2 Leds-Bytes.

Ja, man könnte hier optimieren und ganze Strukturen kopieren... Aber bei 
16 Zeilen ("Leds.L1_rot = L1.rot") ist der Nutzen gering.
Bleibt noch sehr viel kopierter Code fuer die einzelnen LEDs ...
a) Spendiere der TLed-Struktur noch einen "Zustand", z.B int State.
b) Mache eine Funktion "void LedState(TLed *Led, int change);", die 
abhängig von "change" z.B. die nächste Farbe einträgt, oder bleibt (wenn 
change = 0).
c) Rufe LedState für jede Led mit verschiedenen "change" auf. Oder mache 
"change" von Taster 1 bis 5 abhängig, oder oder oder

von T0m (werwolf92)


Lesenswert?

Moin,

Danke euch zwei schonmal!

ich habe ungefähr glaub ich verstanden was ihr meint!
Ich glaube aber ich mache es ein wenig umständlicher...
Musste mir grad erstmal typedef struct angucken was dies genau ist....^^

Habe nun folgendes erstmal erstellt:
1
#define maskeLed1Rot  0b0000000000000001
2
#define maskeLed2Rot  0b0000000000001000
3
#define maskeLed3Rot  0b0000000001000000
4
#define maskeLed4Rot  0b0000001000000000
5
#define maskeLed5Rot  0b0001000000000000
6
7
#define maskeLed1Green  0b0000000000000010
8
#define maskeLed2Green  0b0000000000010000
9
#define maskeLed3Green  0b0000000010000000
10
#define maskeLed4Green  0b0000010000000000
11
#define maskeLed5Green  0b0010000000000000
12
13
#define maskeLed1Blue  0b0000000000000100
14
#define maskeLed2Blue  0b0000000000100000
15
#define maskeLed3Blue  0b0000000100000000
16
#define maskeLed4Blue  0b0000100000000000
17
#define maskeLed5Blue  0b0100000000000000
18
19
#define maskeLed1Start  maskeLed1Blue    // Blau
20
#define maskeLed2Start  0b0000000000110000   // Grün und blau
21
#define maskeLed3Start  maskeLed3Green    // Grün
22
#define maskeLed4Start  0b0000011000000000  // rot und grün
23
#define maskeLed5Start  maskeLed5Rot    // rot
24
25
uint16_t volatile    maskeStart = (maskeLed1Start|maskeLed2Start|maskeLed3Start|maskeLed4Start|maskeLed5Start),
26
            maske0NextUp =  (maskeLed1Rot|maskeLed3Blue|maskeLed5Green),
27
            maske0NextDown = (maskeLed2Blue|maskeLed4Rot);

und dann erst mal so eingefügt:
1
  if(firstTry)
2
  {
3
    for(counter=0;counter<maxCount;counter++)
4
    if(fade < counter)
5
    {
6
      data |= (maskeStart);
7
      SPI_DATA((data));
8
    }
9
    
10
    else
11
    {
12
      data &= ~(maskeStart);
13
      SPI_DATA((data));
14
    }
15
    
16
    if((maxCount-1) == fade)
17
    {
18
      firstTry = false;
19
      fade=0;
20
    }
21
  }
22
23
/******************************************Step 1*/
24
25
  else if(next == 0 && firstTry== false)
26
  {
27
    for(counter=5;counter<maxCount;counter++)
28
    {
29
      
30
      if(fade <= counter)
31
      {
32
        data |= (maske0NextUp);
33
        data &= ~(maske0NextDown);
34
        SPI_DATA((data));
35
      }
36
      
37
      else
38
      {
39
        data |= (maske0NextDown);
40
        data &= ~(maske0NextUp);
41
        SPI_DATA((data));
42
      }
43
    }
44
  }
Funktioniert sogar!

Ich denke aber ich werde es versuchen nach dem Prinzip von Achim machen.
Ich habe nämlich noch nie etwas mit typedef struct gemacht und es ist ja 
auch "nur" ein Übungsprojekt.

Wenn ich nochmal mal Hilfe, meld ich mich nochmal! Vielen dank :)

: Bearbeitet durch User
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.