So i am trying to establish a connection between ATMEGA328p as Master and 24LC256 EEPROM Chip using I2C protocol.
- Clock is set to 100KHz
- SDA and SCK lines are pulled up to Vcc using 4.7K Ohm resistors,
- Start condition works fine, i get a ACK in return too,
- ACK received when the right address is sent,
- Fails when MSB of the address in the chip is sent!
Code:
#define FOSC 16000000UL
#define START 0x08
#define MT_SLA_ACK 0x18
#define MT_SLA_NACK 0x18
#define DEV_ADDR 0x50
typedef enum result_t{FAIL, SUCCESS}result;
void Debug_LED_ON()
{
PORTD|=1<<PD4; //Turn on LED on PIN4 of PORTD
}
void set_clock(int freq_in_khz)
{
TWCR = 1<<TWEN; //Enable TWI module
TWSR |=(1<<TWPS0); //Prescaler set to 4
TWBR = FOSC/freq_in_khz;
TWBR -= 16;
TWBR /= 8; //2*Prescaler_value
}
void send_start()
{
TWCR= ( (1<<TWINT) | (1<<TWEN) | (1<<TWSTA) ); //send START
while( !(TWCR & (1<<TWINT)) ) ; //wait for TWINT flag SET
}
void send_stop()
{
TWCR= ( (1<<TWINT) | (1<<TWEN) | (1<<TWSTO) ); //send STOP
//while( !(TWCR & (1<<TWINT)) ) ; //wait for TWINT flag SET
}
result check_start_status()
{
if ((TWSR & 0xF8) == START )
return SUCCESS;
else
return FAIL;
}
void send_address(char addr_w)
{
TWDR=addr_w; //7bit address + W bit (write bit)
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit to start transmission of address
while (!(TWCR &(1<<TWINT))); //wait for TWINT flag SET
}
result check_MT_slave_ack()
{
if ((TWSR & 0xF8) == MT_SLA_ACK )
return SUCCESS;
else
return FAIL;
}
result check_MT_slave_nack()
{
if ((TWSR & 0xF8) == MT_SLA_NACK )
return SUCCESS;
else
return FAIL;
}
void transmit_data(char data)
{
TWDR=data;
TWCR = (1<<TWINT) | (1<<TWEN); //Clear TWINT bit to start transmission of Data on the bus
while (!(TWCR &(1<<TWINT))); //wait for TWINT flag SET
}
int main (void)
{
DDRC=0xff;
PORTC=0x30; //Enable internal pullups on PORTC PINS SDA(PC4) , SCL(PC5)
DDRD=0xFF; //Port D as output
set_clock(100); //setting clock 100KHz
send_start();
if(check_start_status()==FAIL)
Debug_LED_ON();
send_address(DEV_ADDR << 1);
if(check_MT_slave_ack()==FAIL)
Debug_LED_ON();
transmit_data(0x00);
if(check_MT_slave_ack()==FAIL) //fails here!
Debug_LED_ON();
return 0;
}
Guess somethings wrong with the code, or the way i send the address! A2,A1,A0 bits of 24LC256 are set to ground, therefore the device address is 0x50 << 1.
Update:
The device address is correctly sent now, now when i send the MSB of Address on the chip where i want to write data, it fails!