Sir, I am trying to write 34 into the eeprom at address location 0x0000, but whenever I read and dislpay it on lcd, 49 is displayed. please help me.
my code
sbit SCL=P3^7; // Port pin for SCL line sbit SDA=P3^6; // Port pin for SDA line
void i2c_delay(void); // I2C Clock delay void i2c_start(void); // Generates a I2C Start condition void i2c_stop(void); // Generates a I2C Stop condition void i2c_wbyte(char i2c_wb); // Writes a single byte from I2C Slave unsigned char i2c_rbyte(void); // Reads and returns a single byte from I2C Slave char i2c_ack(void); void i2c_nack(void); void i2c_write(char id, char add,char dat); unsigned char i2c_read(char id,char add);
void i2c_delay(void) { char a; for(a=0;a<80;a++); }
void i2c_start(void) { SCL = 1; i2c_delay(); SDA = 1; i2c_delay(); SDA = 0; i2c_delay(); SCL = 0; i2c_delay(); }
void i2c_stop(void) { //SDA_Dir = 1; //SDA pin as output SDA = 0; i2c_delay(); SCL = 1; i2c_delay(); SDA = 1; i2c_delay(); SCL = 0; }
void i2c_wbyte(unsigned char i2c_wb) { char a; //DA_Dir = 1; // Set SDA pin as output for(a=0;a<8;a++) // Send 8 bits { SCL = 0; i2c_delay(); if(i2c_wb & (0x80 >> a)) { SDA = 1; } else { SDA = 0; } i2c_delay(); SCL = 1; i2c_delay(); }
}
unsigned char i2c_rbyte(void) { char a; unsigned char b; b=0; //SDA_Dir = 0; // Set SDA pin as input for(a=0;a<8;a++) { SCL = 1; i2c_delay(); if(SDA) { b |= (0x80 >> a); // Set data bit on SDA line } i2c_delay(); SCL = 0; i2c_delay(); } return(b); } char i2c_ack(void) { char a; //SDA_Dir = 1; // Set SDA pin as output i2c_delay(); SCL = 0; i2c_delay(); SDA = 1; i2c_delay(); SCL = 1; i2c_delay();
//SDA_Dir = 0; // Set SDA pin as input i2c_delay(); a = SDA; i2c_delay(); SCL = 0; i2c_delay(); return(a); }
void i2c_nack(void) { //SDA_Dir = 1; // Set SDA pin as output SDA = 1; i2c_delay(); SCL = 1; i2c_delay(); SCL = 0; i2c_delay(); } void i2c_write(unsigned char id, unsigned char add, unsigned char dat) { i2c_start(); i2c_wbyte(id); i2c_ack(); i2c_wbyte(add); i2c_ack(); i2c_wbyte(dat); i2c_ack(); i2c_stop(); }
unsigned char i2c_read(unsigned char id,unsigned char add) { unsigned char rd; i2c_start(); i2c_wbyte(id); i2c_ack(); i2c_wbyte(add); i2c_ack(); i2c_start(); i2c_wbyte((id|0x01)); i2c_ack(); rd = i2c_rbyte(); i2c_nack(); i2c_stop(); return(rd); } main() { unsigned char v=34; unsigned char dat=0; i2c_write(0xA0,0x0000,v); dat=i2c_read(0xA0,0x0000); send2lcd(dat); } the delay between read and write correct? the delay between scl and sda line, is ok? please help me
thanks in advance
The START operation in I2C specifies the begin of a transaction, wich ends with a STOP. While the transaction takes place there is a good practice to keep SCL low (0) between function calls, meaning the application is holding the bus for the time of the transaction. The STOP condition of course MUST leave setting the bus free (SCL=1, SDA=1)
The SDA can change only when SCL is low(0), otherwise this is a START or STOP contition.
Have you noticed that 24C04 requires 9 bit address because it has 4Kbits as 512byte x8 bits to represent a range of 0 (hex=0x00) to 511 (hex=0x1FF) a 9bit number is needed. So, there must be a function i2c_waddr(unsigned int adr) defined, declared and used for the 9bit address of the device.
Use the mentioned posted paradigm for the START step, begins holding the bus, creates the START condition, and leaves with the bus on hold because the transaction has not ended yet.
The i2c_delay has to provide for a delay of 3-5 us (microseconds), so the XTAL used and the clocking 1, 6, 12 of the microcontroller play role. Even a few __NOP__ are enough.
Keep these in mind and restrucure your program code.
Once more we see someone who posts the code without proper tags.
Then when asked to use the tags copies the already broken code from the previous post, and repost it again. All the time without noticing that the result is broken this time too.
What have happened to society? Own thinking?
Spenting too much time on forums, in front of a computer screen makes life boring. The are other fields to spend energy.