Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help on Master - Slave assignments in PIC18F4550

Not open for further replies.


Junior Member level 2
May 16, 2011
Reaction score
Trophy points
Activity points

I'm relatively new to microcontrollers. I plan to use I2C as master mode and the internal EEPROM of PIC18F4550 as the slave. Is this possible even if I will be using both the I2C mode and EEPROM of just one PIC18F4550? If yes, how do we do the initialization and port/register assignments in MikroC Pro? Can anyone share their previous experience when working with this?

Please help. Thank you.

You don't need to use the I2C bus to access the internal EEPROM of the PIC. This EEPROM is memory mapped and directly accessible just like the PIC RAM or FLASH.

Look at your compiler documentation it will likely have some built-in functions such as Eeprom_Read/Eeprom_Write to access this memory.

Thank you. Is it possible to have the I2C as master and an external RTC as slave? Can someone please check my code if I can already use this for our RTC? I'm not sure if the code is ready for usage in the PIC already so that I can monitor the time of the day. What else is missing?

unsigned char sec, min1, hr, week_day, day, mn, year;
char *txt, tnum[4];

void main() {
I2C1_Init(100000); // initialize full master mode

//--------------------- Reads time and date information from RTC (DS1307)
void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
I2C1_Start(); // issue start signal
*sec =I2C1_Rd(1);
*min =I2C1_Rd(1);
*hr =I2C1_Rd(1);
*week_day =I2C1_Rd(1);
*day =I2C1_Rd(1);
*mn =I2C1_Rd(1);
*year =I2C1_Rd(1);

//-------------------- Formats date and time
void Transform_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
*sec = ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
*min = ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
*hr = ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
*week_day =(*week_day & 0x07);
*day = ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
*mn = ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
*year = ((*year & 0xF0)>>4)*10+(*year & 0x0F);

//-------------------- Output values to LCD
void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {
case 1: txt="Sun"; break;
case 2: txt="Mon"; break;
case 3: txt="Tue"; break;
case 4: txt="Wed"; break;
case 5: txt="Thu"; break;
case 6: txt="Fri"; break;
case 7: txt="Sat"; break;
Lcd_Chr(1, 6, (day / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day % 10) + 48); // Print oness digit of day variable
Lcd_Chr(1, 9, (mn / 10) + 48);
Lcd_Chr(1,10, (mn % 10) + 48);
Lcd_Chr(1,15, year + 48); // Print year vaiable + 8 (start from year 2008)

Lcd_Chr(2, 6, (hr / 10) + 48);
Lcd_Chr(2, 7, (hr % 10) + 48);
Lcd_Chr(2, 9, (min / 10) + 48);
Lcd_Chr(2,10, (min % 10) + 48);
Lcd_Chr(2,12, (sec / 10) + 48);
Lcd_Chr(2,13, (sec % 10) + 48);


//------------------ Performs project-wide init
void Init_Main() {

Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off

I2C1_Init(100000); // initialize I2C
txt = "Time:";
txt = "201";

//----------------- Main procedure
void main() {
Init_Main(); // perform initialization
while (1) {
Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year); // read time from RTC(DS1307)
Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year); // format date and time
Display_Time(sec, min1, hr, week_day, day, mn, year); // prepare and display on LCD
Delay_ms(1000); // wait 1s

Yes you should be able to access an RTC as an I2C slave. The I2C code seems to look correct although you seem to be initializing the I2C bus twice and there seem to be two 'main()' declarations. Have you already tried this code?
I'll just ask the obvious question: do you have external pull-up resistors on the SCL/SDA lines? Is there some way of monitoring the I2C bus to see whether an acknowledge is given when sending a byte? That would tell you if the device is responding correctly. An oscilloscope is handy for looking at the timing of the signals if all else fails.
Last edited:

I tried to compile this code but there seems to be plenty of errors when I'm dealing with pointers and i have a couple of functions inside the code. Why does this happen?
We have external pull-up resistors on the SCL/SDA lines. We plan to test it on our MikroElektronika Dev Board.
Another question if I may ask, how do we test if the code/RTC is already working? Thank you very much for your time, effort and patience.

Unless you need to use C, I would recommend the Pascal compiler from MikroElektronika. The errors are far less cryptic and code is much easier to get correct -- particularly when passing parameters a place where C is especially weak.

As I mentioned, your code has two main() declarations which is probably totally messing up the C parser. Remove the 3rd and 4th and last lines of the code you posted. You also seem to have some extraneous lines just before the Init_main() function which are illegal where they are placed. I'm guessing from this code example that you are new to C. You may want to start out with a simple program first and get it right before trying the full code.

You should be able to tell the RTC chip is working if you can read the time registers and the seconds values are changing.

You'll need to post some of the errors you're getting before I can help further.

Not open for further replies.

Part and Inventory Search

Welcome to