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.

PIC 18Fxxxx Memory

Status
Not open for further replies.

AtomSoft

Well-Known Member
Ok since im technically still a newbie this should be a ok question:

How do i store data in the memory of a PIC18FXXXX?

Probably it would be better to ask it like if a user inputs a name how would i make it permanent data unlessed chosen to be erased by user.

or if still not understood imagine you are a user of a PC(computer) and you save something in my documents when you restart its still there. I know this requires something like a small on board battery (i have) But am i supposed to store the information in a certain address also? Also i would have to make a switchable power circuit so when power is down it turns to like a sleep mode and then uses the small batter to just keep information on the chip. I know this has to do with eeprom i think. Some help would be appreciated. Thanks in advance.
 
Two places, EEPROM or FLASH are both program accessible, you use the TABLE command.
Some new PICs have started to omit the EEPROM in favor of high endurance Flash.
 
AtomSoft said:
How do i store data in the memory of a PIC18FXXXX?
Read chapters 6 and 7 of the 18F1320 datasheet. All your questions will be answered. There's even example code in there. :)

The Midrange Manual has more detail. **broken link removed** all separated into chapters. I don't know where to get it all in one file.
 
Last edited:
If you are using C18 then this should help,

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
}

Mike.
Edit, changed address to char from int.
 
Last edited:
thanks alot guys i will read my butt off and try that code. So:

These devices have 256 bytes of data EEPROM with
an address range from 00h to FFh.

So using above code i would just :

char MyReadVal = ReadEEPROM(0x01); //This would read value at address 01h

WriteEEPROM(0x01, MyVariable) // Write to 01h with MyVariable
 
Code:
void high_isr (void)
{
	INTCONbits.INT0IF=0;    // clear the flag and return BREAKPOINT and watch
	//MyFlash(3,50);
	char MyTmp;   //[b] I get a syntax error here why?[/b]
	MyTmp = ReadEEPROM(0x01);
	
	if(MyTmp = 0x01){
		WriteEEPROM(0x01, 0b00000000);
	} else {
		WriteEEPROM(0x01, 0b00000001);
	}

}
 
You should keep interrupts short, so rather than doing something REALLY SLOW, like writing to EEPROM in your interrupt, set a flag in the interrupt, and act on that flag in your main.
 
Ok i know you cant handle interrupts during a write but while on a read?

Ok im trying to check if a bit is set in address 0x01 on the eeprom. I can compare with binary i can see if set but cannot handle a interrupt if reading at all. Below is my code. Any help would do.


Code:
#pragma    config OSC=INTIO2, WDT=OFF, LVP=OFF, DEBUG=ON
#include <p18f1320.h>

void interrupt_at_high_vector(void);
void high_isr (void);
void MyDelay(int xD);
void MyFlash (char qTimes, char xSpeed);
unsigned char ReadEEPROM(unsigned char address);
void WriteEEPROM(unsigned char address,unsigned char data);
void MyToggle(char MyAddr);

#pragma code /* return to the default code section */
#pragma interrupt high_isr

void high_isr (void)
{
	INTCONbits.INT0IF=0;    // clear the flag and return BREAKPOINT and watch
	MyToggle(0x01);

}

void main(void)
{
    OSCCON = 0x72;            // 8MHz
    ADCON1 = 0xFF;
    INTCON2 = 0b00000101;    // falling edge, high priority
    INTCON = 0b11010000;     // Setting Bit 3 to 1 gives a automatic interrupt 
    TRISB = 0b00100101;
	ADCON1bits.PCFG0 = 0;
	TRISA = 0b10111110;

    while(1){

	char MyFlashVal;
		 MyFlashVal = ReadEEPROM(0x01);

		if (MyFlashVal = 0b00000001){
			MyFlash(1,100);
		} else {
			LATA=0b00000001; // Turn LED on
			MyDelay(200);

			LATA=0b00000000; // Turn LED off
			MyDelay(200);
		}
    }
}

void MyDelay(int xD)
{
	int countD = xD * 100;
     	
	while (countD > 1)
   	{
		countD = countD - 1;
	}
}

void MyToggle(char MyAddr) 
{
	char MyTmp;
	MyTmp = ReadEEPROM(MyAddr);
	
	if(MyTmp = 0b00000001){
		WriteEEPROM(MyAddr, 0b00000000);
	} else {
		WriteEEPROM(MyAddr, 0x00000001);
	}
}

void MyFlash (char qTimes, char xSpeed)
{
	int x = qTimes;
	while(x != 0)  
	{
		TRISA = 0b10111110;
		LATA = 0b00000001;
		MyDelay(xSpeed);

		LATA = 0b01000000;
		MyDelay(xSpeed);

		TRISA = 0b00111111;
		LATA = 0b01000000; 
		MyDelay(xSpeed);

		LATA = 0b10000000;
		MyDelay(xSpeed);

		TRISA = 0b01111110;
		LATA = 0b10000000;
		MyDelay(xSpeed);

		LATA = 0b00000001;
		MyDelay(xSpeed);
			
		x--;
	}
	
	TRISA = 0b10111110;
}

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
}

#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm     //   brakpoint here 
}
 
Ok i know you cant handle interrupts during a write but while on a read?

No, that isn't what I meant. If you are inside of an interrupt, the first thing you, or the compiler, does, is disable interrupts, perform the task, then set the interrupts on the way out. If you spend a lot of time inside of your interrupt, then no other interrupts can occur, and you may miss something.

Rather than call MyToggle from withing the interrupt, set a flag, then check for the condition of that flag outside, something like this:
Code:
       ...
       void MyToggle(char MyAddr);

#pragma code /* return to the default code section */
#pragma interrupt high_isr

void high_isr (void)
{
	INTCONbits.INT0IF=0;    // clear the flag and return BREAKPOINT and watch
	myFlag = 0x01;

}

void main(void)
{
     int myFlag = 0x00;
     OSC...
     ...110;
     
      while(1){
      
      if (myFlag) {
      myFlag = 0x00;
      MyToggle(MyAddr);
      } // end if
      ...


But that is using myFlag as a global, so you might want to tune the scope....
 
Last edited:
Ok cool thanks a bunch!
Code:
#pragma    config OSC=INTIO2, WDT=OFF, LVP=OFF, DEBUG=ON
#include <p18f1320.h>

void interrupt_at_high_vector(void);
void high_isr (void);
void MyDelay(int xD);
void MyFlash (char qTimes, char xSpeed);
unsigned char ReadEEPROM(unsigned char address);
void WriteEEPROM(unsigned char address,unsigned char data);
void MyToggle(char MyAddr);

#pragma code /* return to the default code section */
#pragma interrupt high_isr

char LSF;
char LST;

void high_isr (void)
{
	INTCONbits.INT0IF=0;    // clear the flag and return BREAKPOINT and watch
	LST = 1;

}

void main(void)
{
    OSCCON = 0x72;            // 8MHz
    ADCON1 = 0xFF;
    INTCON2 = 0b00000101;    // falling edge, high priority
    INTCON = 0b11010000;     // Setting Bit 3 to 1 gives a automatic interrupt 
    TRISB = 0b00100101;
	ADCON1bits.PCFG0 = 0;
	TRISA = 0b10111110;

	LSF = ReadEEPROM(0x01);
	LST = 0;

    while(1){


		if (LST){
			LST = 0;
			MyToggle(0x01);
			LSF = ReadEEPROM(0x01);
		}
		
		if (LSF == 0x01){
			MyFlash(1,100);
		} 
		else 
		{
			LATA=0x01; // Turn LED on
			MyDelay(200);

			LATA=0; // Turn LED off
			MyDelay(200);
		}
    }
}

void MyDelay(int xD)
{
	int countD = xD * 100;
     	
	while (countD > 1)
   	{
		countD = countD - 1;
	}
}

void MyToggle(char MyAddr) 
{
	char MyTmp;
	MyTmp = ReadEEPROM(MyAddr);
	
	if(MyTmp == 0x01){
		WriteEEPROM(MyAddr, 0b00000000);
	} else {
		WriteEEPROM(MyAddr, 0x00000001);
	}
}

void MyFlash (char qTimes, char xSpeed)
{
	int x = qTimes;
	while(x != 0)  
	{
		TRISA = 0b10111110;
		LATA = 0b00000001;
		MyDelay(xSpeed);

		LATA = 0b01000000;
		MyDelay(xSpeed);

		TRISA = 0b00111111;
		LATA = 0b01000000; 
		MyDelay(xSpeed);

		LATA = 0b10000000;
		MyDelay(xSpeed);

		TRISA = 0b01111110;
		LATA = 0b10000000;
		MyDelay(xSpeed);

		LATA = 0b00000001;
		MyDelay(xSpeed);
			
		x--;
	}
	
	TRISA = 0b10111110;
}

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
}

#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
_asm GOTO high_isr _endasm     //   brakpoint here 
}
 
To test i programmed device and pressed RB0 to initiate the blinking led then i unplugged device from power and waited 30 seconds and restored power and it blinks then i pressed RB0 again and it flashes the leds from Left to Right and i unplugged and waiting again the 30 seconds and plugged in and it flashes left to right as it was set to do. Thanks alot this helps me learn alot about memory. I guess the next thing to do it become organized in it. Learn about tables and such and just try to make things look nice.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top