View previous topic :: View next topic |
Author |
Message |
Freddie
Joined: 06 Sep 2003 Posts: 49
|
Read and Write 16 Bit Number To Internal EEPROM |
Posted: Sun Oct 26, 2008 2:11 pm |
|
|
I'm using PIC16F876A.
I need to read a two byte 16 bit number out of internal EEPROM, increment it and write it back to EEPROM. The code below works ok for reading it out and incrementing it. It does not write the values to EEPROM though. I get no errors and the code exectutes fine (per the debugger) but the values in the EEPROM dont change. I think it has something to do with how I pack the bytes before I write it back to EEPROM?? Not really sure, I could use some help or some other working sample code. Thanks.
Code: |
#define AddressU 0
#define AddressL 1
int8 TempUpper, TempLower;
int16 TempValue;
//Read current value from EEPROM
TempUpper = read_eeprom(AddressU);
TempLower = read_eeprom(AddressL);
//Combine Upper and Lower into Value
TempValue = 0x0000;
TempValue = TempUpper;
TempValue = TempValue << 8;
TempValue = TempValue | TempLower;
//Incrent the value
TempValue = TempValue + 1;
//Put the Value back into Upper and Lower
TempUpper = (TempValue >> 8) & 0x00FF;
TempLower = TempValue & 0x00FF;
//Write Upper and Lower to EEPROM
write_eeprom(AddressU, TempUpper);
write_eeprom(AddressL, TempLower);
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 26, 2008 2:49 pm |
|
|
Quote: | the values in the EEPROM dont change |
The MPLAB Help File for the Microchip ICD2 says this:
Quote: | Writing Data EEPROM
If data EEPROM is written during program execution, the EEPROM window
of MPLAB IDE will not reflect the changes. You will need to perform a
READ of EEPROM memory in order to update the values in the window. |
Here is an example of reading/writing a 16-bit word to external eeprom.
It could be changed to work with internal eeprom.
http://www.ccsinfo.com/forum/viewtopic.php?t=27405&start=5 |
|
|
Freddie
Joined: 06 Sep 2003 Posts: 49
|
|
Posted: Sun Oct 26, 2008 3:45 pm |
|
|
Thanks PCMP, I knew about having to reload the EEPROM data.
After tinkering with this a bit more I found that the issue is with these two lines:
Code: |
//Put the Value back into Upper and Lower
TempUpper = (TempValue >> 8) & 0x00FF;
TempLower = TempValue & 0x00FF;
|
If I change the "& 0x00FF" to "& 0xFF" like this, it works:
Code: |
//Put the Value back into Upper and Lower
TempUpper = (TempValue >> 8) & 0xFF;
TempLower = TempValue & 0xFF;
|
It seems that I may have been inadvertantly casting TempUpper and TempLower to 16 bits and the write_eeprom() function did not like that?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 26, 2008 3:57 pm |
|
|
If you want to split and combine bytes into a word, it can be done much
more easily and error-free if you use the make8() and make16()
functions. These are in the CCS manual. |
|
|
Freddie
Joined: 06 Sep 2003 Posts: 49
|
|
Posted: Sun Oct 26, 2008 4:02 pm |
|
|
PCM programmer wrote: | If you want to split and combine bytes into a word, it can be done much
more easily and error-free if you use the make8() and make16()
functions. These are in the CCS manual. |
Thats a good idea, thanks. I'm gonna change my code to use the make8() and make16() functions. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Oct 26, 2008 4:57 pm |
|
|
The make16() and make8() are useful for straightforward coding of 8/16-bit conversions. However, the C-standard compatible method in above example is generally supported and efficiently coded by CCS C. I don't see an inadvertent type cast or even incorrect coding when compiling the example with PCM V4.081. Also the generated binary code is identical when changing 0x00ff to 0xff.
It may be an issue of a previous compiler version, or there must be some special setting not shown in the posting. |
|
|
Freddie
Joined: 06 Sep 2003 Posts: 49
|
|
Posted: Sun Oct 26, 2008 5:27 pm |
|
|
I'm using CCS compiler version 3.245.
I changed it to use the make8 and make16 functions, see below.
Everything works except that it does not actually write to the EEPROM, I'm sure of that.
What could be going on here? Can someone try this function with a later version of the compiler and let me know what happens?
Code: |
void Increment16BitNumber(int8 UpperAddress, int8 LowerAddress)
{
int8 TempUpper, TempLower;
int16 TempValue;
//Read current value from the bin
TempUpper = read_eeprom(UpperAddress);
TempLower = read_eeprom(LowerAddress);
//Combine Upper and Lower into Value
TempValue = make16(TempUpper, TempLower);
//Incrent the value of the bin
TempValue = TempValue + 1;
//Write the value back into the bin
TempUpper = make8(TempValue,1);
TempLower = make8(TempValue,0);
write_eeprom(UpperAddress, TempUpper);
write_eeprom(LowerAddress, TempLower);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Freddie
Joined: 06 Sep 2003 Posts: 49
|
|
Posted: Sun Oct 26, 2008 6:22 pm |
|
|
I built a test program per PCMP's suggestion and the test program works fine.
However, my "real" program still does not write to the EEPROM!!! There must be something else somewhere in the program that is interacting and causing this issue. I'm not sure I can post the real code because it is a project for work. I'll have to keep debugging and let you know what/if I find the root cause.
Thanks for trying to help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 26, 2008 6:35 pm |
|
|
Comment out sections of it until it does work. This will give you a clue
as to what is causing the problem.
For example, if you are calling a routine to get the time from a RTC chip,
comment out the guts of that routine and just make it return a preset
date-time value. This allows your program to still work overall, but
you can test if certain aspects of your program are causing a problem. |
|
|
Freddie
Joined: 06 Sep 2003 Posts: 49
|
|
Posted: Sun Oct 26, 2008 6:51 pm |
|
|
I think I figured it out.
I use Microchip MPLAB, Microchip ICD2 and PCM 3.245.
When I made and ran the test program I was not using any breakpoints. When I ran the "real" program I have a breakpoint at the top of the "Increment16BitNumber" function and I would then step through each line of that function looking at the variables in the watch window to see what they did. When the program was done I would stop the debugger and pull the content of the EEPROM, always to see that the EEPROM was not written to.
I think the issues was that I was "stepping" through the lines that have the write_eeprom() statements. This apparently changes the timing of execution and the EEPROM was not written to properly? When I removed the breakpoint and ran it with no stepping it works fine every time!
Go figure. I spent 3 hrs debugging this. I guess that's not too bad considering that I have not programmed at pic in about 6 months. Just now getting back into the swing of things.
Is MPLAB the best environment to use with PCM? I've been thinking of getting PCW. Is PCW a stand alone development debug environment and compatible with the Microchip ICD2? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 26, 2008 7:31 pm |
|
|
I debug by using temporary printf() statements within the program, to
display the contents of variables. Or, I will place getc() statements
between lines or sections of the program to allow stepping throught it.
Or I will place a while(1) statement to halt progress at a certain point.
This allows the program to run at full speed in the actual product
environment. I don't use the debugger. This is just my method.
It works for me. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Mon Oct 27, 2008 1:17 am |
|
|
To my opinion, MPLAB debugging is irreplaceable to trace low-level coding issues, and it's also very efficient in general debugging. If you use breakpoints, the program behaviour is almost unchanged up to the first breakpoint hit. Single stepping must be used carefully. You must be aware, that some processor actions may not work as expected. |
|
|
Ttelmah Guest
|
|
Posted: Mon Oct 27, 2008 3:19 am |
|
|
Obvious comment. NOCPD fuse...
Best Wishes |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Oct 27, 2008 8:02 am |
|
|
Don't know about the pic you are using but I am using an 18F6722 and my EEPROM is at address 0xF00000 not 0
#define DATA_BASE_ADDR 0xF00000
addr = DATA_BASE_ADDR;
write_eeprom(addr++, *data++);
Actually, looking at the device selector in PCC I notice that the start address of eeprom for your chip is
0x00002100
Open the device selector from the tools menu, find your chip then look at memory. |
|
|
|