Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help Trobleshooting I2c code 8951

Status
Not open for further replies.

JeffreyPeter

New Member
I have studied I2C in a number of sites but I can't find the error in my program. I'm trying to write 'A' and read it from the eeprom. I have written a working code for LCD separately...
Code:
#include<at89x51.h>
#include<lcd.h>
#include<delay.h>
#include<intrins.h>   //For using [_nop_()]
#define ack 1
#define nack 0
sbit sda=P1^0;
sbit scl=P1^1;

void I2C_start() // Start I2C
{
        sda = 1;
        _nop_();_nop_();
        scl = 1;
        _nop_();_nop_();
    sda = 0;
        _nop_();_nop_();
    scl = 0;
        _nop_();_nop_();
}
void I2C_stop()
{
        sda = 0;
        _nop_();_nop_();
        scl = 1;
        _nop_();_nop_();
        sda = 1;
        _nop_();_nop_();
}
void I2C_writebit(unsigned char Data)
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                sda = (Data & 0x80) ? 1:0;
                scl = 1;
                _nop_();
                scl = 0;
                Data<<=1;
        }
        scl= 1;
        _nop_();_nop_();
        scl = 0;
}

unsigned char I2C_readbit(char ackbit)
{
        unsigned char i, Data=0;
                sda = 1;// not clear Y SDA is out here
        for(i=0;i<8;i++)
                {
                        scl = 1;
                        Data<<=1;
                        Data  = (Data | sda);
                scl = 0;
                        _nop_();
        }
        if(ackbit)
                sda = 0;
                else
                        sda = 1;
        _nop_();_nop_();
                scl = 1;
                _nop_();_nop_();
                scl = 0;
                return Data;
}
void I2C_writebyte()                                    //save in EEPROM
{
        I2C_start();
        I2C_writebit(0xA0);                                             //device address
        I2C_writebit(0x00);                                             //word address
        I2C_writebit(0x41);                                             //send data     A
        I2C_stop();
}
void I2C_readbyte()
{
        unsigned char i;
        I2C_start();
        I2C_writebit(0xA0);
        I2C_writebit(0x00);
        I2C_start();
        I2C_writebit(0xA1);                                      //device address
        i=I2C_readbit(nack);
        I2C_stop();
        lcd_data(i); // I have written a separate LCD.h file for this function
}
void main()
{

        unsigned short int LCDL1=0x80;
        unsigned short int LCDL2=0xc0;
        lcd_ini();
        I2C_writebyte();
        I2C_readbyte();
        while(1)
        {
                delay_msec(1);
        }
}
 
I don't know what speed your processor is running at but 2 nops may be too short a delay. The original I²C bus had a max clock speed of 100kHz.

Mike.
 
OK.... I see the problem straight away...... You cannot use analogue resistor models with the I2C simulation ( noise is simulated ) You need a PULLUP model.. Replace the two 10kΩ for two pullups and it should be better...
 
Hi Jeffrey....

The 24LC64 has word addressing
Code:
void I2C_writebyte()                                    //save in EEPROM
{
        I2C_start();
        I2C_writebit(0xA0);                                             //device address
        I2C_writebit(0x00);                                             //word address
        I2C_writebit(0x41);                                             //send data     A
        I2C_stop();
}

that has an eight bit internal address

Code:
void I2C_writebyte()                                    //save in EEPROM
{
        I2C_start();
        I2C_writebit(0xA0);                                             //device address
        I2C_writebit(0x00);
        I2C_writebit(0x00);                                             //word address
        I2C_writebit(0x41);                                             //send data     A
        I2C_stop();
}

16 bit address...... The rest of your code is fine

Excellent code....

BTW.... After writing to an EEprom... you'll need to wait AT LEAST 5mS before you can access it again...

Code:
void main()
	{
	unsigned short int LCDL1=0x80;
	unsigned short int LCDL2=0xc0;
	//lcd_ini();
	I2C_writebyte();
	delayMs(5);     // wait a spell
	I2C_readbyte();
	while(1)
       ........................
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top