Angesteuert wird bei mir mit einen Microchip PIC12F1840
Der PIC benötigt nur 3 Anschlüsse
PIN 1 = VCC
PIN 2 = Datenausgang ==> zu DIN der RGB Led/Kette
PIN 8 = MASSE
Das wars schon an Hardware.
Testleds waren:
SK6812 Side Led 4020 Eckstein Komponete Art.Nr.: LED0006-10
SK6812 Mini 3535 led-stübchen Art.Nr.: SK6812_144strip_x50cm
WS2812 2020 led-stübchen Art.Nr.: WS2812_2020_x10
WS2812 5050 RGB Stripe 5050 irgendwo mal bei Ebay bestellt...
Segor LED8 RGB/WS2812B runde LED, wobei hier rot und grün vertauscht ist.
!! Bei Segor gibt es ein ein RGB-Stripe IP67 geschützt, die haben ein Problem:
Der Power On Reset funktioniert nicht, beim Einschalten gehen alle LEDs mit voller Helligkeit an. (2,7 Ampere)
Artikel: PixelLight 1m-144x/IP67w
Hier die "erprobte" Software mit den Grundfunktionen:
Die Software lief mit allen Optimierungsstufen 0,1,2 und 3 des Compilers: XC8 V2.05Code:// Beispielcode für den Microchip PIC Controller PIC12F1840 // grundlegende Ansteuerung einer RGB Kette: // Autor: SIRO 20.08.2019 // // PIN 1 = VCC // PIN 2 = Datenausgang ==> zu DIN der RGB Led/Kette // PIN 8 = MASSE // // An Pin2 (Port RA5) vom Controller wird die Datenleitung der RGB Kette angeschlossen // // PIC12F1840 Configuration Bit Settings // 'C' source line config statements // CONFIG1 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = ON // Watchdog Timer Enable (WDT enabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled) #pragma config CLKOUTEN = OFF // Clock /Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = ON // Internal/External Switchover (Internal/External Switchover mode is enabled) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) // CONFIG2 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = ON // PLL Enable (4x PLL enabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) /* !!!!!!!!!!!!! B O E S E F A L L E */ /* !!!!!!!!!!! LVP muss off sein, sonst kann MCLRE NICHT OFF sein ??????*/ /* Der PIC reagiert dann immer auf den MCLR Pin mit einem RESET */ /* wahelt selbst den richtigen Header aus pic12F1840.h */ /* xc.h includiert htc.h pic.h pic_chip_select.h pic12f1840.h */ #include <xc.h> // wird für die von Microchip zur Verfügung gestellten delays benötigt #define _XTAL_FREQ 32000000 /*----------------------------------------------------------------------*/ /* hier habe ich meine eigenen Datentypen definiert: ein "U" bedeutet unsigned, also ohne Vorzeichen ein "S" bedeutet signed, also mit Vorzeichen ein U8 ist ein 8 Bit Wert ohne Vorzeichen Wertebereich 0..255 ein S8 ist ein 8 Bit Wert mit Vorzeichen Wertebereich -127..+128 */ typedef unsigned char U8; /* 8 Bit ohne Vorzeichen */ typedef signed char S8; /* 8 Bit mit Vorzeichen */ /*----------------------------------------------------------------------*/ /* im INTCON Register gibt es ein globales Interrupt Einschaltbit GIE */ /* wird dieses Bit auf High (1) gesetzt, sind Interrupts erlaubt */ /* wird dieses Bit auf Low (0) gesetzt, sind ALLE Interrupt gesperrt */ #define ENABLE (GIE=1) /* global interrupt enable */ #define DISABLE (GIE=0) /* global interrupt disable */ /*----------------------------------------------------------------------*/ // so viele LEDs sollen in der Kette angesteuert werden #define LED_COUNT 16 /* Jede LED hat 3 Bytes, also 24 Bits fuer die Daten */ typedef struct // __pack ? weil wir keinen Speicher verschwenden wollen { U8 green; /* 8 Bit fuer die Helligkeit */ U8 red; /* 8 Bit fuer die Helligkeit */ U8 blue; /* 8 Bit fuer die Helligkeit */ } TLed; /* Type Bezeichner ist TLed */ TLed LedArray[LED_COUNT]; // Das komplette LED Array (Datenstrom) /*----------------------------------------------------------------------------*/ // schiebt die gesamte Ledkette aus // Das Timing wurde mit NOPs angepasst void LedShiftOut(void) { U8* leds = (U8*)LedArray; U8 count = LED_COUNT; U8 one_byte; S8 bit_count; // damit keine Multiplikation verwendet wird: count = (count << 1) + count; // 3 Bytes pro Led RGB DISABLE; // alle Interrupts sperren while (count) { CLRWDT(); // den Watchdog bedienen, falls erforderlich one_byte = *leds++; // aktuelles Datenbyte laden // 8 Bits durchlaufen: for (bit_count = 0; bit_count < 8; bit_count++) { if (one_byte & 0x80) // wenn das oberste Bit 7 gesetzt ist dann { LATA5 = 1; // lange High Phase einleiten NOP(); // Signal verlängern NOP(); NOP(); LATA5 = 0; // High Phase beenden } else // Kurze High Phase weil das Datenbit Low ist { LATA5 = 1; // kurze High Phase einleiten NOP(); // Signal verlängern LATA5 = 0; // High Phase beenden } one_byte <<= 1; // Das Datenbyte 1 mal links verschieben } count--; // Anzahl auszugebener Datenbytes -1 } ENABLE; // Interrupt wieder einschaalten // Das Ende des Datenstroms wird mit einem "längerem" Low signalisiert // Die Länge ist unterschiedlich bei verschiedenen LEDs. Siehe Datenblatt __delay_us(280); // Das Ende der Datenübertragung erreicht wenn die Leitung länger als xxx Low bleibt. } /*----------------------------------------------------------------------------*/ // fuellt die gesamte Ledkette mit den übergebenen Werten void FillLeds(U8 r,U8 g,U8 b) { U8 i; for (i=0; i < LED_COUNT; i++) { LedArray[i].red = r; LedArray[i].green = g; LedArray[i].blue = b; } LedShiftOut(); } /*----------------------------------------------------------------------------*/ void init_system(void) { /* internal oszillator block 32 MHz / 4 stage pipeline = 8 MHz ==> 125ns Instruction cycle */ SCS0 = 0; /* OSCON register */ SCS1 = 0; SPLLEN = 1; /* is ignored if config enables the PLL */ /* MF 500 KHz default on reset */ /* set to 8MHz value ==> 32Mhz clock with PLL */ IRCF0 = 0; /* OSCON register */ IRCF1 = 1; IRCF2 = 1; IRCF3 = 1; /* !!!! alle ports stehen auf ADU input nach einem reset */ /* wir stellen sie um auf normale input/output funktion */ ANSELA = 0; /* 0 ==> normal Digital IO */ /* Pin Direction */ TRISA5 = 0; /* Datenausgang fuer die RGB LED 0=output */ } /*---------------------------------------------------------------*/ // wird nicht unbedingt benötigt // alle LEDs ausschalten void LedInit(void) { U8 i; for (i = 0; i < LED_COUNT; i++) { LedArray[i].green = 0x00; LedArray[i].red = 0x00; LedArray[i].blue = 0x00; } } /*----------------------------------------------------------------------------*/ void main(void) { init_system(); while (1) { // die gesamte LED Kette mit einer Farbe füllen FillLeds(0x00,0x00,0xFF); __delay_ms(1000); FillLeds(0x00,0xFF,0x00); __delay_ms(1000); FillLeds(0xFF,0x00,0x00); __delay_ms(1000); FillLeds(0x00,0xFF,0xFF); __delay_ms(1000); FillLeds(0xFF,0xFF,0x00); __delay_ms(1000); FillLeds(0xFF,0x00,0xFF); __delay_ms(1000); FillLeds(0xFF,0xFF,0xFF); __delay_ms(1000); // so kann man auf jede einzelne LED und der entsprechenden Farbe zugreifen: // wir stellen hier die RGB Werte für erste LED in der Kette ein: // Zählung der LEDs von 0..x LedArray[0].red = 127; // halbe Helligkeit für rot LedArray[0].green = 64; // viertel Helligkeit fuer grün LedArray[0].blue = 0xFF; // volle Helligkeit für blau LedShiftOut(); // es werden immer ALLE LED Daten ausgeschoben __delay_ms(5000); // warte 5 Sekunden } }
Siro







Zitieren
Lesezeichen