BragaD0 0 Posted October 27, 2013 Share Posted October 27, 2013 Hello, I`m trying to use PCF8574N with the MSP430G2553, but with no luck so far. I tried several examples but nothing seems to work. Basically, what i`m trying to do is light up a selected number of LEDs using the PCF8574N, but no matter the value I use in the UCB0TXBUF, P0 to P7 are always on HIGH, please see the code below: #include <msp430.h> int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST+UCMODE_3+UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2+UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x20; // Set slave address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0RXIE; // Enable RX interrupt TACCTL0 = CCIE; // TACCR0 interrupt enabled TACTL = TASSEL_2 + MC_2; // SMCLK, contmode while (1) { __bis_SR_register(CPUOFF + GIE); // CPU off, interrupts enabled UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // CPU off, interrupts enabled while (UCB0CTL1 & UCTXSTT); // Loop until I2C STT is sent UCB0TXBUF = 0x01; //send command byte while(!(UCB0TXIFG)){;} //wait for transmission to finish //UCB0CTL1 |= UCTXSTP; // I2C stop condition after 1st TX } } #pragma vector = TIMER0_A0_VECTOR __interrupt void TA0_ISR(void) { __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } I removed the P1.6 LED Jumper too. I'm really new to MSP430, so if someone could point out what is wrong with the code, or recommend some other code that I could use as example, I would really appreciate it. Thank you, Quote Link to post Share on other sites
shluzzzoid 18 Posted October 28, 2013 Share Posted October 28, 2013 You are assured, what the address correct? Try to use my project: #include "i2c.h" #define SDA BIT7 //P1.7 #define SCL BIT6 //P1.6 #define LED BIT0 //P1.0 void i2c_init(void){ P1DIR |= SCL | SDA | LED; // Set SCL, SDA and LED as Output P1REN |= SCL | SDA; // Set Pull-Ups on SCL and SDA // enable SDA, SCL, SCLK, i2c mode, MSB, output enabled, hold in reset USICTL0 = USIPE7 | USIPE6 | USIMST | USIOE | USISWRST; // USICTL0 Upper 8bit Register of 16bit USICTL Register // USIPE7 = P1.7 USI Mode, i2c SDA enabled // USIPE6 = P1.6 USI Mode, i2c SCL enabled // USIPE5 = P1.5 USI Mode, i2c Clock Input? (Not Set) // USILSB = LSB Mode (Not Set = MSB) // USIMST = Master Mode // USIGE = Output Latch (Not Set = Clock Controlled) // USIOE = Data Output Enable // USISWRST = USI Software Reset (Set to allow changing settings) // SMCLK / 128, and Reverse Clock Polarity USICKCTL = USIDIV_7 + USISSEL_2 + USICKPL; // USICKCTL 8bit USI Clock Control Register // USIDIVx = Clock Divider (Bit7-5, USIDIV_7 = Divide by 128) // USISSELx = Clock Source (For Master Mode, Bit4-2, USISSEL_2 = SMCLK) // USICKPL = Clock Polarity (0 = Inactive Low, 1 = Inactive High) // USISWCLK = Software Clock State // I2C Mode USICTL1 = USII2C; // USICTL1 Lower 8bit Register of 16bit USICTL Register // USICKPH = Clock Phase (0 = Data Changed, then Captured, 1 = Data Captured, then Changed) // USII2C = I2C mode // USISTTIE = START condition Interrupt // USIIE = USI Counter Interrupt // USIAL = Arbitration Lost Notification // USISTP = STOP condition Notification // USISTTIFG = START condition Int. Flag // USIIFG = USI Counter Int. Flag // release from reset USICTL0 &= ~USISWRST; } void i2c_start(void) { // Send i2c START condition USISRL = 0x00; // Load USISRL Lower Byte Shift Register MSB with 0 for i2c START USICTL0 |= USIGE | USIOE; // Force Output Latch, And Enable Data Output Bit (High to Low SDA while SCL is High) USICTL0 &= ~USIGE; // Clear Output Latch (Return to Clock Control) } void i2c_stop(void){ // Prepare i2c STOP condition USICTL0 |= USIOE; // Enable Data Output Bit (Turn SDA into Output) USISRL = 0x00; // Load USISRL Lower Byte Shift Register MSB with 0 for i2c STOP USICNT = 1; // Load USICNT Counter with number of Bits to Send. USIIFG Auto-Cleared // Data TXed by USI I2C while((USICTL1 & USIIFG) != 0x01); // Delay, Wait for USIIFG, Counter down to 0 // Send i2c STOP condition USISRL = 0xFF; // Load USISRL Lower Byte Shift Register MSB with 1 for i2c STOP USICTL0 |= USIGE; // Force Output Latch (Low to High SDA while SCL is High) USICTL0 &= ~USIOE & ~USIGE ; // Clear Data Output Enable Bit and Output Latch (Release SCL) } uint8_t i2c_write8(uint8_t c) { // TX USICTL0 |= USIOE; // Enable Data Output Bit (Turn SDA into Output) USISRL = c; // Load USISRL Lower Byte Shift Register with 8 Bit data (Byte) USICNT = 8; // Load USICNT Counter with number of Bits to Send. USIIFG Auto-Cleared // Data TXed by USI I2C while((USICTL1 & USIIFG) != 0x01); // Delay, Wait for USIIFG, Counter down to 0 // RX // Data TXed. Ready to Receive (n)ACK from i2c Slave USICTL0 &= ~USIOE; // Clear Data Output Enable Bit (Turn SDA into Input) USICNT = 1; // Load USICNT Counter with number of Bits to Receive. USIIFG Auto-Cleared // Data RXed by USI I2C while((USICTL1 & USIIFG) != 0x01); // Delay, Wait for USIIFG, Counter down to 0 c = USISRL; // LSB of USISRL Holds Ack Status of 0 = ACK (0x00) or 1 = NACK (0x01) return c; // Return Data } Quote Link to post Share on other sites
BragaD0 0 Posted October 31, 2013 Author Share Posted October 31, 2013 Hello, Thank you for sharing your code. By using it as a reference I was able to achieve what I needed. Sorry for taking so long to reply. Diego Quote Link to post Share on other sites
jamshi5 0 Posted November 28, 2013 Share Posted November 28, 2013 Dear Noob, Can you please post the corrected code. Me too want to use I2C without using interrupts. 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.