Forum: Mikrocontroller und Digitale Elektronik WS2801 led strip ansteuerung


von Peter (Gast)


Lesenswert?

Guten Tag
Ich möchte einen 1m LED Strip ansteuern (IC darauf: WS2801) dafür habe 
ich ein Programm basierend auf Atmelstudio (Atmega 644). Allerdings 
leuchten dan alle LEDs weiss egal ob ich rot Anteil verstelle oder nur 
eine Farbe einstelle sie leuchten alle weiss.
Hat jemand dazu schon einmal ein TEST-Programm geschrieben? Wen ja hoffe 
ich das ich weiter komme. Das man 500us warten muss konnte ich von dem 
Datenblatt entnehmen.

von 50c (Gast)


Lesenswert?

Quelltext?

von blubb (Gast)


Lesenswert?

Zeile 42

von Peter (Gast)


Lesenswert?

Quellcode:


#include <avr/io.h>
#pragma GCC optimize 0

#define NumberOfLeds 32

unsigned char data[NumberOfLeds][3];

/*********************************************************************** 
***********
*  Wait1s()
*
*Beschreibung:
*Wartet 1 Sekunde.
*
*Rückgabewert:
*keine
*
*Parameter:
*keine
************************************************************************ 
**********/

void Wait1s(void)
{
  unsigned long int ulZaehler;
  for (ulZaehler = 0 ; ulZaehler < 797 ; ulZaehler++)
  {
    asm("nop");
  }
}
/*********************************************************************** 
***********/
void send_RGB(void)
{
  //Clock- und Daten-Leitungen löschen
  PORTA &= ~0xA0;

  for(unsigned char lednum = 0; lednum < NumberOfLeds; lednum++)
  {
    for(unsigned char mask = 0x80; mask; mask >>= 1)
    {
      //Datenleitung setzen oder löschen je nach Tabellen-Inhalt. Pin C1
      if(data[lednum][0] & mask) PORTA |= 0x20; else {PORTA &= 0x20; 
asm("nop");};
      //Clock-Leitung setzen und gleich wieder löschen. Pin C0
      PORTA |= 0x80; PORTA &= ~0x80;
    }

    for(unsigned char mask = 0x80; mask; mask >>= 1)
    {
      if(data[lednum][2] & mask) PORTA |= 0x20; else {PORTA &= 0x20; 
asm("nop");};
      PORTA |= 0x80; PORTA &= ~0x80;
    }

    for(unsigned char mask = 0x80; mask; mask >>= 1)
    {
      if(data[lednum][1] & mask) PORTA |= 0x20; else {PORTA &= 0x20; 
asm("nop");};
      PORTA |= 0x80; PORTA &= ~0x80;
    }
    //Wait1s();
  }
}


int main(void)
{
  DDRA = 0xFF;

  while(1)
  {

    for(unsigned char i = 0; i < NumberOfLeds; i++)
    {
      data[i][0] = 50; //Rot
      data[i][1] = 0; //Grün
      data[i][2] = 0; //Blau
    }



    // SEND DATA TO STRIP 
-------------------------------------------------
    send_RGB();
  }
}

von Markus (Gast)


Lesenswert?

Oben über dem Editor Fenster steht immer, wie Code im MC-Netz zu 
formatieren ist:
1
C-Code

von Markus (Gast)


Lesenswert?

>[c]C-Code[/c ....

von Peter (Gast)


Lesenswert?

1
#include <avr/io.h>
2
#pragma GCC optimize 0
3
4
#define NumberOfLeds 32
5
6
unsigned char data[NumberOfLeds][3];
7
8
/**********************************************************************************
9
*  Wait1s()
10
*
11
*Beschreibung:
12
*Wartet 1 Sekunde.
13
*
14
*Rückgabewert:
15
*keine
16
*
17
*Parameter:
18
*keine
19
**********************************************************************************/
20
21
void Wait1s(void)
22
{
23
  unsigned long int ulZaehler;
24
  for (ulZaehler = 0 ; ulZaehler < 797 ; ulZaehler++)
25
  {
26
    asm("nop");
27
  }
28
}
29
/**********************************************************************************/
30
void send_RGB(void)
31
{
32
  //Clock- und Daten-Leitungen löschen
33
  PORTA &= ~0xA0;
34
  
35
  for(unsigned char lednum = 0; lednum < NumberOfLeds; lednum++)
36
  {
37
    for(unsigned char mask = 0x80; mask; mask >>= 1)
38
    {
39
      //Datenleitung setzen oder löschen je nach Tabellen-Inhalt. Pin C1
40
      if(data[lednum][0] & mask) PORTA |= 0x20; else {PORTA &= 0x20; asm("nop");};
41
      //Clock-Leitung setzen und gleich wieder löschen. Pin C0
42
      PORTA |= 0x80; PORTA &= ~0x80;
43
    }
44
45
    for(unsigned char mask = 0x80; mask; mask >>= 1)
46
    {
47
      if(data[lednum][2] & mask) PORTA |= 0x20; else {PORTA &= 0x20; asm("nop");};
48
      PORTA |= 0x80; PORTA &= ~0x80;
49
    }
50
    
51
    for(unsigned char mask = 0x80; mask; mask >>= 1)
52
    {
53
      if(data[lednum][1] & mask) PORTA |= 0x20; else {PORTA &= 0x20; asm("nop");};
54
      PORTA |= 0x80; PORTA &= ~0x80;
55
    }
56
    //Wait1s();
57
  }
58
}
59
60
61
int main(void)
62
{
63
  DDRA = 0xFF;
64
  
65
  while(1)
66
  {
67
    
68
    for(unsigned char i = 0; i < NumberOfLeds; i++)
69
    {
70
      data[i][0] = 50; //Rot
71
      data[i][1] = 0; //Grün
72
      data[i][2] = 0; //Blau
73
    }
74
    
75
    
76
    
77
    // SEND DATA TO STRIP -------------------------------------------------
78
    send_RGB();
79
  }
80
}

von Markus (Gast)


Lesenswert?

Wie soll den in Deinem Code das erforderliche, Nanosekunden genaue 
Timing eingehalten werden?:

https://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/

von Peter (Gast)


Lesenswert?

Dies ist aber

Markus schrieb:
> Wie soll den in Deinem Code das erforderliche, Nanosekunden genaue
> Timing eingehalten werden?:
>
> https://wp.josh.com/2014/05/13/ws2812-neopixels-ar...

Dies ist aber der WS2812 und ich benötige das für den WS2801 der noch 
eine Clockleitung besitzt.

von yesitsme (Gast)


Lesenswert?

Ich bin mir nicht sicher ob das das macht, was du willst...

PORTA &= 0x20

von Peter (Gast)


Lesenswert?

yesitsme schrieb:
> Ich bin mir nicht sicher ob das das macht, was du willst...
>
> PORTA &= 0x20

was willst du damit sagen?

von yesitsme (Gast)


Lesenswert?

Du löscht jedes Bit ausser das wichtige.

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.