I'm building an I2C function to read slave devices in the next format: Start > Address Slave + W > A > Register> A> Repeated Start> Address Slave + R > A > DATA > NACK > STOP , but my code is behaving as follows : Start > Address Slave + W > A > Register> A> Repeated Start> Address Slave + R > A > DATA >NacK > Repeated Start I'd like to if I'm missing something important, I'm using as guide the file "slau412d". Regards #include typedef enum { writeReg, writeData, readI2C, stop,readReg, inactive, readData } cmd_; cmd_ i2cStatus=inactive; unsigned char I2Creg; unsigned char *PTxData; // Pointer to TX data volatile unsigned char TXByteCtr; void i2c_init(void){ WDTCTL = WDTPW + WDTHOLD; // Stop WDT 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; UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB0TXIE + UCB0RXIE; // Enable TX interrupt } void readBytes(unsigned char address,unsigned char reg,unsigned char * data,unsigned char length){ i2cStatus=readReg; I2Creg=reg; UCB0I2CSA = address; // Slave Address is 048h // TX array start address while (UCB0CTL1 & UCTXSTP); UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition UCB0TXBUF = I2Creg; __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts } void writeByte(unsigned char address,unsigned char reg,unsigned char data){ i2cStatus=writeReg; I2Creg=reg; UCB0I2CSA = address; // Slave Address is 048h PTxData = &data; // TX array start address TXByteCtr = 1; // Load TX byte counter while (UCB0CTL1 & UCTXSTP); UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts } void writeBytes(unsigned char address,unsigned char reg,unsigned char *data){ i2cStatus=writeReg; I2Creg=reg; UCB0I2CSA = address; // Slave Address is 048h PTxData = data; // TX array start address TXByteCtr = sizeof data; // Load TX byte counter while (UCB0CTL1 & UCTXSTP); UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts } unsigned char TxData[2] = // Table of data to transmit { 0x11,0x15 }; unsigned char buff[23]; int main(void) { // set up bit 0 of P1 as output i2c_init(); readBytes(0x12,0x02,buff,3); while (1) { //writeByte(0x4e,0x09,0x03); } } unsigned char data=0; //------------------------------------------------------------------------------ // The USCIAB0TX_ISR is structured such that it can be used to transmit any // number of bytes by pre-loading TXByteCtr with the byte count. Also, TXData // points to the next byte to transmit. //------------------------------------------------------------------------------ #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) #else #error Compiler not supported! #endif { if(UCB0STAT & UCNACKIFG){ i2cStatus=stop; } switch(i2cStatus){ case writeData: if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag i2cStatus=inactive; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 } break; case writeReg: UCB0TXBUF = I2Creg; i2cStatus=writeData; break; case readData: data=UCB0RXBUF; UCB0CTL1 |= UCTXSTP; break; case readReg: IFG2 &= ~ UCB0RXIFG ; UCB0CTL1 |= UCTXSTT; UCB0CTL1 &= ~UCTR; i2cStatus=readData; break; case stop: UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0RXIFG; // Clear USCI_B0 TX int flag i2cStatus=inactive; __bic_SR_register_on_exit(CPUOFF); // Exit LPM0 break; } }
↧