Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[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

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top