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 using 16F876A comunication with EEPROM(M24C64)

Not open for further replies.


New Member
im doing elec engineering and this is my project
i am trying to write a code for i2c but there are some problems
TRISC = 0x10 or TRISC4 = 1 my code does not work i need to play with them seperately i dont know how. understanding internal registers is this what i have to do mates. i dont know what else to use coz there are plenty of them and i dont know anything about them.

Using the I2C Bus
i got the i2c code from here.
plz help me...


    863 bytes · Views: 178
  • i2c.h
    2.5 KB · Views: 202


Well-Known Member
Most Helpful Member
I think that you have misunderstood the way that the TRISC register works, and how to drive the I2C bus.

The TRISC register enables or disables the outputs for port C. Each bit controls one pin. When bit 0 of TRISC is high, the RC0 is high impedance (i.e. and input) and bit 0 of PORTC can be read as an input.

When using I2C it is common to make the output bit low, and turn on and off the TRIS bit to make the line go up and down. The pull-up resistor makes the line go high when the TRIS bit is high, and the output pulls the line low when it is enabled by clearing the TRIS bit.

With the I2C bus there are two lines, clock and data, and so you need two bits to be turned on and off. The example you are working from has:-
#define SCL TRISB4 // I2C bus
#define SDA TRISB1 //

so that application uses bits 1 and 4 of port B, also known as RB1 and RB4

The defines have meant that he can write code like:-

which just means that the data line is driven low by the PIC.

You have written:
#define SCL TRISC // I2C bus
#define SDA TRISC //

which looks similar but makes no sense, because you have defined SCL and SDA, which are bits, as equal to the whole 8 bit port.

Your line
SDA = TRISC | 0x58; //0101 1000

This really shows that you haven't understood what is going on. You defined SDA to be TRISC. That is just a shorthand so that you can use "SDA" instead of "TRISC", which would be OK if "SDA" in this case wasn't a bit. However, you then go and use both "SDA" and "TRISC" in the same line, just making your code more difficult to read.

Also, the line means:-
Collect the contents of TRISC
OR it with 0b01011000
move the result to SDA (also known as TRISC)

So that is potentially setting 3 bits, not one. It also means that the line following the delay,
SCL = TRISC | 0x48; //0100 1000
does nothing as those bits are set already.

The I2C protocol calls for individual bits to be set and cleared, one at a time, with a pause between them.

If you wanted to use the TRIS byte like that, you would write:

TRISC = TRISC | 0x10;

to set a single bit, bit 4 in this example



to clear a bit 4.


TRISC4 = 1;
TRISC4 = 0;

are a lot easier to write and to understand.

You need to define SCL and SDA as the appropriate bits of the TRIS registers (TRISC3 and TRISC4, I think) and then put the rest of the code back to as the example, which looks like it works.


New Member
thanks for writhing with good explanation.

im using IAR embedded Workbench v2.21A PICmocro

the problem is this it does not accept "#define SDA TRISC4" it only accepts
"#define SDA TRISC", i tryied to do it TRISC.4 but dont know how does it accepts single bit instead of accepting the whole byte.
please tell me what to. how to define the single bit as TRISC4 and TRISC3 which are SDA and SCL.


Well-Known Member
Most Helpful Member
Well I don't usually write in C, I prefer assembler code.

The should be a way of getting the complier to understand individual bits, but you'll have to read the documentation for the compiler.

Manipulating individual bits is very common in programming PICs, and I really don't think that I could work with a compiler that didn't have an easy way of doing that.

If the complier won't let you define individual bits, then it probably hasn't got any way of manipulating them.

You could write:-

TRISC = TRISC | 0x10; to set bit 4
TRISC = TRISC & 0xEF; to clear bit 4
TRISC = TRISC | 0x08; to set bit 3
TRISC = TRISC & 0xF7; to clear bit 3

or it might be possible to include assembly code, in which case you need:-
BSF TRISC, 4 ;to set bit 4
BCF TRISC, 4 ;to clear bit 4
BSF TRISC, 3 ;to set bit 3
BCF TRISC, 3 ;to clear bit 3


New Member
hi i have a header file of PIC16F876 which have TRISC bits configuration as single bit. of if i change
the header file of 15f876a line
where it says

__no_init volatile __bank1 unsigned char TRISC @ 0x87;

to this

__no_init volatile __bank1 union
unsigned char TRISC;
unsigned char TRISC0:1;
unsigned char TRISC1:1;
unsigned char TRISC2:1;
unsigned char TRISC3:1;
unsigned char TRISC4:1;
unsigned char TRISC5:1;
unsigned char TRISC6:1;
unsigned char TRISC7:1;
} @ 0x87;

i dont find any reason why wont it accept it ill go to lab tomorrow and will check it. tell me if u have any batter idea
ill be thankfull to u
Last edited:


New Member
U can define like dis in embedded c
#define SDA RC4 // it means u are using TRISC4 bit of portc
#define SCL RC5

Whatever it may be the pins of ports .
Last edited:
Not open for further replies.

Latest threads