Need help in TWI read routine ATmega32

Thread Starter

NewbeeAVR

Joined Dec 5, 2017
2
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
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;
}
 
Top