fj604 34 Posted May 29, 2011 Share Posted May 29, 2011 MAX6957 can be a useful tool: a LED driver + I/O expander, giving you 20 ports (PDIP) or 28 port (surface mount) selectable as: - constant current sink LED driver - input - input with pullup - output Here is a demo code for the Launchpad (MSP430G2231) using hardware SPI: /* * Interfacing MSP430G2231 to MAX6957 SPI LED driver and I/O expander Pins MSP430G2231 MAX6957 1 DVCC ----------- 28 V+ 3 P1.1 (CS) ----------- 27 CS 7 P1.5/SCLK ----------- 25 SCLK 8 P1.6/SDO ----------- 26 DIN 9 P1.7/SDI -/\/10K\/\- 4 DOUT 14 DVSS ----------- 2 GND ----------- GND 3 GND ----------- GND 1 ISET -/\/39K\/\- GND 12 P19 ----------- LED1 13 P20 ----------- LED2 14 P21 ----------- LED3 8 P15 ----/ ----- GND Upon startup, LED1-3 will light up for about 1.5 seconds, then LED2-3 will start glowing intermittently. While a button on P15 is pushed, LED1 will change brightness. */ #include #define PIN_CS BIT1 #define DELAY 40000 void spi_init(void) { P1DIR = PIN_CS; // Set CS to output P1OUT = PIN_CS; // CS to high USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE; // SDI enable, SDO enable, SCLK enable, Master mode, Data output enable, release USICTL1 = USICKPH | USIIE; // CKPH = 1, Interrupt Enable USICKCTL = USIDIV_7 | USISSEL_2 ; // Clock / 128, SMCLK; } void timer_init(void) { TACTL = TASSEL_2 | MC_0; // SMCLK, stop timer TACCTL0 = CCIE; // Enable timer compare interrupt } void sleep(unsigned int count) { TACCR0 = count; // Load top value in compare register TACTL |= TACLR | MC_1; // Clear counter, start timer in up mode _low_power_mode_0(); // Sleep in LPM0 until interrupt TACTL &= ~MC_1; // Stop timer } unsigned int cmd(unsigned char addr, unsigned char data) { P1OUT &= ~PIN_CS; // Take CS low USISRH = addr; // Load address to high byte USISRL = data; // Load data to low byte USICNT = USI16B | 16; // 16 bit transfer _low_power_mode_0(); // sleep in LPM0 until interrupt P1OUT |= PIN_CS; // Take CS high return USISR; } void sense(void) { static unsigned char g=0; cmd(0x2F | BIT7, 0); // Turn high bit on to read register 0x2F for port 15 if (!(cmd(0, 0) & BIT0)) // Send No-op command and check bit 0 = button pushed cmd(0x19, g++ << 4); // Increase brightness of LED on port 19 } void leds(unsigned char v) { cmd(0x1A, v | (0x0F-v) << 4); // control brightness of LEDs on ports 20-21 sense(); } void main(void) { signed char i=0; WDTCTL = WDTPW + WDTHOLD; // Disable WDT spi_init(); timer_init(); _enable_interrupts(); cmd(0x0C, 0x00); // set ports 16-19 to LED cmd(0x0D, 0x00); // set ports 20-23 to LED cmd(0x0B, 0xFF); // set ports 12-15 to GPIO Input with pullup cmd(0x33, 0x01); // Port 19 on cmd(0x34, 0x01); // Port 20 on cmd(0x35, 0x01); // Port 21 on cmd(0x07, 0x01); // Display test on _delay_cycles(1500000); // ~ 1.5s pause cmd(0x07, 0x00); // Display test off cmd(0x04, BIT0 | BIT6); // Individual segment current control, normal operation for (; { for (i=0; i<0x10; i++) { leds(i); sleep(DELAY); } for (i=0x0F; i>=0; i--) { leds(i); sleep(DELAY); } } } #pragma vector=USI_VECTOR __interrupt void usi_interrupt(void) { USICTL1 &= ~USIIFG; // Clear interrupt flag _low_power_mode_off_on_exit(); // Return from LPM } #pragma vector=TIMERA0_VECTOR __interrupt void timer_A_interrupt(void) { _low_power_mode_off_on_exit(); // Return from LPM } I figured that a 10K resistor is needed as without it MAX6957 would just stop - but I still cannot figure out why - any ideas? I also have the I2C version - MAX6956 - stay tuned bluehash, timotet and RobG 3 Quote Link to post Share on other sites
gordon 229 Posted July 5, 2011 Share Posted July 5, 2011 I figured that a 10K resistor is needed as without it MAX6957 would just stop - but I still cannot figure out why - any ideas? Might it be this? (Also the MAX6957 data sheet page 7, towards the bottom.) fj604 1 Quote Link to post Share on other sites
fj604 34 Posted July 17, 2011 Author Share Posted July 17, 2011 Might it be this? (Also the MAX6957 data sheet page 7, towards the bottom.) Pardon my ignorance, but if MSP430's SDI is already high impedance (is it?), then why does MAX6957 have to have a 10K resistor on DOUT? (I feel like I am missing something fundamental - like SDI not being high impedance in SPI mode) Quote Link to post Share on other sites
gordon 229 Posted July 18, 2011 Share Posted July 18, 2011 I have not tried reading from it yet. I am leaving DOUT floating while only telling it to glow my blinkies, and it does not seem to cause any ill effect. USI SDI being high impedance isn't mentioned explicitly in SLAU144, but it is mentioned wrt. USCI I2C (p. 458), which may be for a reason or may as well be an omission, I don't know. Try implementing one of the methods in Maxim Appnote 1879 without changing anything else. Does that thaw your 6957? Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.