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.

Problem to write and read from EEPROM - 16F877

Status
Not open for further replies.

isaac82

New Member
Hello hi everyone... i got a problem to read and write from PIC16877 EEPROM. Here i attached together my code using PIC C LITE compiler...I hope all of u can help me. Thank You very much.


// Project 8.1 We are Online
#include <pic.h> // standard pic header file

/* Xtal frequency */
#define XTAL 4000000

// Hardware Notes:
// PIC16F627 Running at 4MHz

// Configuration Fuses
#if defined(_16F877A)
#warning PIC16F877A Selected
__CONFIG(0x3F61);

#error Unsupported PICmicro MCU Selected
#endif

// Global Variables

#define TRISLED1 TRISB0
#define TRISLED2 TRISB1
#define TRISLED3 TRISB2
#define TRISLED4 TRISB3
#define TRISLED5 TRISB4
#define TRISLED6 TRISB5
#define TRISLED7 TRISB6
#define TRISLED8 TRISB7

#define LED1 RB0
#define LED2 RB1
#define LED3 RB2
#define LED4 RB3
#define LED5 RB4
#define LED6 RB5
#define LED7 RB6
#define LED8 RB7

volatile unsigned CMCONNEW @ (unsigned) &CMCON; // LED Physical Bits
ANSEL = 0x00; // Digital I/O



// ---------------------------- Delay Function -------------------------------------------------
void Delay500Us() //500 Usec Delay Routine
{
unsigned char cnt500Us = 165; // Delay Cycle to achieve 500Us delay
while(--cnt500Us != 0) // Delay Timing is approximately 3 usec per loop
continue; // Note this routine is for 4MHz crystal frequency
}

void Delay100Ms() //100 msec Delay Routine
{
unsigned char cnt100Ms = 200; // 200 * 500 Usec = 100 msec
do
{
Delay500Us();
}while(--cnt100Ms != 0);
}

void Delay1s() // 1 sec Delay Routine
{
unsigned char cnt1Ms = 1; //10 * 100 msec = 1 sec
do
{
Delay100Ms();
}while(--cnt1Ms != 0);
}

// ---------------------------- Delay Function -------------------------------------------------


unsigned char ReadByteFromEE(unsigned char address)
{
unsigned char byte; // Variable hold the data that is read

EEADR = address; // Read from this address

RD = 1; // Initiate a read cycle

byte = EEDATA; // Fetch byte from dataregister
return byte; // Return the read byte
}


void WriteByteToEE(unsigned char data, unsigned char address)
{

EEADR = address; // Address to write to 0x00 to 0xFF
EEDATA = data; // Data to write

WREN = 1; // Enable writes to the EEProm
while(GIE)
GIE = 0; // Disable interrupts during write

EECON2 = 0x55; // Register not implemented on 16F684
EECON2 = 0xAA; // strange that this is required
WR = 1; // Initiate a write cycle


while(!EEIF); // Wait for write to complete

WREN = 0; // Disable writes to EEProm
EEIF = 0; // Clear "write complete" flag
GIE = 1; // Reenable interrupts

}



// ---------------------------- main program ---------------------------------------------------
void main()
{

TRISLED1 = 0;
TRISLED2 = 0;
TRISLED3 = 0;
TRISLED4 = 0;
TRISLED5 = 0;
TRISLED6 = 0;
TRISLED7 = 0;
TRISLED8 = 0;

LED4 = 0;
LED3 = 0;
LED2 = 0;
LED1 = 0;
LED5 = 0;
LED6 = 0;
LED7 = 0;
LED8 = 0;

CMCONNEW = 0b00000111; // Disabled analog function at port A

while (1 == 1) // Loop forever
{

WriteByteToEE(0x0A, 0x00);
PORTB = ReadByteFromEE(0x00);
Delay1s();
}
}
 
I can't see anything wrong with your code.

This is working code for the 18 series chips,
Code:
unsigned char ReadEEPROM(unsigned char address){
    EECON1=0;                   //ensure CFGS=0 and EEPGD=0 
    EEADR = address;
    EECON1bits.RD = 1;
    return(EEDATA);
}

void WriteEEPROM(unsigned char address,unsigned char data){
char SaveInt;
    SaveInt=INTCON;             //save interrupt status
    EECON1=0;                   //ensure CFGS=0 and EEPGD=0
    EECON1bits.WREN = 1;        //enable write to EEPROM
    EEADR = address;            //setup Address
    EEDATA = data;              //and data
    INTCONbits.GIE=0;           //No interrupts
    EECON2 = 0x55;              //required sequence #1
    EECON2 = 0xaa;              //#2
    EECON1bits.WR = 1;          //#3 = actual write
    INTCON=SaveInt;             //restore interrupts
    while(!PIR2bits.EEIF);      //wait until finished
    EECON1bits.WREN = 0;        //disable write to EEPROM
}
As you can see it is almost identical to yours. The only thing you are not doing is clearing the EEPGD bit, this bit is undefined at reset and so will need clearing.

Can you also check the generated code and make sure that the necessary sequence of asm is generated? You will find the sequence on page 35 of the data sheet.

Mike.
 
I should have deleted the first line of my last post as I later found the error in your code. You need to clear the EEPGD bit in your code. It would have been nice if I could have edited my post above rather than filling the board with pointless corrections like this one.

Mike.
 
thank you very much for your help. I have set EEPGD = 0, but after i compile using MPLAB, value for EEPROM still 0%. Below is my HEX file.

:06000000A001A101CB2FBD
:100F5800A5308301A000A00BAF2F08008301A001DA
:100F6800A00AB927A00BB52F0800C8308301A0003C
:100F7800AC27A00BBC2F08008301A00003178D002D
:100F880083160C1483120C080313A1000800073001
:100F9800831603139C009D0111308312A0000A30B0
:100FA800D9271130C0278600D02F8301A1008316CE
:100FB80003178C1383120313200803178D000313E0
:100FC800210803178C0083160C15EB2F8B138B1B32
:100FD800EA2F5530831603178D00AA308D008C1424
:100FE800831203130D1EF42F831603170C1183129B
:080FF80003130D128B17080012
:02400E00613F10
:00000001FF
 
I could be completely wrong here because C is not my thing. My reading of both your code and hex throws this up at me...

You don't seem to be pointing at the E2prom in your read routine, although in this particular case it's already been set to point to it by your write routine. Best to be explicit and set it to point to either Flash or E2prom in case it gets changed later on inadvertently in your code.

Also and more to the point, where are you defining your PortB output directions ?
I ask this merely because I don't see it being set in your hex file...

I don't see any other obvious problems with your read or write routines, but like I said, C is not my thing so take my comments with a pinch of salt, check em out and let us all know the outcome :)

rgds
 
I should have deleted the first line of my last post as I later found the error in your code. You need to clear the EEPGD bit in your code. It would have been nice if I could have edited my post above rather than filling the board with pointless corrections like this one.

Mike.

Hi Mike,
Off topic, but I agree with your comments regarding the EDIT feature, someone in the future will try to use your original code.

The same applies to a circuit drawing errors.

Perhaps, Admin may consider our comments.:)
 
Hi Mike,
Off topic, but I agree with your comments regarding the EDIT feature, someone in the future will try to use your original code.

The same applies to a circuit drawing errors.

Perhaps, Admin may consider our comments.:)

I agree too.We need the EDIT button permanently.Some program adjustments comes to mind later time it was happend to me also.Also to edit the Circuit drawings.15 mins expire like 1 second.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top