Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

MSP430G2553 DCOCTL/BCSCTL1 weirdness with ws2812b leds

$
0
0

Hi,

 

I'm trying to drive 15 ws2812b leds using a g2553 sitting on a Launchpad

 

I'm finding the following behaviour a bit confusing and am wondering if anyone can provide an explanation...

 

The code below is borrowed from RobG's post (http://forum.43oh.com/topic/2680-group-buy-10-o-rgb-smd-led-with-built-in-controller/page-4#entry23841 )

 

If I try to run at 16MHz the strip does not behave/work as expected

BCSCTL1 = CALBC1_16MHZ;
DCOCTL = CALDCO_16MHZ;

However, if I set DCOCTL to CALDCO_1MHZ and keep BCSCTL1 at CALBC1_16MHZ (see code below) , the strip works fine...

 

Is the clock calibration on my G2553 shot? How would one reset this?

#include <msp430g2553.h>
typedef unsigned char u_char;
typedef unsigned int u_int;
typedef struct {
	u_char r;
	u_char g;
	u_char b;
} RGBLED;
#define DATA_OUT_PIN BIT7
void sendRGB(u_char numberOfLEDs);
RGBLED data[15] = { 0, }; // 0.5m strip
void main(void) {
	WDTCTL = WDTPW + WDTHOLD;
	BCSCTL1 = CALBC1_16MHZ;
	DCOCTL = CALDCO_1MHZ;
	// setup USIB
	P1SEL |= DATA_OUT_PIN;
	P1SEL2 |= DATA_OUT_PIN;
	UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master
	UCB0CTL1 |= UCSSEL_2; // SMCLK
	UCB0BR0 |= 0x03; // 1:3 - 16MHz/3 = 0.1875us
	UCB0BR1 = 0;
	UCB0CTL1 &= ~UCSWRST;
	u_char x = 0;
	u_char dir = 1;
	while (1)
	{
		u_char c = 0;
		while (c < 14) {
			data[c].r = x; //x << 3;
			data[c].b = x; //127 - (x << 3);
			data[c].g = x; //255 - (x << 3);
			data[c+1].r = 255 - x;
			data[c+1].b =255 - x ;
			data[c+1].g =255 - x;
			c+=2;
		}
		sendRGB(15);
		__delay_cycles(100000);
		if (dir) {
			x++;
			if (x == 0xFF)
				dir = 0;
		}
		else {
			x--;
			if (x == 0)
					dir = 1;
		}
	}
}
void sendRGB(u_char numberOfLEDs) {
	u_int c = 0;
	u_char led = 0;
	u_char leds[3];
	u_char d;
	while (c < numberOfLEDs) {
		leds[0] = data[c].g;
		leds[1] = data[c].r;
		leds[2] = data[c].b;
		while (led < 3) {
			u_char b = 0;
			d = leds[led];
			while (b < 8) {
				while (!(IFG2 & UCB0TXIFG))
					;
				(d & 0x80) ? (UCB0TXBUF = 0xF0) : (UCB0TXBUF = 0xC0);
				d <<= 1;
				b++;
			}
			led++;
		}
		led = 0;
		c++;
	}
	__delay_cycles(800); // delay 50us to latch data, may not be necessary
}

Thanks for any pointers

Naren


Viewing all articles
Browse latest Browse all 2077

Trending Articles