We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello All,
I am finding it really hard to perform write and read operations on the EEPROM connected to the MCU by two wires using the I2C Protocol.
I've read the data sheets, written the code exactly matching the datasheet info, but it was of no avail.
Please help me out.
My code looks something like this
void Write_Start(void) { E2P_SDA = 1; E2P_SCL = 1; delay_i2c(); E2P_SDA = 0; delay_i2c(); E2P_SCL = 0; delay_i2c(); } void Write_to_E2P(void) { unsigned char DEV_SEL_CODE = 0x0A0; unsigned char ADDR_MSB = 0x50; unsigned char ADDR_LSB = 0x05; unsigned char i; Write_Start(); for(i=7;i>=0;i--) { E2P_SDA = DEV_SEL_CODE^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED1=1; for(i=7;i>=0;i--) { E2P_SDA = ADDR_MSB^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED2=1; for(i=7;i>=0;i--) { E2P_SDA = ADDR_LSB^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED3=1; for(i=7;i>=0;i--) { E2P_SDA = current_channel^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED4=1; }
programs have comments, scribbles do not
Erik
thank you for your interest in the thread i posted. i assumed the lingo would be self explanatory. i'll put up a commented version.
well, you might want to take a look at these Erik,
1.) en.wikipedia.org/.../Computer_program 2.) www.webopedia.com/.../program.html 3.) encarta.msn.com/.../computer_program.html 4.) www.britannica.com/.../computer-program
see if you can find the words "comment" or "comments" in these page !
you could have gone easy on that..........
Sandy Sandy,
Not to fuel that particular fire, I do think that you should heed erik's advice.
I would fire any 'programmer' that didn't comment their code properly.... as in doesn't have any.
He could have stated it a tad better, but 'we' see so much code and when people don't comment on what they are "trying to do" it makes it harder for 'us' to figure out your problem for free. Remember 'we' are giving our time for free, to help you.
So thanks for telling 'us' that you plan on commenting your code for us so we can easily see what you think you are doing.
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
This is from my code-monkey rule-book (aka "Rules for [Radcial] Code Monkeys")
I rarely give out this type of valuable information, so you (and every forum reader) better appreciate it...
COMMENTS
Generally "Comments" are either Strategic or Tactical in nature. While some comments can be categorized as Orientation.
Strategic comments describe what a section of code is supposed to accomplish. Strategic comments should be placed before the code section that implements the task.
Tactical comments describes the specifics on how the code is implementing a task. Typically these tactical comments are on an end-of -line basis. Tactical comments serve to enlighten the non-obvious behavior or method implemented, and not a re-statement of what the code performs:
Orientation and Strategic are closely related, but they do differ. Orientation comments provide the reader with a wider conceptual view of the code module. Orientation comments can be information about the system's environment like the OS, CPU, Memory, IDE, Versions, etc. While Strategic and Tactical are the dominant forms, Orientation should be still be contained in all source code modules.
The over-use of tactical comments will result in source code that takes too long to read, and begins to devalue and hide the worth-while comments. Strategic comments should be the primary and dominant form of commenting source code.
Tactical comments should be as detailed as needed to inform the programmer. The common used for Tactical comments is when describing the side-effects of code implementation or when the code performs something that is not obvious to the standard or novice programmer. Always write on a level that is explanatory the reader, and never assume the reader is as competent as you think you are.
Tactical comments in "C" typically use the double-slash notation, while the Strategic comments are flower-boxed. Orientation comments are typically found at the top of the module.
thanks a lot for your valuable advice captain. i dont disagree with you at all, so, i am posting my commented version right away.
/* the routine for sending a start bit for i2c initialization */ void Write_Start(void) { E2P_SDA = 1; // sda is set high initially for a Hi to Low transition E2P_SCL = 1; // scl is made high delay_i2c(); // delay of 5 micro seconds E2P_SDA = 0; // sda is driven low to complete hi to low signal delay_i2c(); // delay of 5 micro seconds E2P_SCL = 0; // scl is then made low again to complete one clock period delay_i2c(); } /* this is used to write a byte onto the eeprom at location 0x5005 */ void Write_to_E2P(void) { unsigned char DEV_SEL_CODE = 0x0A0; // device select code unsigned char ADDR_MSB = 0x50; // MSB of address unsigned char ADDR_LSB = 0x05; // LSB of address unsigned char i; // loop variable Write_Start(); // I2C START for(i=7;i>=0;i--) // transmitting from the bit 7 down to bit 0 in the loop { E2P_SDA = DEV_SEL_CODE^i; // data bit on the sda line E2P_SCL = 0; // a rising edge of the pulse to sample the sda line delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; // these lines are for the 9th clock pulse when the slave pulls the sda line low E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) // if the acknowledge is recieved then we glow an LED used for debugging on board LED1=1; /* the same story follows for the rest three bytes, which are - the address MSB and LSB and the data byte to be transferred */ for(i=7;i>=0;i--) { E2P_SDA = ADDR_MSB^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED2=1; for(i=7;i>=0;i--) { E2P_SDA = ADDR_LSB^i; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED3=1; for(i=7;i>=0;i--) { E2P_SDA = data_byte^i; // data_byte is a global variable E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); } E2P_SDA = 1; E2P_SCL = 0; delay_i2c(); E2P_SCL = 1; delay_i2c(); delay_i2c(); E2P_SCL = 0; delay_i2c(); if(E2P_SDA == 0) LED4=1; }
Excuse me, Ms. Sandy, were you not asking for help? Do you really believe people will me more interested in helping you if you insult them?
Well, whatever that was, started and ended with my reply, now, Please, assist me!
Sandy Sandy, I agree, started and ended
Unfortunately, the Monkey-dung hit the fan here, and I can't spend my time dealing with your issue at the moment.
I have some "race-conditions" to settle asap (meaning I'll be working over the weekend).
I'm sure some of our talented contributors will help out if they can get past the 'hostility' issues.
Hope all goes well.
why on earth use that chip. The P89C66x is identical PLUS it has hardware IIC, the code for which can be obtained from the CodeArchitect.
Bit banged IIC makes EVERYTHING ELSE come to a total standstill for an excessive time. Hardware IIC just generates an interrupt for each byte.
i am using a DIP Package. My board is designed for that.
why on earth use that chip.
I do wish forums could filter the I wouldn't start from there style answers.
But many "I wouldn't start from there" do bring forward good information.
In this case: It is normally better to use a controller with I2C than to implement it in software. And today, there is no correlation between controller price and the availability of a I2C controller.
Another interesting thing is the answer we got: "i am using a DIP Package. My board is designed for that."
Quite a number of 8051 chips are available in a DIP package. Quite a number of development boards with 40-pin DIP sockets are intended for use with quite a number of different 8051 chips, as long as care is taken with supply voltages, crystal frequency and similar.
A much better reason for not considering alternatives would have been: "The controller is soledred on my development board, and I don't have the equipment to replace it with another, and can't afford buying another development board."
Another good reason for staying with bit-banging would have been: "My assignment is to implement a software-only solution, to prove that I understand the protocol."
have you verified timing using a scope? are you sure the data line is not held low (hence occupying the bus)...?
i have not tested it with a scope. will the eeprom occupy the bus in the 9th clock period, if the byte is not written , will it not release the bus ? Can you please go through the code and tell me if my understanding of the protocol is indeed right ?
If you are already into bit banging, maybe it is better to take a modular approach: write a small routine that places a start on the bus. Then do the same for stop, ack, nack, a byte etc. It is hard to say what's wrong without snooping the bus.