[AVR] TWI (I2C) read routine in AVR

Status
Not open for further replies.

NewbeeAVR

Junior Member level 2
Joined
Dec 2, 2017
Messages
21
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
195
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


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#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;
}

 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…