Hi,
I have written code to read using AVR TWI interface. I am interfacing it to DS1307 later. But it is not working. To know execution at specific points I have put LEDs they are interfaced to PORTA.
The problem is instruction after Repeated Start are not working properly. I have checked status code after repeated start it should be 0x10, but it is 0x28 that is displayed on PORTB. I am testing it in Proteus with DS1307. I am reading location from 0x01 to 0x06 of DS1307.
Device ATmega32
IDE AtmelStudio
I have written code to read using AVR TWI interface. I am interfacing it to DS1307 later. But it is not working. To know execution at specific points I have put LEDs they are interfaced to PORTA.
The problem is instruction after Repeated Start are not working properly. I have checked status code after repeated start it should be 0x10, but it is 0x28 that is displayed on PORTB. I am testing it in Proteus with DS1307. I am reading location from 0x01 to 0x06 of DS1307.
Device ATmega32
IDE AtmelStudio
Code:
#include <avr/io.h>
#define RTC_ADDRESS 0b1101000 //7-bit DS1307 address
unsigned char Data[10];
unsigned char SLA_R,SLA_W;
void Initialize(unsigned char TWISlaveAddress)
{
SLA_R = ((TWISlaveAddress << 1) | 0x01);
SLA_W = (TWISlaveAddress << 1);
TWBR = 50; //By default prescalar is 1, TWSR_TWPS1 = 0, TWSR_TWPS0 = 0
TWCR = (1 << TWEN);
}
void Read(unsigned char TWIReadStartAddress, unsigned char TWIReadByteCount, unsigned char *TWIDestinationArrayR)
{
TWCR |= (1 << TWINT) | (1 << TWSTA); //Send START
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
if ((TWSR & 0xF8) == 0x08) //START sent
PORTA |= (1 << PA0);
TWDR = SLA_W;
TWCR |= (1 << TWINT); //Clear TWINT to send SLA_W
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
if ((TWSR & 0xF8) == 0x18) //SLA_W transmitted, ACK received
PORTA |= (1 << PA1);
TWDR = TWIReadStartAddress;
TWCR |= (1 << TWINT); //Clear TWINT to send Address
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
if ((TWSR & 0xF8) == 0x28) //Data byte transmitted, ACK received
PORTA |= (1 << PA2);
//Repeated START
TWCR |= (1 << TWINT) | (1 << TWSTA); //Send Repeated START
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
PORTB = (TWSR & 0xF8);
if ((TWSR & 0xF8) == 0x10) //Repeated START transmitted
PORTA |= (1 << PA3);
TWDR = SLA_R;
TWCR |= (1 << TWINT); //Clear TWINT to send SLA_R
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
if ((TWSR & 0xF8) == 0x40) //SLA_R transmitted, ACK received
PORTA |= (1 << PA4);
TWCR |= (1 << TWEA); //Return ACK after each byte read
unsigned char TWIReadCount;
for (TWIReadCount = 0; TWIReadCount <= (TWIReadByteCount - 1); TWIReadCount++)
{
TWCR |= (1 << TWINT); //Clear TWINT to read (next) Data
while (!(TWCR & (1 << TWINT))); //Wait until TWINT = 1
if ((TWSR & 0xF8) == 0x50) //Data byte received, ACK returned
{
*TWIDestinationArrayR = TWDR;
TWIDestinationArrayR++;
}
}
PORTA |= (1 << PA5);
TWCR &= (~(1 << TWEA)); //Return NACK after last byte read
TWCR |= (1 << TWINT) | (1 << TWSTO); //Send STOP
while(TWCR & (1 << TWSTO)); //Wait until bus release
PORTA |= (1 << PA6);
}
int main()
{
DDRA = 0xFF;
DDRB = 0xFF;
Initialize(RTC_ADDRESS);
Read(0x01, 6, &Data[0]);
return 0;
}