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:
Code:
// 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
}
}
Die Software lief mit allen Optimierungsstufen 0,1,2 und 3 des Compilers: XC8 V2.05
Siro
Lesezeichen