This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I want to communicate with more than 2 micro-controllers by using i2c protocol but transmit byte and receive byte doesn't match.please help me to complete communication.3835.I2C.h
#include "I2C.h" void I2C_Init(void) { OUTP &= ~(SDA | SCL); DIR &= ~(SDA | SCL); } void I2C_Start(void) { DIR &= ~(SDA | SCL); DIR |= SDA; DIR |= SCL; } void I2C_Restart(void) { unsigned int i=0; DIR &= ~SDA; DIR &= ~SCL; i<<=1; DIR |= SDA; i<<=1; DIR |= SCL; } void I2C_Stop(void) { unsigned int i=0; DIR |= SDA; i<<=1; DIR &= ~SCL; i<<=1; DIR &= ~SDA; } void I2C_TX_Byte(char byte) { unsigned char n, mask = 0x80; extern unsigned int menu; for(n=0;n<8;n++) { if((byte & mask) != 0) { DIR &= ~SDA; DIR &= ~SCL; DIR |= SCL; } else { DIR |= SDA; DIR &= ~SCL; DIR |= SCL; } mask >>= 1; } DIR &= ~SDA; n = 0; while((IN & SDA)!= 0) { n++; if(n == 100) break; } OUTP |= SCL; OUTP &= ~SCL; DIR |= SDA; return; } // Master receive a byte via I2C from slave unsigned char I2C_RX_Byte(int ack) { unsigned int mask; unsigned char retval=0; unsigned int i=0; DIR &= ~SDA; for(mask=0x80; mask; mask >>=1) { i<<=1; DIR &= ~SCL; if(IN & SDA) { retval |= mask; } i<<=1; DIR |= SCL; } if(ack) { DIR |= SDA; } i<<=1; DIR &= ~SCL; i<<=1; DIR |= SCL; DIR &= ~SDA; return retval; } unsigned char I2C_Read(char addr, char reg_addr) { unsigned char retval=0x00; addr <<=1; addr &= 0xFE; I2C_Start(); I2C_TX_Byte(addr); I2C_TX_Byte(reg_addr); I2C_Restart(); addr |= 0x01; //LSB to 1 for read I2C_TX_Byte(addr); retval = I2C_RX_Byte(1); I2C_Stop(); return retval; } unsigned char I2C_Read1(char addr,char addr1, char reg_addr) { unsigned char retval=0x00; addr <<=1; addr &= 0xFE; I2C_Start(); I2C_TX_Byte(addr); I2C_TX_Byte(addr1); I2C_TX_Byte(reg_addr); I2C_Restart(); addr |= 0x01; //LSB to 1 for read I2C_TX_Byte(addr); I2C_TX_Byte(addr1); retval = I2C_RX_Byte(1); I2C_Stop(); return retval; } void I2C_Write(char addr, char reg_addr, char txdata) { addr <<=1; addr &= 0xFE; I2C_Start(); I2C_TX_Byte(addr); I2C_TX_Byte(reg_addr); I2C_TX_Byte(txdata); I2C_Stop(); } void I2C_Write1(char addr, char reg_addr, char txdata, char txdata2) { addr <<=1; addr &= 0xFE; I2C_Start(); I2C_TX_Byte(addr); I2C_TX_Byte(reg_addr); I2C_TX_Byte(txdata); I2C_TX_Byte(txdata2); I2C_Stop(); }
I take it you have provided I2C master bit-banging code? Can you provide some examples of the transmitted bytes vs what is received? Why have you chosen not to use the USCI_B peripheral? Do you have any oscilloscope or logic analyzer screenshots of your communication lines?
Regards,
Ryan
I already use this USCI_B peripheral but master doesn't receive any byte. (Receiving code doesn't work and it doesn't receive any value).I want to communicate with multiple slave from one master.please help me to resolve this problem.
thankyou.
MSP430F532x Demo - USCI_B0 I2C Master RX multiple bytes from MSP430 Slave // // Description: This demo connects two MSP430's via the I2C bus. The slave // transmits to the master. This is the MASTER CODE. It continuously // receives an array of data and demonstrates how to implement an I2C // master receiver receiving multiple bytes using the USCI_B0 TX interrupt. // ACLK = n/a, MCLK = SMCLK = BRCLK = default DCO = ~1.045MHz // // ***to be used with "MSP430F532x_uscib0_i2c_11.c" together*** // // /|\ /|\ // MSP430F5529 10k 10k MSP430F5529 // slave | | master // ----------------- | | ----------------- // -|XIN P3.0/UCB0SDA|<-|----+->|P3.0/UCB0SDA XIN|- // | | | | | // -|XOUT | | | XOUT|- // | P3.1/UCB0SCL|<-+------>|P3.1/UCB0SCL | // | | | | // // Bhargavi Nisarga // Texas Instruments Inc. // April 2009 // Built with CCSv4 and IAR Embedded Workbench Version: 4.21 //****************************************************************************** #include <msp430.h> unsigned char *PRxData; // Pointer to RX data unsigned char RXByteCtr; volatile unsigned char RxBuffer[128]; // Allocate 128 byte of RAM int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x03; // 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 = 0x48; // Slave Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCRXIE; // Enable RX interrupt while (1) { PRxData = (unsigned char *)RxBuffer; // Start of RX buffer RXByteCtr = 5; // Load RX byte counter while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT; // I2C start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until all data // is RX'd __no_operation(); // Set breakpoint >>here<< and } // read out the RxBuffer buffer } //------------------------------------------------------------------------------- // The USCI_B0 data ISR is used to move received data from the I2C slave // to the MSP430 memory. It is structured such that it can be used to receive // any 2+ number of bytes by pre-loading RXByteCtr with the byte count. //------------------------------------------------------------------------------- #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData if (RXByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB0RXBUF; // Move final RX data to PRxData __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU } break; case 12: break; // Vector 12: TXIFG default: break; } }
MSP430F532x Demo - USCI_B0 I2C Slave TX multiple bytes to MSP430 Master // // Description: This demo connects two MSP430's via the I2C bus. The slave // transmits to the master. This is the slave code. The interrupt driven // data transmission is demonstrated using the USCI_B0 TX interrupt. // ACLK = n/a, MCLK = SMCLK = default DCO = ~1.045MHz // // ***to be used with "MSP430F532x_uscib0_i2c_10.c" together*** // // /|\ /|\ // MSP430F5529 10k 10k MSP430F5529 // slave | | master // ----------------- | | ----------------- // | P3.0/UCB0SDA|<-|----+->|P3.0/UCB0SDA | // | | | | | // | | | | | // | P3.1/UCB0SCL|<-+------>|P3.1/UCB0SCL | // | | | | // // Bhargavi Nisarga // Texas Instruments Inc. // April 2009 // Built with CCSv4 and IAR Embedded Workbench Version: 4.21 //****************************************************************************** #include <msp430.h> unsigned char *PTxData; // Pointer to TX data const unsigned char TxData[] = // Table of data to transmit { 0x11, 0x22, 0x33, 0x44, 0x55 }; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P3SEL |= 0x03; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMODE_3 + UCSYNC; // I2C Slave, synchronous mode UCB0I2COA = 0x48; // Own Address is 048h UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCTXIE + UCSTPIE + UCSTTIE; // Enable STT and STP interrupt // Enable TX interrupt while (1) { PTxData = (unsigned char *)TxData; // Start of TX buffer __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts // Remain in LPM0 until master // finishes RX __no_operation(); // Set breakpoint >>here<< and } // read out the TXByteCtr counter } //------------------------------------------------------------------------------ // The USCI_B0 data ISR TX vector is used to move data from MSP430 memory to the // I2C master. PTxData points to the next byte to be transmitted, and TXByteCtr // keeps track of the number of bytes transmitted. //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // The USCI_B0 state ISR TX vector is used to wake up the CPU from LPM0 in order // to do processing in the main program after data has been transmitted. LPM0 is // only exit in case of a (re-)start or stop condition when actual data // was transmitted. //------------------------------------------------------------------------------ #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: // Vector 6: STTIFG UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag break; case 8: // Vector 8: STPIFG UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 if data was transmitted break; case 10: break; // Vector 10: RXIFG case 12: // Vector 12: TXIFG UCB0TXBUF = *PTxData++; // Transmit data at address PTxData break; default: break; } }
**Attention** This is a public forum