|
|
View previous topic :: View next topic |
Author |
Message |
waheed
Joined: 19 May 2012 Posts: 26 Location: Pakistan
|
EEPROM Garbage value |
Posted: Wed May 30, 2012 3:36 am |
|
|
Controller: 18f452
Compiler v4.125
The program increments the 3 variables every time PIN_E0 is pressed and stores the values to EEPROM and resets cpu every time PIN_E1 is pressed.
Code: |
#include <18F452_new.h>
#fuses NOWDT,HS,NOPROTECT
#use delay(clock=20000000)
#ROM int8 0xF00000 = {1, 2, 3, 4, 5}
#include <stdlib.h>
#include <dt_lcd_v01.c>
unsigned int8 lockout=0;
unsigned int8 minutes;
unsigned int16 hours;
//////////////////////////////////////////////////////////
////*** EEPROM WRITE (16 BIT) ***////
//////////////////////////////////////////////////////////
void write_int16_eeprom(int8 n, int16 data)
{
int i;
int16 add;
add = (&data);
for (i=0; i<3; i++)
{
write_eeprom( i + n , *(i + add) );
}
}
//////////////////////////////////////////////////////////
////*** EEPROM READ (16 BIT) ***////
//////////////////////////////////////////////////////////
int16 read_int16_eeprom(int8 n)
{
int i;
int16 add;
int16 data;
add = (&data);
for (i=0; i<3; i++)
{
*(add+ i) = read_eeprom (i + n);
}
return (data);
}
//////////////////////////////////////////////////////////
////*** MAIN PROGRAM ***////
//////////////////////////////////////////////////////////
void main()
{
set_tris_a(0);
dt_lcd_init();
dt_lcd_clear_screen();
lockout = read_eeprom(1);
minutes = read_eeprom(2);
hours = read_int16_eeprom(3);
while (1)
{
if (input(PIN_E0)== 0)
{
lockout++;
minutes = minutes+2;
hours = hours+3;
}
dt_lcd_gotoxy(0,0);printf(dt_lcd_printchar,"Lockout: %d",lockout);
dt_lcd_gotoxy(0,1);printf(dt_lcd_printchar,"minutes: %d",minutes);
dt_lcd_gotoxy(0,2);printf(dt_lcd_printchar,"hours : %Lu",hours);
if (input(PIN_E1)== 0)
{
write_eeprom(1,lockout);
write_eeprom(2,minutes);
write_int16_eeprom(3,hours);
reset_cpu();
}
}
}
|
When the program runs, it shows some initial values:
lockout = 2
minutes = 3
hours = 1284
I want these values set to 0.
I have already tried writing 0s to eeprom first but that didn't work.
If I set these values to 0 in the main function then variables will initialize every time at 0 and whole point of preserving the values is lost. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 30, 2012 4:57 am |
|
|
You're trying to do too much.
You think you have a problem reading and writing eeprom.
Divide and conquer.
Reduce your code to the point where you're testing your problem area ONLY, one byte at a time.
Then put the rest back in.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Wed May 30, 2012 5:00 am |
|
|
The obvious really big mistake, is size. An int16, is two bytes, but you try to store/read 3. 0,1,2.....
Best Wishes |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed May 30, 2012 5:03 am |
|
|
Your read and write routines are too complex and are wrong: they try to read and write 3 bytes for each int16!
Here are my versions:
Code: |
void write_int16_eeprom(int16 address, int16 data)
{
// Portable version
// write_eeprom(address, data & 0xFF);
// write_eeprom(address + 1, data >> 8);
// Non-portable version: CCS only.
write_eeprom(address, make8(data, 0));
write_eeprom(address + 1, make8(data, 1));
}
/******************************************************************************/
int16 read_int16_eeprom(int16 address)
{
// Portable version
// return read_eeprom(address) | (int16)read_eeprom(address + 1) << 8;
// Non-portable, but faster version for CCS only.
return make16(read_eeprom(address + 1), read_eeprom(address));
}
|
RF Developer
Last edited by RF_Developer on Wed May 30, 2012 5:04 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Wed May 30, 2012 5:04 am |
|
|
q1. What controls the PIN_E0 ? If a simple swtich or pushbutton you will have serious 'bounce' to deal with.You'll need to 'cleanup' the signal !
q2...
unsigned int8 lockout=0;
unsigned int8 minutes;
unsigned int16 hours;
...
this code forces lockout to 0, but only reserves space for minutes and hours.Unless YOU put something there, it WILL be a random value.
q3. You should add 'PUT' to the fuses options.It'll help 'stabilze' the PIC.
q4. You may want to add a 'delay_ms(500)' after your LCD init code,just before the MAIN loop. Again to get the PIC 'stable'. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Wed May 30, 2012 6:42 am |
|
|
Hi,
Another really important question that is being overlooked is where did you get that code? If you wrote it yourself, I would assume that you would have enough understanding of the code to troubleshoot it too.
What does this line of code do?
Code: |
#ROM int8 0xF00000 = {1, 2, 3, 4, 5}
|
Answer: it "preloads" EEPROM locations 0 thru 4 with the values 1, 2, 3, 4, 5 during chip programming. If you want everything to be zeroed the very first time you run the program, just leave out that line as the EEPROM defaults to all 0's after chip programming.
This code
Code: |
lockout = read_eeprom(1);
minutes = read_eeprom(2);
|
is working exactly right. It's reading the preloaded values of 2, and 3 from EEPROM locations 1 and 2.
This comes up over and over on the forums. You can't simply cut-n-paste code that you find elsewhere, cobble it together, and then expect it to work out of the box. There is nothing wrong with "re-using" code from others, but you've absolutely got to understand it, and then when it doesn't work, learn to divide your program into manageable bits, and troubleshoot them separately until the program does what you want!
If it were me, I'd start by writing a simple program to write one EEPROM location, and then read it right back. If that worked OK, I'd try to write two EEPROM locations, and so on until I had built the entire program.
John |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 30, 2012 7:46 am |
|
|
Quote: | If you want everything to be zeroed the very first time you run the program, just leave out that line as the EEPROM defaults to all 0's after chip programming. | The EEPROM on my PIC16F877 defaults to 0xFF after programming.
The code below was loaded into a PIC16F877 on a PICDEM 2 PLUS board.
Button A4 pulls down when pressed.
Code advances test_value in EEPROM location 0 when A4 held down.
Test_value resumes from old value after any reset.
Code: | #include <16F877.h>
#fuses HS,NOWDT,NOLVP
#use delay(clock=4000000) //one instruction=1us
#use rs232(baud=9600, xmit=PIN_c6, rcv=PIN_c7)
int test_value;
void main()
{
test_value = 0;
while (1)
{
if (input(pin_A4) == 0 )
{
test_value = read_eeprom(0);
printf ("Old value from eeprom = %d \r" , test_value) ;
test_value++;
printf ("New value to eeprom = %d \r\r" , test_value) ;
write_eeprom(0,test_value);
delay_ms(100);
}
}
}
|
Mike |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Wed May 30, 2012 8:11 am |
|
|
Hi Mike,
Yeah, you are correct, I was thinking about something else. If he absolutely needs to read the EEPROM right off the bat, and see '0' values he can change the #ROM directive to:
Code: |
#ROM int8 0xF00000 = {0, 0, 0, 0, 0}
|
Actually, a better way to do it that uses the compiler to obtain the address of the EEPROM is this:
Code: |
#ROM int8 getenv("EEPROM_ADDRESS") = {0, 0, 0, 0, 0}
|
This method is "transportable" from chip to chip without requiring you to explicitly define the EEPROM address.
John |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed May 30, 2012 8:30 am |
|
|
And of course none of these approaches offers any protection
for invalid eeprom data values.
That's what an added CRC word or check sum Byte( or word) for each stored value adds to the value of the code.
I have never made use of eeprom for any important stored value without such protection, as blind, unverified trust in an eeprom stored parameter can lead to another cascade of trouble in runtime.
It also inherently catches and allows recovery /default trapping for un-inited data too.
Just my 2 cents |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed May 30, 2012 2:07 pm |
|
|
Quote: | And of course none of these approaches offers any protection
for invalid eeprom data values.
| Agreed.
Mike |
|
|
|
|
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
|