i have written some configuration function for ATmega168 to read data from TWI communication with DS1307. But i can write to DS1307 not read. Can someone help me.
this are my functions:
void TW_init(void)
{
TWBR = 2;
TWSR = (1 << TWPS1);
TWCR = (1 << TWEN);
}
void TW_start(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while ((TWCR & (1<<TWINT)) == 0);
}
void TW_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void TW_write(uint8_t data)
{
TWDR = data;
TWCR = (1 << TWEN)|(1 << TWINT);
while(!(TWCR & (1 << TWINT)));
}
uint8_t TW_read(void)
{
TWCR = (1<<TWINT)|(1<<TWEN);
while(!(TWCR & (1 << TWINT)));
return TWDR;
}
uint8_t DS1307_Read(uint8_t address)
{
unsigned short r_data;
TW_start();
TW_write(DS1307);
TW_write(address);
TW_start();
TW_write(DS1307 + 1);
r_data = TW_read();
TW_stop();
return r_data;
}
uint8_t DS1307_Write(uint8_t address, uint8_t w_data)
{
TW_start();
TW_write(DS1307);
TW_write(address);
TW_write(w_data);
TW_stop();
}
I tried a lot to correct my configuration functions but i can't find a mistake or what is missing so maybe someone ales can help me with correcting it. I'm testing it in Proteus and it show me that clock has been set.
if more details needed I'll post them.
In DS1307_Read()
you need to assert a "STOP" signal after selecting the address:
uint8_t DS1307_Read(uint8_t address)
{
unsigned short r_data;
TW_start();
TW_write(DS1307);
TW_write(address);
TW_stop(); // <-- STOP
TW_start();
TW_write(DS1307 + 1);
r_data = TW_read();
TW_stop();
return r_data;
}
Since this is a DS1307 specific interface rather then generic I2C read, it would be more efficient to perform a sequential read/write of the entire time/date data as in this example