Jump to content
Sign in to follow this  
fransp

Eprom Data Write And Read

Recommended Posts

Hi All,

 

 

BoostC has a #pragma for putting dat into the eeprom.

 

Does it have functions to read the eeprom?

 

 

With best regards,

 

 

Frans.

Share this post


Link to post
Share on other sites

Frans,

 

#pragma DATA can be used to set EEPROM memory when the device is programmed. Thats because the PIC EEPROM is mapped to some addresses that can be accessed through the programming interface.

 

To read and write EEPROM at run time you need to write some code.

There is plenty of code about that does this: eeprom example

 

This code is wrtten for old C2C compiler, maybe you can convert it and share it with others.

 

Regards

Dave

Share this post


Link to post
Share on other sites
Frans,

 

#pragma DATA can be used to set EEPROM memory when the device is programmed. Thats because the PIC EEPROM is mapped to some addresses that can be accessed through the programming interface.

 

To read and write EEPROM at run time you need to write some code.

There is plenty of code about that does this: eeprom example

 

This code is wrtten for old C2C compiler, maybe you can convert it and share it with others.

 

Regards

Dave

 

 

Hi Dave,

 

 

Thanks, I wil give it a go and let you know.

 

With best regards,

 

 

Frans.

Share this post


Link to post
Share on other sites

Hope you don't mind...

It's a little bit messy, but it does the job:

unsigned char EE_read(char addr);
void EE_wait(void);
void EE_write(char addr, char data);

unsigned char EE_read(char addr){
eeadr=addr; //0-255 destination address
clear_bit(eecon1,EEPGD); //EEPGD=0 -> EEPROM; EEPGD=1 -> FLASH
set_bit(eecon1,RD); //start reading
return eedata;
}

void EE_wait(void)
{
while(test_bit(eecon1,WR));
}

void EE_write(char addr, char data){
EE_wait();
eeadr=addr; //0-255 destination address
eedata=data;
clear_bit(eecon1,EEPGD); //EEPGD=0 -> EEPROM; EEPGD=1 -> FLASH
set_bit(eecon1,WREN);
clear_bit(intcon, GIE);//disable interrupts
asm {
	MOVLW 0x55
	MOVWF _eecon2
	MOVLW AAh
	MOVWF _eecon2
}
set_bit(eecon1,WR);
set_bit(intcon, GIE);//reenable interrupts
clear_bit(eecon1,WREN);
}

 

After seeing the C2C code I guess that probably the asm lines can be deleted and two direct assignements could be used...

Share this post


Link to post
Share on other sites

Frans,

 

After seeing the C2C code I guess that probably the asm lines can be deleted and two direct assignements could be used...

 

I would prefer to keep the asm there.

This sequence has to be precisely adhered to or EEPROM does not get written.

Using C direct assigments starts to make assumptions about the code the compiler may generate - so best to leave the assembler there (in my opinion).

 

Regards

Dave

Share this post


Link to post
Share on other sites
After seeing the C2C code I guess that probably the asm lines can be deleted and two direct assignements could be used...

Boost C also generate the right assembly (at least for a PIC16). But the target I´m testing (PIC16F648A) doesn´t have this EECON1<EEPGD> bit implemented. What is this about?

...
     clear_bit(eecon1,EEPGD);
...

Share this post


Link to post
Share on other sites

I forgot to say that I wrote the code for my 16F877...

bit 7 EEPGD: Program/Data EEPROM Select bit

1 = Accesses program memory

0 = Accesses data memory

 

It's used to select either the EEPROM or the FLASH memory.

Share this post


Link to post
Share on other sites

Frans,

 

Post it here.

 

Maybe we will add it to the example code page later.

 

Regards

Dave

Share this post


Link to post
Share on other sites
Frans,

 

Post it here.

 

Maybe we will add it to the example code page later.

 

Regards

Dave

 

Hi Dave,

 

Ok, I have worked out a complete example, including test to validate the method.

There is plenty of comment to follow what I am doing and for what purpose.

 

Thanks for having me do this. I enjoyed every mistake of it.

 

For All,

 

Here is my implementation of the C2C example about Reading, Writing and Erasing the EEprom under program control.

There are three routine's for Writing, Reading and Erasing.

The Main routine is for testing and showing the code is doing what it is supposed to do.

 

This is the header file.

#ifndef _EEPROM_READ_WRITE_H_
#define _EERPOM_READ_WRITE_H_

// General defines, could have been in system.h?
#define _EEPROM 0X2100

// Definition of device.
// Example target 16F874, check the Settings/Target...
// example CLOCK 20MHz, to make delay_ work on time.
#pragma CLOCK_FREQ 20000000
// These are needed too, but may vary with the application.
#pragma DATA _CONFIG, _PWRTE_OFF & _BODEN_OFF & _WDT_OFF & _LVP_ON & _CPD_OFF & _DEBUG_OFF & _HS_OSC & _CP_OFF

// note: this is actually done at programming the device.
// change the data to make Test 1 fail.
#pragma DATA _EEPROM,55

// my handy defines
// pin handling
#define in 1	// gate logic
#define out 0
#define on 1	// pin logic
#define off 0

// Prototyping board specific
// LED is as per prototype board PIC-P40-USB-20MHz by Olimex.

// bit allocations
volatile bit LED@PORTE.1;
volatile bit LED_pin@TRISE.1;

// Configuration of pins is done in main.

// Defines for configuration
// Definition for all analog pins to digital
#define alldigital 0x06 

#endif //_EEPROM_READ_WRITE_H_

 

This is de code file:

 

 
#include <system.h>
#include "Eeprom_read_write.h"

/* Demonstration of the write eeprom, read eeprom functions. 
Written in BoostC.

Based on EEPROM routines from C2C example by Petr Mervart.

This demo program was written for a PIC16F874 on a Olimex prototyping board
type: PIC-P40-USB-20MHz
I use the Shane Tolmie bootloader and downloader.
The downloader was modified by Stef Mientky for direct access of the FTDI FT 232BM USB to serial converter.
OS WinXP.

Documentation:
C2C example of Petr Mervart.
PIC16F87XA Datasheet, DS39583B, page 33-36

Note: 	in BoostC :
		the actual registers are in lower case.
		the constants are in upper case.
		viz: clear_bit( eecon1,EEPGD )
*/

// You can fill the eeprom at programming time with 
// #pragma DATA 0x2100,data,<data>
// see: .h

void eeprom_write ( char adresa , char data )  //write to eeprom
{
// we check for a writing finish at the end.

eeadr = adresa;					// the address
eedata = data;						// the data

clear_bit( eecon1,EEPGD ); 		 // make sure we do write to data memory.
set_bit( eecon1,WREN );			// enabel writing.
//	clear_bit( intcon , GIE );			// disable interrupts when using them	
asm{ 
	movlw	0x55 					// special sequence to unlock programming.
	movwf	_eecon2 			
	movlw	0xAA 
	movwf	_eecon2
	}

set_bit( eecon1, WR );     		// start writing. 
while( test_bit( eecon1 , WR )); 	 // cycle until WR reg. eecon1 = 1 (writing...)
clear_bit( eecon1, WREN );			// disable writing.
clear_bit ( pir2 , EEIF );			// datasheet says clear also interrupt EEIF
//	set_bit( intcon , GIE );			// enable interrupts when using them

}
//


char eeprom_read( char adresa ) 		 // read from eeprom
{
   eeadr = adresa;					// the address
   
   clear_bit( eecon1,EEPGD ); 		// make sure we read the eeprom
   
   set_bit( eecon1, RD );   			// start reading
   return eedata;						// return the byte
}
//



//The original EERPOM_NULL was rewritten to this eraser.

void eeprom_erase ( char adresa , char size )           // erase eeprom
{
char i;
for (i = 0; i < size; i++ )
  	 {
		eeprom_write( adresa+i , 0 );
	}
}
//

void main()
{
char i,j,k,m;

// Configuration as needed for my prototype board.

// to use analog ports as digital 
clear_bit ( trise, PSPMODE );	// have to switch off slave port pins in E
adcon1 = alldigital;			// have to set the analog/Vref/digital selection.

// define direction of LED pin.
LED = off;						// first put it off i.e. inactive state.
LED_pin = out;					// then switch it to ouput.

// end configuration.


// The Tests.
// I have no LCD or serial com ready for the proto board.

// Test 1: This will test the #pragma _EEPROM and reading of the eeprom.
// It will lit the LED when test passes i.e. data written is data read.
// else it will blink the LED 5 times in 2 sec interval.

// Put something in the eeprom, see .h

// flash the test number
k = 1;
while ( k > 0 )
		{
			LED = on;
			delay_ms(100);
			LED = off;
			delay_ms(200);
			k--;
		}
delay_s(1);

j = eeprom_read ( 0 );

if ( j == 55 )
{	LED  = on;
	delay_s(5);
}
else
{
	k = 10;
	while ( k > 0 )
		{
			LED = !LED;
			delay_s( 1 );
			k--;
		}
}
LED = off;
delay_s ( 2 );

// Test 2. This test will test the writing of the eeprom
// It will write one byte and read it back.
// It will lit the LED when the test passes else it will blink.

// flash the test number
k = 2;
while ( k > 0 )
		{
			LED = on;
			delay_ms(100);
			LED = off;
			delay_ms(200);
			k--;
		}
 delay_s(1);

eeprom_write ( 1 , 88 );
j = eeprom_read ( 1 );
if ( j == 88 )
{	LED  = on;
	delay_s(5);
}
else
{
	k = 10;
	while ( k > 0 )
		{
			LED = on;
			delay_ms(100);
			LED = off;
			delay_ms(100);
			k--;
		}
}
LED = off;
delay_s( 2 );


// TEST 3. This test will test the erasing of the eeprom
// It will erase the number of bytes given and read it back.
// Iy will lit the LED when the test passes else it will blink.

// flash the test number
k = 3;
while ( k > 0 )
		{
			LED = on;
			delay_ms(100);
			LED = off;
			delay_ms(200);
			k--;
		}
 delay_s(1);
 
// First we add another byte to the eeprom to check for eraser overshoot.
eeprom_write (2, 0x99 );
eeprom_write (3, 0x5A );
eeprom_erase ( 1 , 2); 		//it will erase two bytes starting at address 1.

j = eeprom_read ( 0 );
i = eeprom_read ( 1 );
k = eeprom_read ( 2 );
m = eeprom_read ( 3 );

if (( j == 55 ) && ( i == 0 ) && ( k == 0 ) && ( m == 0x5A ))
{	LED  = on;
	delay_s(5);
}
else
{
	k = 10;
	while ( k > 0 )
		{
			LED = !LED;
			delay_s(1);
			k--;
		}
}
// signal end.
k = 20;
while ( k > 0 )
		{
			LED = !LED;
			delay_ms(50);
			k--;
		}
LED = off;
// End of Tests.
}

 

Enjoy, like I did.

 

 

With best regards,

 

 

Frans.

Edited by fransp

Share this post


Link to post
Share on other sites

However, I came up with a different solution, (at least for the writer) that works equally well, and actually delas with the interrupts correctly:

void write_eeprom(char addr, char data)
{
char int_on;
while(test_bit(eecon1, WR))
;
eeadr=addr;
eedata=data;
clear_bit(eecon1, EEPGD);
int_on=(test_bit(intcon, GIE));
clear_bit(intcon, GIE);
set_bit(eecon1, WREN);
eecon2=0x55;
eecon2=0xaa;
set_bit(eecon1, WR);
if(int_on)
	set_bit(intcon, GIE);
clear_bit(eecon1, WREN);
}

by swapping the clear_bit(intcon, GIE) and the set_bit(eecon1, WREN) I was able to prevent the bank-switch which was getting in the way of the 5-critical-instruction block

Plus my code actually handles the interrupt apropriately (though it does consume 1 byte of RAM).

 

I think fransp's example (perhaps with my write routine?) should be added to the boostC examples directory, as this must be a common issue, and it took some tweaking to get it to work correctly.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...