AnsweredAssumed Answered

External MCU Communication by I2C

Question asked by sh.leili on Mar 7, 2014
Latest reply on May 3, 2014 by sh.leili
Hi all,

I want to do a project by using atmega48 and NFC chip.
I have the M24LR-Discovey boards and want to read/write on the EEPROM of M24LR04E by using I2C communication .
I am completely confused how to define the EEPROM ID and EEPROM Address .

I am not fully sure that if it is possible when m24lr04e and stm8l152 already are connected by I2C .

i used this  code:
#include <avr/io.h>
#include <util/delay.h>
#include <compat/twi.h>

#define MAX_TRIES 100

#define EEPROM_ID    0x0E        //  EEPROM Device Identifier
#define EEPROM_ADDR  0x02        //  EEPROM Device Address

#define I2C_START 0
#define I2C_DATA  1
#define I2C_STOP  2

unsigned char i2c_transmit(unsigned char type) {
 switch(type) {
    case I2C_START:    // Send Start Condition
      TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
      break;
    case I2C_DATA:     // Send Data
      TWCR = (1 << TWINT) | (1 << TWEN);
      break;
    case I2C_STOP:     // Send Stop Condition
      TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
      return 0;
 }

 // Wait for TWINT flag set in TWCR Register
 while (!(TWCR & (1 << TWINT)));

 // Return TWI Status Register, mask the prescaler bits (TWPS1,TWPS0)
 return (TWSR & 0xF8);
}

int i2c_writebyte(unsigned int i2c_address, unsigned int dev_id,
                 unsigned int dev_addr,char data) {
 unsigned char n = 0;
 unsigned char twi_status;
 char r_val = -1;

i2c_retry:
 if (n++ >= MAX_TRIES) return r_val;

 // Transmit Start Condition
 twi_status=i2c_transmit(I2C_START);

 // Check the TWI Status
 if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
 if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;

 // Send slave address (SLA_W)
 TWDR = (dev_id & 0xF0) | ((dev_addr & 0x07) << 1) | TW_WRITE;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if ((twi_status == TW_MT_SLA_NACK) || (twi_status == TW_MT_ARB_LOST)) goto i2c_retry;
 if (twi_status != TW_MT_SLA_ACK) goto i2c_quit;

 // Send the High 8-bit of I2C Address
 TWDR = i2c_address >> 8;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;

 // Send the Low 8-bit of I2C Address
 TWDR = i2c_address;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;

 // Put data into data register and start transmission
 TWDR = data;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;

 // TWI Transmit Ok
 r_val=1;

i2c_quit:
 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_STOP);
 return r_val;
}

int i2c_readbyte(unsigned int i2c_address, unsigned int dev_id,
                unsigned int dev_addr, char *data)
{
 unsigned char n = 0;
 unsigned char twi_status;
 char r_val = -1;

i2c_retry:
 if (n++ >= MAX_TRIES) return r_val;

 // Transmit Start Condition
 twi_status=i2c_transmit(I2C_START);

 // Check the TWSR status
 if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
 if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;

 // Send slave address (SLA_W) 0xa0
 TWDR = (dev_id & 0xF0) | ((dev_addr << 1) & 0x0E) | TW_WRITE;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if ((twi_status == TW_MT_SLA_NACK) || (twi_status == TW_MT_ARB_LOST)) goto i2c_retry;
 if (twi_status != TW_MT_SLA_ACK) goto i2c_quit;

 // Send the High 8-bit of I2C Address
 TWDR = i2c_address >> 8;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;

 // Send the Low 8-bit of I2C Address
 TWDR = i2c_address;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);

 // Check the TWSR status
 if (twi_status != TW_MT_DATA_ACK) goto i2c_quit;  

 // Send start Condition
 twi_status=i2c_transmit(I2C_START);

 // Check the TWSR status
 if (twi_status == TW_MT_ARB_LOST) goto i2c_retry;
 if ((twi_status != TW_START) && (twi_status != TW_REP_START)) goto i2c_quit;

 // Send slave address (SLA_R)
 TWDR = (dev_id & 0xF0) | ((dev_addr << 1) & 0x0E) | TW_READ;

 // Transmit I2C Data
 twi_status=i2c_transmit(I2C_DATA);  

 // Check the TWSR status
 if ((twi_status == TW_MR_SLA_NACK) || (twi_status == TW_MR_ARB_LOST)) goto i2c_retry;
 if (twi_status != TW_MR_SLA_ACK) goto i2c_quit;

 // Read I2C Data
 twi_status=i2c_transmit(I2C_DATA);
 if (twi_status != TW_MR_DATA_NACK) goto i2c_quit;

 // Get the Data
 *data=TWDR;
 r_val=1;

i2c_quit:
 // Send Stop Condition
 twi_status=i2c_transmit(I2C_STOP);
 return r_val;
}

int main(void)
{
  char buffer[34]= {
      0b10000001,
      0b10000001,
      0b10000001,
      0b10000001,
      0b00000110,
      0b00001100,
      0b00011001,
      0b00110011,
      0b01100110,
      0b11001100,
      0b10011000,
      0b00110000,
      0b01100000,
      0b11000000,
      0b10000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b10000000,
      0b11000000,
      0b01100000,
      0b00110000,
      0b10011000,
      0b11001100,
      0b01100110,
      0b00110011,
      0b00011001,
      0b00001100,
      0b00000110,
      0b00000011,
      0b00000001,
      0b00000000,
      0b00000000,
      0b00000000,
      };  

 char data,id1,id2;
 unsigned int dev_address,i,idelay;

 DDRD=0xFF;                   // Set PORTD as Output
 PORTD=0x00;                  // Set All PORTD to Low

 /* Initial ADC Peripheral for User's Trimpot Input */
 ADMUX=0x00;                // Select Channel 0 (PC0)

 // Initial the ADC Circuit
 ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);

 // Free running Mode
 ADCSRB = 0x00;

 // Disable digital input on ADC0 (PC0)
 DIDR0 = 0x01;

 /* Initial TWI Peripheral */
 TWSR = 0x00;   // Select Prescaler of 1

 // SCL frequency = 11059200 / (16 + 2 * 48 * 1) = 98.743 khz
 TWBR = 0x30;   // 48 Decimal

 // Read the EEPROM ID
 dev_address=0;              // Start at Address 0
 i2c_readbyte(dev_address,EEPROM_ID,EEPROM_ADDR,&id1);
 i2c_readbyte(dev_address + 1,EEPROM_ID,EEPROM_ADDR,&id2);

 // Write to EEPROM if no ID defined
// if (id1 != buffer[0] || id2 != buffer[i]) {
   for(i=0;i < 34;i++) {
   i2c_writebyte(dev_address + i,EEPROM_ID,EEPROM_ADDR,buffer[i]);
     int y;
      for (y=0;y<100;y++);
  }
 //}  

 // Initial Delay Value
 idelay=100;  

 for(;;) {
   for(i=2;i < 34;i++) {
     // Start conversion by setting ADSC on ADCSRA Register
     ADCSRA |= (1<<ADSC);

     // wait until convertion complete ADSC=0 -> Complete
     while (ADCSRA & (1<<ADSC));

     // Get the ADC Result
     idelay = ADCW;

     // Read the EEPROM
     i2c_readbyte(dev_address + i,EEPROM_ID,EEPROM_ADDR,&data);

     // Put data to the PORTD
     PORTD=data;
     int y;
     for (y=0;y<1000;y++)    ;    // Delay
   }
 }


 return 0;
}


thank you all

Outcomes