|
|
View previous topic :: View next topic |
Author |
Message |
marc10k
Joined: 15 Jan 2007 Posts: 11 Location: Germany
|
EEPROM writing problem |
Posted: Fri Jul 13, 2007 4:50 am |
|
|
Hello
I want to write a couple of bytes into the internal EEPROM from my 18F8722 with compiler version 4.042.
When I call the function Internal_EEPROM with 0x00 as data and write one byte it works ok but when writing two bytes it stores only the first. The second stays 0xFF. When writing 3 bytes the first and third become 0x00 and the second stays at 0xFF.
This was verified in the simulator and in real life.
Any suggestions? Thanks for your help.
Code: |
/******************************************************************************
* *
* Access to the internal EEPROM of the Microcontroller *
* *
* R_W -> 0..read, 1..write *
* Base_Address-> internal EEPROM address *
* Data -> data to read from/write into internal EEPROM *
* Length -> how long is variable ( 8..8 bit, 16..16 bit, *
* 24..24 bit, 32..32 bit) *
* Returns -> 1..everything OK, 0..EEPROM write failed *
* *
******************************************************************************/
#SEPARATE int1 Internal_EEPROM(int1 R_W, int Base_Address ,int32& Data, int Length)
{
int j, i, loop_end;
int32 ReRead;
loop_end = Length/8; // determine how many bytes need to be read/written
switch (R_W)
{
case 0: // Read from internal EEPROM
Data = 0x00;
for(i=0; i < loop_end; i++)
{
*(((int8 *)&Data)+loop_end-i-1) = Read_EEPROM(Base_Address + i); // from CCS Support
}
return(OK);
break;
case 1: // Write to internal EEPROM
for (j = 0; j < INT_ROM_RETRY; j++) // write until error exceeds threshold
{
ReRead = 0x00;
for(i=1; i <= loop_end; i++)
Write_EEPROM(Base_Address+i-1, *(&Data + loop_end - i)); // write data
for(i=0; i < loop_end; i++)
*(&ReRead+loop_end-i-1) = Read_EEPROM(Base_Address + i); // read written data
if (ReRead != Data) { continue; } else return(OK);
}
// PIC_Fehler(Error_Internal_ROM);
return(FAILURE);
break;
}
}
/******************************************************************************
* *
* Set the EEPROM registers to their init values at first startup *
* Assumes that this is the first start of this µC and the internal EEPROM *
* is not yet initialised. *
* *
* Returns -> 1..everything OK, 0..EEPROM write failed *
* *
******************************************************************************/
int1 EEPROM_Setup()
{
int fail = 0; // problem with writing to the EEPROM?
EEPROM_data = IF_PIC_REV;
Internal_EEPROM(1, Addr_IF_PIC_REV, EEPROM_data, 8);
EEPROM_data = 0x30;
Internal_EEPROM(1, Addr_Digital_Poti,EEPROM_data, 8); LCD_Contrast = 0x30;
EEPROM_data = 0x00;
if (Internal_EEPROM(1, Addr_S1_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_S1 = 0x00;
if (Internal_EEPROM(1, Addr_S2_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_S2 = 0x00;
if (Internal_EEPROM(1, Addr_M1_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_M1 = 0x00;
if (Internal_EEPROM(1, Addr_M2_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_M2 = 0x00;
if (Internal_EEPROM(1, Addr_M3_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_M3 = 0x00;
if (Internal_EEPROM(1, Addr_L_MBST, EEPROM_data, 16) != OK) fail++;
GMBST_L = 0x00;
if (Internal_EEPROM(1, Addr_Operating_Time, EEPROM_data, 24) != OK) fail++;
GOperating_Time = 0x00;
if (Internal_EEPROM(1, Addr_Magnetron_On_Time, EEPROM_data, 24) != OK) fail++;
GMagnetron_On_Time = 0x00;
if (fail > 0)
return (failure);
else
return (OK); |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 13, 2007 2:17 pm |
|
|
I didn't try to understand your whole program, but you've got at least
two places in your code where you're making the assumption that
pointer arithmetic will be done as if all pointers are byte pointers.
CCS used to operate that way, but not anymore, since vs. 4.021.
For example, this expression,
Code: | *(&Data + loop_end - i)); |
needs to be modified to look like this:
Code: | *(&(int8 *)Data + loop_end - i)); |
Also fix this one:
Code: | *(&ReRead+loop_end-i-1) |
Here's a test program that will let you see the difference. Compile this
code and run it in MPLAB simulator and view the results in the Output
window. Setup the MPLAB simulator to use 'UART1' for output.
Code: |
#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//===========================
void main()
{
int32 Data;
int i, loop_end;
int8 *Ptr;
loop_end = 2;
i = 0;
Ptr = &Data + loop_end - i;
printf("&Data = %LX\n\r", &Data);
printf("Ptr = %LX \n\r", Ptr);
// This time, cast 'Data' to a char ptr before
// doing pointer arithmetic.
Ptr = &(char *)Data + loop_end - i;
printf("&Data = %LX\n\r", &Data);
printf("New Ptr = %LX \n\r", Ptr);
while(1);
} |
Here are the results:
Quote: |
&Data = 0006
Ptr = 000E
&Data = 0006
New Ptr = 0008 |
|
|
|
marc10k
Joined: 15 Jan 2007 Posts: 11 Location: Germany
|
|
Posted: Mon Jul 16, 2007 12:20 am |
|
|
Thanks PCM Programmer
It worked fine after I moved the '&' from your first example in front of DATA. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|