ud23
Advanced Member level 3
- Joined
- Apr 20, 2011
- Messages
- 926
- Helped
- 185
- Reputation
- 370
- Reaction score
- 180
- Trophy points
- 1,323
- Activity points
- 6,138
hi all i m working with the msp430f6779 and external eeprom i used sample I2c code i am able to write eeprom but when i try to read more then one address its give me garbage value.
i am using 1 k pull -up for sda and scl and scl is 100khz.
below is my code
please any one help me whats the problem exactly in above code.
i am using 1 k pull -up for sda and scl and scl is 100khz.
below is my code
Code:
#include "msp430.h"
#include "I2Croutines.h"
int PtrTransmit;
unsigned char I2CBufferArray[50];
unsigned char I2CBuffer;
int tx_byte_count;
unsigned char rx_byte_count;
int tx_byte_counter;
unsigned char rx_byte_counter;
unsigned char i;
unsigned char tx_rx;
int tx_count;
void InitI2C(unsigned char eeprom_i2c_address)
{
I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // Assign I2C pins to USCI_B0
// Recommended initialisation steps of I2C module as shown in User Guide:
UCB1CTLW0 |= UCSWRST; // Enable SW reset
UCB1CTLW0 |= UCMST | UCMODE_3 | UCSSEL_3; // I2C Master, use SMCLK
UCB1BR0= 12; // fSCL = SMCLK/12 = ~100kHz
UCB1BR1 = 0;
UCB1I2CSA = eeprom_i2c_address; // Slave Address is 048h
// UCB1I2COA1 = 0x01A5;
UCB1CTLW0 &= ~UCSWRST; // Clear SW reset, resume operation
UCB1IE |= UCTXIE0; // Enable TX interrupt // defines the control byte that is
UCB1IE |= UCRXIE0; // sent to the EEPROM.
if (UCB1STAT & UCBBUSY) // test if bus to be free
{ // otherwise a manual Clock on is
// generated
I2C_PORT_SEL &= ~SCL_PIN; // Select Port function for SCL
I2C_PORT_OUT &= ~SCL_PIN; //
I2C_PORT_DIR |= SCL_PIN; // drive SCL low
I2C_PORT_SEL |= SDA_PIN + SCL_PIN; // select module function for the
// used I2C pins
}
}
/*---------------------------------------------------------------------------*/
// Description:
// Initialization of the I2C Module for Write operation.
/*---------------------------------------------------------------------------*/
void I2CWriteInit(void)
{
UCB1CTLW0 |= UCTR; // UCTR=1 => Transmit Mode (R/W bit = 0)
UCB1IFG &= ~UCTXIFG0;
UCB1IE &= ~UCRXIE0; // disable Receive ready interrupt
UCB1IE |= UCTXIE0; // enable Transmit ready interrupt
}
/*----------------------------------------------------------------------------*/
// Description:
// Initialization of the I2C Module for Read operation.
/*----------------------------------------------------------------------------*/
void I2CReadInit(void)
{
UCB1CTLW0 &= ~UCTR; // UCTR=0 => Receive Mode (R/W bit = 1)
UCB1IFG &= ~UCRXIFG0;
UCB1IE &= ~UCTXIE0; // disable Transmit ready interrupt
UCB1IE |= UCRXIE0; // enable Receive ready interrupt
}
/*----------------------------------------------------------------------------*/
// Description:
// Byte Write Operation. The communication via the I2C bus with an EEPROM
// (2465) is realized. A data byte is written into a user defined address.
/*----------------------------------------------------------------------------*/
void EEPROM_ByteWrite(unsigned int Address, unsigned char Data)
{
unsigned char adr_hi;
unsigned char adr_lo;
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations.
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[2] = adr_hi; // Low byte address.
I2CBufferArray[1] = adr_lo; // High byte address.
I2CBufferArray[0] = Data;
tx_count =2;
//tx_byte_count = tx_count + 1;
//tx_byte_counter = tx_count;
I2CWriteInit();
UCB1CTLW0 |= UCTXSTT; // start condition generationemain in LPM0 until all data is TX'd
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
// UCB1CTLW0 |= UCTR | UCTXSTT; // => I2C communication is started
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
// __bis_SR_register(LPM0_bits + GIE);
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
}
/*----------------------------------------------------------------------------*/
// Description:
// Random Read Operation. Data is read from the EEPROM. The EEPROM
// address is defined with the parameter Address.
/*----------------------------------------------------------------------------*/
unsigned char EEPROM_RandomRead(unsigned int Address)
{
unsigned char adr_hi;
unsigned char adr_lo;
I2CBuffer =0;
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations
adr_hi = Address >> 8; // calculate high byte
adr_lo = Address & 0xFF; // and low byte of address
I2CBufferArray[1] = adr_hi; // store single bytes that have to
I2CBufferArray[2] = adr_lo;
tx_count =1;
// tx_byte_count = tx_count + 1;
// tx_byte_counter = tx_count;
I2CWriteInit();
UCB1CTLW0 |= UCTXSTT; // start condition generationemain in LPM0 until all data is TX'd
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
// Read Data byte
I2CReadInit();
UCB1CTLW0 |= UCTXSTT; // I2C start condition
while(UCB1CTLW0 & UCTXSTT); // Start condition sent? // Enter LPM0 w/ interrupts
__bis_SR_register(LPM0_bits + GIE);
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
return I2CBuffer;
}
/*----------------------------------------------------------------------------*/
// Description:
// Acknowledge Polling. The EEPROM will not acknowledge if a write cycle is
// in progress. It can be used to determine when a write cycle is completed.
/*----------------------------------------------------------------------------*/
void EEPROM_AckPolling(void)
{
while (UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations
do
{
UCB1STAT = 0x00; // clear I2C interrupt flags
UCB1CTLW0 |= UCTR; // I2CTRX=1 => Transmit Mode (R/W bit = 0)
UCB1CTLW0 &= ~UCTXSTT;
UCB1CTLW0 |= UCTXSTT; // start condition is generated
while(UCB1CTLW0 & UCTXSTT) // wait till I2CSTT bit was cleared
{
if(!(UCNACKIFG & UCB1STAT)) // Break out if ACK received
break;
}
UCB1CTLW0 |= UCTXSTP; // stop condition is generated after
// slave address was sent => I2C communication is started
while (UCB1CTLW0 & UCTXSTP); // wait till stop bit is reset
__delay_cycles(500); // Software delay
}while(UCNACKIFG & UCB1STAT);
}
unsigned char EEPROM_CurrentAddressRead(void)
{
while(UCB1STAT & UCBUSY); // wait until I2C module has
// finished all operations
I2CReadInit();
UCB1CTLW0 |= UCTXSTT; // I2C start condition
while(UCB1CTLW0 & UCTXSTT); // Start condition sent?
UCB1CTLW0 |= UCTXSTP; // I2C stop condition
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupts
while(UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent
return I2CBuffer;
}
#pragma vector = USCI_B1_VECTOR
__interrupt void USCI_B1_ISR(void)
{
if(UCTXIFG0 & UCB1IFG)
{
UCB1TXBUF = I2CBufferArray[tx_count]; // Load TX buffer
tx_count--; //Decrement TX byte counter
if(tx_count < 0)
{
UCB1IE &= ~UCTXIE0;
UCB1IFG &= ~UCTXIFG0; //Clear USCI_B0 TX int flag
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
else if(UCRXIFG0 & UCB1IFG)
{
I2CBuffer = UCB1RXBUF; // store received data in buffer
// UCB1IFG &= ~UCRXIFG0;
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
}
}
please any one help me whats the problem exactly in above code.