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.

I2c Problem with PIC 16F887 and Eeprom 24LC256

Status
Not open for further replies.

smitchel

New Member
Hi everybody,

I'm having a little of problem with the I2C library, I read the datasheet of the eeprom 24LC256 in details to find out how I should communicate via I2C with it. I did everything like in the datasheet to "byte write" and then "random read". I just wanted to try to write a byte somewhere in the eeprom and then read it to make sure it was indeed written.
I'm using the simulation software proteus. I tested each function in my code one by one, but using a lcd screen and a variable tested with a "if" to make sure everytime an I2C funtion was executed, I got a "0" as indicated in the library documentation.
In the end I managed to pinpoint the problem, or I think I did. The I2C_rd() command doesn't want to work if there's no argument in it, so I tried 0, for the no ack, but I still can't get the byte I wrote. Same thing with 1. So I really don't know what to do now.
The address of the eeprom on the i2c bus is 000 so with the control byte either A0 for writing or A1 for reading mode. The random address I tried to use for the eeprom is 0x708F and I tried to write the byte 0x20. By the way, if someone know a way to convert the byte read into a char readeable by the lcd screen that would be nice, because I have to combare the byte read with the actual byte I put and display a message on the lcd screen.

Here's the code: (also I put a lot of delay_ms, I had problems with that, so since I wasn't sure where was the problem I put them everywhere, I'll remove them later)

Code:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

// End LCD module connection definition
// Define Messages
 char message2[] = "000000000000000";
 char message4[] = "It Works!";
 char message5[] = "LCD Operational";
 int bob;
 void main() {
  TRISC = 0b00000000; // PORTC All Outputs
  TRISA = 0b00000000; // PORTA All Outputs, Except RA3
  TRISB = 0b00000000;

  Lcd_Init();                      // Initialize LCD
  Lcd_Out(1,2,message5);            // Write message1 in 1st row
  Lcd_Out(2,1,message2);

    I2C1_Init(100000);
    Delay_ms(20);
    I2C1_Start();              // issue I2C1 start signal

    Delay_ms(20);
    I2C1_Wr(0xA0);             // send byte via I2C1  (device address + W)

    Delay_ms(20);
    I2C1_Wr(0x70);             //send high byte

    Delay_ms(20);
    I2C1_Wr(0x8F);               // send low byte
    Delay_ms(20);

    I2C1_Wr(0x20);             // send data (data to be written)

    Delay_ms(20);
    I2C1_Stop();               // issue I2C1 stop signal

    Delay_ms(100);


    I2C1_start();               // Claim I2C1 BUS

    Delay_ms(20);
    I2C1_wr(0xA0);      // Tell all I2C1 devices you are talking to EEPROM in WRITE MODE

    Delay_ms(20);

    I2C1_wr(0x70);     // Address High Byte
    Delay_ms(20);

    I2C1_wr(0x8F);        // Address Low Byte
    Delay_ms(20);

    I2C1_start();           // RESTART I2C1 BUS (necissary for microchip protocol)

    Delay_ms(20);
    I2C1_wr(0xA1);      // Tell all I2C1 you are talking to EEPROM in READ MODE.
   
    Delay_ms(20);
    bob = I2C1_Rd(1);         // Read in the data     ---------------------problem here-----------------
    Delay_ms(20);
    
    if (bob == 0x44)
    {
   Lcd_Out(2,2,message4);
   }
   Delay_ms(20);
   I2C1_stop();                // release the bus
}
 
Last edited:
I have mentioned this before....... Real resistor models do not work here... In ISIS you MUST use the pullup resistor model...

Secondly... Look into the sprintf / printf functions... Then you can output to the LCD with the decimal numbers.
 
Last edited:
Well thank you Ian, but I'm not sure I understand your answer. I mean I thought my model was already a pull-up resistor model so I don't see how I could change it. If you could tell me the changes to make for it to work on ISIS.
 
There are two types of model in ISIS Analogue primitive and Digital primitive.... A 10k resistor is an analogue model... this means ISIS has a hard job simulating.. thus internal workings (math and such) affect the operation of the EEPROM.... If you use a digital pullup, the simulator can do its job far more efficiently.

Type "pullup" in the component search, and insert it as the pull up resistor.
 
So I used the "pullup" resistor and this time the code doesn't stop like before, I may have not mentioned it but when it read, it just stopped. Now the whole code is interpreted, but when I put my if condition to see if the byte read is the as the one written, it still doesn't work. There was an error, by the way, the byte data was 0x20 while I compared my bob variable with 0x44, but even with the right values, it doesn't work.
I tried to use the command sprintf( bob, "%d", bob2 ) ; but mikroc won't compile it and gives me "Undeclared identifier 'sprintf' in expression". It's regular C though. So I'm not sure what to do now. Can you give me the proper sythax to you use printf / sprintf, so I can see what it reads on the lcd screen.
 
For sprintf() and printf() you need to incorporate this line
Code:
#include<stdio.h>
You ALSO need to read the documentation..

sprintf()... will allow you to print to a stream (a character array) then you can print to the screen using a pointer to that array.
Your variable "bob" is an integer.... you need to convert to an ascii string..
set up an LCD buffer of about 8 bytes..... Use " sprintf(mybuffer,"%d",bob); " OR " itoa(); " the format for itoa(); is:-
Code:
#include <stdlib.h>
char *itoa(int value, char *string, int radix);
// value = value to be converted.... string = a pointer to your buffer... radix = hex, decimal etc..

printf().. will work if you include the relevant wrapper function "putch()" <---- read your documentation on this.
 
Last edited:
Thank you. Thank you very much for your help. I finally solved my problem, I discovered there was a I2C debug console in ISIS and saw what was going wrong. Even though it returned 0, the second Start bit sent by the I2C1_start(); command wasn't working properly, so I replaced it with the I2C1_Repeated_Start(); command and it worked. But the printf command will be very useful for me later on. Thanks again.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top