PDA

View Full Version : Write and Read from eeprom



savnik
- 19th March 2007, 06:40
I have the below code (one part of code).
My problem is when turn off the power and after turn on again , don't save the value P in the eeprom always.Why;
I use 16f88


P VAR WORD 'value of the divider
FLAG VAR BYTE


READ 3,FLAG
IF FLAG = 55 THEN
READ 1,P.BYTE0 ' Divider
READ 2,P.BYTE1
ELSE
P= 256 ' value of the divider
ENDIF

..
..
..
..
..

'************************** CHOICE OF THE DIVIDER ***********************

PREDIV:

LCDOUT $FE,1,"* DIVIDER *"
LCDOUT $FE,$C0," P = ",#P

LOOP:
BUTTON PLUS,0,10,5,B1,1,PICK ' Goes to PICK if press the button
BUTTON BMENU,0,255,0,B4,1,MEN
PAUSE 100
GOTO LOOP

PICK:
IND = IND + 1
IF IND< 9 THEN CHOIX
IND= 0
GOTO CHOIX

CHOIX:
LOOKUP2 IND,[1,10,16,32,40,64,80,128,256],P

WRITE 3 , 55
WRITE 1 , P.BYTE0 ' SAVE The VALUE OF P
WRITE 2 , P.BYTE1
PAUSE 100

GOTO MAIN

Ioannis
- 19th March 2007, 07:37
Yassou Niko!

If the power is taken before the Write commands, then it is possible to loose the values. When do you power off the device?

Ioannis

savnik
- 19th March 2007, 07:51
Yassou Niko!

If the power is taken before the Write commands, then it is possible to loose the values. When do you power off the device?

Ioannis

Geiasou Giannh (ta agglika mou einai xalia)
I turn off the power after enough (>30 sec) time when change the value

Ioannis
- 19th March 2007, 08:03
Time is not the most critical point. If the program never makes it to the Write commands, then it sure will never store the values to EEPROM.

Ioannis

mackrackit
- 19th March 2007, 08:10
I had a similar problem and fixed it by using two variables. Do not know why this worked, but I have used this routine for some time now.


cnt var byte
Pb1 var word
Pset var word
READ 0,Pset.BYTE0
READ 1,Pset.BYTE1
Pb1 = Pset

C_P:
for cnt = 1 to 1
Pb1=Pb1+1
WRITE 0,Pb1.BYTE0
WRITE 1,Pb1.BYTE1
READ 0,Pset.BYTE0
READ 1,Pset.BYTE1
pause 100
next
RETURN


Maybe all you need is the count routine to ensure that the data is being written?

savnik
- 20th March 2007, 17:51
I have 4 routines to write and read

savnik
- 20th March 2007, 18:27
Need to add the : Include "Modedefs.Bas" ;

mackrackit
- 20th March 2007, 18:43
That would do it. Was scratching my head...

jason
- 8th June 2007, 15:46
hello ya all,

I have been at this for 3 days and nights now, i give up, I need help.

Its simple in the pbp manual and from what Ive read in this forum, but to no luck. heres the details, not in the exact order

pbp 2.47
Include "modedefs.bas" ' is included
DISABLE ' to turn off interupts even though i never hae used them
DEFINE OSC 4
TRISA = %11011
TRISB = %11011011

The problem is somtimes it works and somtimes it dosn't. When I read back the data after i write it, it reads correct. but after Ive turned it off and back on it comes up with weird numbers, random numbers. I send it to and lcd through serout2, and also receive a command or two. but I dont think the problem is there because other data shows up fine. the exact full code will be down below, but for now to point out where I think the problem is.

WRITEIT:

WRITE 0,T0
READ 0,T0
WRITE 1,T1
READ 1,T1
WRITE 2,P0
READ 2,P0
WRITE 3,P1
READ 3,P1
WRITE 4,C0
READ 4,C0
WRITE 5,C1
READ 5,C1
RETURN

If my problem is somewhere else then Please point it out, cause I have tried everything. I am not one to give up easy, so for me to be here asking for help is rare. I am not an expert at pbp, but I do my best and can do almost everything I set out to do. here is the rest of my code

Include "modedefs.bas" ' Include serial modes
DEFINE OSC 4
TRISA = %11011
TRISB = %11011011

'--------------------------DECLARES------------------------------

PERCENT VAR BYTE
TOTAL VAR WORD
CAMBIO VAR WORD
PREMIOS VAR WORD
TT VAR WORD
PP VAR WORD
CC VAR WORD
COUNTING VAR BYTE
AMOUNT VAR BYTE
MAC VAR BYTE
DIP1 VAR BYTE
DIP2 VAR BYTE
DIP3 VAR BYTE
DONE VAR BYTE
COINOUT VAR PORTB.0
COININ VAR PORTB.1
MOTOR VAR PORTB.2
LLAVE VAR PORTB.3
BUTTON1 VAR PORTB.4
COUNTER VAR PORTB.5
A VAR WORD
C0 VAR CAMBIO.BYTE0
C1 VAR CAMBIO.BYTE1
T0 VAR TOTAL.byte0
T1 VAR TOTAL.byte1
P0 VAR PREMIOS.BYTE0
P1 VAR PREMIOS.BYTE1


X VAR BYTE

'-------------------------------SETUP-----------------------------

counter=0
motor=0
DONE=0

'----------------------------turn off interupts-------------------
DISABLE
'-----------------------------get data-----------------------------

pause 100
READ 0,T0
READ 1,T1
READ 2,P0
READ 3,P1
READ 4,C0
READ 5,C1
READ 6,MAC
PAUSE 500

AMOUNT=100
COUNTING=0

'----------------------------DIP SETUP-----------------------------

DIP1=PORTA.0
IF DIP1=0 THEN
DIP1=40
ELSE
DIP1=20
ENDIF

DIP2=PORTA.1
IF DIP2=0 THEN
DIP2=20
ELSE
DIP2=10
ENDIF

DIP3=PORTB.7
IF DIP3=0 THEN
DIP3=10
ELSE
DIP3=5
ENDIF

IF PORTA.4=0 THEN
AMOUNT=25
ELSE
AMOUNT=100
ENDIF

PERCENT=DIP1+DIP2+DIP3
IF PERCENT=70 THEN PERCENT=100
IF BUTTON1 = 0 THEN BOR

'--------------------------------MAIN LOOP---------------------------

LOOP:
IF COININ = 1 THEN COUNT1COIN
IF COINout = 1 THEN COINOUT100
IF PORTB.6 = 1 THEN LLA2
IF LLAVE = 1 THEN LLAVE1
IF BUTTON1 = 0 THEN SACAR
GOTO LOOP

'-------------------------LLAVERO CONNECTED--------------------------

LLA2:
PAUSE 500
FOR X=1 TO 5
GOSUB INFO
NEXT X
GOTO BORRAR

'--------------------------CONTAR 1 MONEDA---------------------------

COUNT1COIN:
PAUSE 20
IF COININ=1 THEN COUNT1COIN
TOTAL=TOTAL+1
GOSUB WRITEIT
GOTO LOOP

'----------------------CONTAR 1 MONEDA SALIENDO----------------------

COINOUT100:
PREMIOS=PREMIOS+1
TOTAL=TOTAL-1
GOSUB WRITEIT
GOTO LOOP

'-------------------------CONTAR 1 A CONTADOR------------------------

CNT:
COUNTER=1
PAUSE 40
COUNTER=0
PAUSE 50
RETURN

'------------------------EL LLAVE DEL CLIENTE------------------------

LLAVE1:
PAUSE 100
IF LLAVE=1 THEN LLAVE1

IF CAMBIO +AMOUNT > (TOTAL/PERCENT)*100 THEN LOOP
COUNTING=0
MOTOR=1

COUNT100:
IF COINOUT=1 THEN COUNT100WAIT
GOTO COUNT100

COUNT100WAIT:
PAUSE 5
IF COINOUT=0 THEN COUNT100DONE
GOTO COUNT100WAIT

COUNT100DONE:
COUNTING=COUNTING+1
TOTAL=TOTAL-1
CAMBIO=CAMBIO+1
GOSUB WRITEIT

IF COUNTING=AMOUNT THEN
motor=0
gosub cnt
PAUSE 300
GOTO LOOP
ELSE
ENDIF

gosub cnt

GOTO COUNT100

'-----------------------------GUARDAR INFO--------------------------
WRITEIT:

WRITE 0,T0
READ 0,T0
WRITE 1,T1
READ 1,T1
WRITE 2,P0
READ 2,P0
WRITE 3,P1
READ 3,P1
WRITE 4,C0
READ 4,C0
WRITE 5,C1
READ 5,C1
RETURN

'PARA NO BORRAR CON EL BUTTONES AL MENOS QUE NO TIENE UN # DE MAC


BOR:
IF BUTTON1 = 0 THEN BOR
IF MAC > 251 THEN
GOTO BORRAR1
ELSE
GOTO LOOP
ENDIF

'----------------------------BORRAR INFO---------------------------

BORRAR:
SERIN2 PORTA.3,16780, 500,BORRAR,[WAIT ("CB"),DEC1 DONE]
IF DONE=1 THEN BORRAR1
IF DONE=0 THEN MAC1
GOTO BORRAR

BORRAR1:
TOTAL=0
PREMIOS=0
CAMBIO=0

GOSUB WRITEIT

FOR X=1 TO 5
GOSUB INFO
NEXT X

GOTO LOOP

'----------------------MANDAR LA INFO AL LLAVERO-------------------

INFO:

A = TOTAL * 100 'A is temporary storage of computation
A = DIV32 PERCENT 'using DIV32... B can be any integer up to 65534
A = A / 100 'final result is placed in variable A as an integer... any

PREMIOS=A
SEROUT2 PORTA.2,16780,["M",DEC3 MAC]
PAUSE 100
SEROUT2 PORTA.2,16780,["T",DEC5 TOTAL]
PAUSE 100
SEROUT2 PORTA.2,16780,["P",DEC5 PREMIOS]
PAUSE 100
SEROUT2 PORTA.2,16780,["%",DEC3 PERCENT]
PAUSE 100
SEROUT2 PORTA.2,16780,["S",DEC5 CAMBIO]
RETURN

'-----------------------GRABAR EL # DE MAC-------------------------

MAC1:
serin2 PORTA.3,16780, MAC1,[WAIT ("M"),DEC3 MAC]
WRITE 6,MAC
READ 6,MAC
FOR X=1 TO 5
GOSUB INFO
NEXT X
GOTO BORRAR

'------------------------SACAR EL GANACIAS-------------------------

SACAR:
PAUSE 100
IF BUTTON1=0 THEN SACAR
IF TOTAL < 100 THEN LOOP
MOTOR=1
COUNTING=0

CAMOUNT:
IF COINOUT=1 THEN CAMOUNTWAIT
GOTO CAMOUNT

CAMOUNTWAIT:
PAUSE 5
IF COINOUT=0 THEN CDONE
GOTO CAMOUNTWAIT

CDONE:
COUNTING=COUNTING+1
TOTAL=TOTAL-1
GOSUB WRITEIT

IF COUNTING=100 THEN
MOTOR=0
PAUSE 300
GOTO LOOP
ELSE
ENDIF
GOTO CAMOUNT

skimask
- 8th June 2007, 17:01
What PIC are you using?
What are you using for pullup values going out to the EEPROM?

jason
- 8th June 2007, 17:10
Its the internal eeprom of the pic16f84a

skimask
- 8th June 2007, 17:16
Its the internal eeprom of the pic16f84a

uhh...der...it sure is...dumb question on my part...


Break it down, get it simple, get rid of all of that other stuff in your program, make something seriously simple, and build it back up. There is a bit of a logic error in your program that'll probably cause your symptoms.

jason
- 8th June 2007, 18:56
Thank you for your quick help on this

Ok I did as you suggested

I made a new file, and slowly added until I had a problem. I'm not sure if this is the problem with my "write" but I wouldn't doubt it, due to some sort of overflow.

here I am trying to get a percentage of a word sized integer


percent=35
example: A=65535 * .35 or A=(65535*100) /35

'-----------
A = TOTAL * 100 'A is temporary storage of computation
A = DIV32 PERCENT 'using DIV32... B can be any integer up to 65534
'-----------

if total=100 wouldn't A=35 ???


I'm not familiar with DIV32 at all, I read up on it and understand somewhat how it works, becuase PBP can't deal with numbers larger than a "word" it uses this as a temperary variable so that people like me can do this type of math, right ?

Acetronics2
- 8th June 2007, 19:43
Hi, Jason

Did you had a look to THAT Thread ???

http://www.picbasic.co.uk/forum/showthread.php?t=1078

Alain

jason
- 8th June 2007, 20:13
WOW

I think that is my problem here. However I only understood a little bit of it.

Why is this so complicated just to store a word ?

OK, so I thought storing total.byte0 in location 0 and then storing total.byte1 in location 1 would handle the whole word right ?
'----------------------------------------------------------------------
total=33024 or total.byte0=10000000 and total.byte1=11111111
write 0,total.byte0
write 1,total.byte1

If so then in location 0 would be 10000000 and in location 1 would be 11111111
or is this wrong ?

if it is right then I can't get that data back the same way ?

read 0,total.byte0
read 1,total.byte1

total=33024

if not then what ???? I'm more confused then before, but I think your on the right track

rhino
- 8th June 2007, 20:32
total=33024
Binary(33024) = %1000000100000000
total.BYTE1 = %10000001
total.BYTE0 = %00000000



To write a word, each of the 2 bytes that make up the word must be
written separately:
w Var Word
WRITE 0,w.BYTE0
WRITE 1,w.BYTE1

skimask
- 8th June 2007, 20:41
And there be the logic error I thought I saw earlier...
Now build you program up and see what happens...then we can work on optimizing that program a bit. I looks a bit of a mess...not too bad, but could be better...

jason
- 8th June 2007, 20:47
thank you for setting me straight, however that didnt answer my question. am i reading the data back to "total" correctly ?

skimask
- 8th June 2007, 21:01
thank you for setting me straight, however that didnt answer my question. am i reading the data back to "total" correctly ?

Did you try it out yet?

jason
- 8th June 2007, 21:42
Hello skimask

Yes Ive been working on your suggestion this whole time, But did get side tracked with one of those replys. so here is the conclusion if I take out "IF COINOUT = 1 THEN COINOUT100" from the main loop it works fine. but I dont see what is wrong there. I dont even have any coins going out while I'm testing this to cause a problem. But ive programed the pic and tested it about 4 times now. every time I take it out of the loop it works fine

COINOUT100:
PREMIOS=PREMIOS+1
TOTAL=TOTAL-1
GOSUB WRITEIT
GOTO LOOP

that math was wrong but I figured it out. However even if I take that clear out it still wouldn't write correctly

A = TOTAL * PERCENT
A = DIV32 100

so I keeped working until I came to that conclusion

here is the code in its cut down version with the problem quoted out




Include "modedefs.bas" ' Include serial modes
DEFINE OSC 4
TRISA = %11011
TRISB = %11011011

A VAR WORD
DONE VAR BIT
X VAR BYTE
PERCENT VAR BYTE
TOTAL VAR WORD
PREMIOS VAR WORD
CAMBIO VAR WORD
MAC VAR BYTE
T0 VAR TOTAL.byte0
T1 VAR TOTAL.byte1
P0 VAR PREMIOS.BYTE0
P1 VAR PREMIOS.BYTE1
C0 VAR CAMBIO.BYTE0
C1 VAR CAMBIO.BYTE1
COINOUT VAR PORTB.0
COININ VAR PORTB.1
DONE=0
PERCENT=50

DISABLE
GOSUB READIT

loop:
IF PORTB.6 = 1 THEN LLACONECTED
IF COININ = 1 THEN COUNT1COIN
' IF COINout = 1 THEN COINOUT100 'this is the problem
GOTO LOOP

COUNT1COIN:
PAUSE 20
IF COININ=1 THEN COUNT1COIN
TOTAL=TOTAL+1
GOSUB WRITEIT
GOTO LOOP

LLACONECTED:
GOSUB READIT
PAUSE 500
FOR X=1 TO 5
GOSUB INFO
NEXT X
GOTO BORRAR


BORRAR:
SERIN2 PORTA.3,16780, 500,BORRAR,[WAIT ("CB"),DEC1 DONE]
IF DONE=1 THEN BORRAR1
IF DONE=0 THEN
gosub info
gosub info
gosub info
else
endif
GOTO BORRAR

BORRAR1:
TOTAL=0
PREMIOS=0
CAMBIO=0
GOSUB WRITEIT
FOR X=1 TO 5
GOSUB INFO
NEXT X
GOTO LOOP

WRITEIT:
WRITE 0,T0
WRITE 1,T1
WRITE 2,P0
WRITE 3,P1
WRITE 4,C0
WRITE 5,C1
RETURN

READIT:
READ 0,T0
READ 1,T1
READ 2,P0
READ 3,P1
READ 4,C0
READ 5,C1
READ 6,MAC
RETURN

INFO:
SEROUT2 PORTA.2,16780,["M",DEC3 MAC]
PAUSE 100
SEROUT2 PORTA.2,16780,["T",DEC5 TOTAL]
PAUSE 100
SEROUT2 PORTA.2,16780,["P",DEC5 PREMIOS]
PAUSE 100
SEROUT2 PORTA.2,16780,["S",DEC5 CAMBIO]
PAUSE 100
rETURN

CNT:
COUNTER=1
PAUSE 20
COUNTER=0
PAUSE 20
RETURN

'COINOUT100:
' PREMIOS=PREMIOS+1
' TOTAL=TOTAL-1
' GOSUB WRITEIT
'GOTO LOOP

skimask
- 9th June 2007, 00:30
Try this out:

Include "modedefs.bas" ' Include serial modes
DEFINE OSC 4
TRISA=$1b : trisb=$db : a var word : done var bit : x var byte : percent var byte : total var word : premios var word : cambio var word : mac var byte : t0 var total.byte0 : t1 var total.byte1
p0 var premios.byte0 : p1 var premios.byte1 : c0 var cambio.byte0 : c1 var cambio.byte1 : coinout var portb.0 : coinin var portb.1 : done=0 : percent=50
DISABLE
GOSUB READIT
loop:
IF PORTB.6 = 1 THEN LLACONECTED
IF COININ = 1 THEN COUNT1COIN
IF COINout = 1 THEN COINOUT100 'this is the problem
GOTO LOOP
COUNT1COIN: PAUSE 20 : IF COININ=1 THEN COUNT1COIN
TOTAL=TOTAL+1 : GOSUB WRITEIT:GOTO LOOP
LLACONECTED: gosub readit : pause 500:for x=1 to 5:gosub info:next x : goto borrar
BORRAR: SERIN2 PORTA.3,16780, 500,BORRAR,[WAIT ("CB"),DEC1 DONE]
IF DONE=1 THEN BORRAR1
IF DONE=0 THEN
gosub info:gosub info:gosub info
endif
GOTO BORRAR
BORRAR1: total=0 : premios=0:cambio=0:gosub writeit:for x=1 to 5 : gosub info:next x:goto loop
writeit: write 0,t0:write 1,t1:write 2,p0:write 3,p1:write 4,c0:write 5,c1 : return
readit: read 0,t0:read 1,t1:read 2,p0:read 3,p1:read 4,c0:read 5,c1:read 6,mac:return
info: serout2 porta.2,16780,["M",dec3 mac] : pause 100:serout2 porta.2,16780,["T",dec5 total] : pause 100:serout2 porta.2,16780,["P",dec5 premios] : pause 100:serout2 porta.2,16780,["S",dec5 cambio]
pause 100:return
CNT: COUNTER=1:PAUSE 20:COUNTER=0:PAUSE 20:RETURN
COINOUT100:
PREMIOS=PREMIOS+1:if total > 0 then TOTAL=TOTAL-1
GOSUB WRITEIT:GOTO LOOP
END

Darrel Taylor
- 9th June 2007, 01:54
Get a few more Colon's in there and we're gonna be in deep ____.

Or have a cancer problem. :eek:
<br>

BigWumpus
- 9th June 2007, 10:20
What happens, if you switch off the power ?
Maybe the code just think, the switch is pressed and try to write to the eeprom - while power is falling...

jason
- 9th June 2007, 14:56
Yep that is my problem.

if I take out the "write" it saves fine

COINOUT100:
PREMIOS=PREMIOS+1:if total > 0 then TOTAL=TOTAL-1
:GOTO LOOP 'GOSUB WRITEIT

So I did a little checking and the machine I'm interfacing to sends several signals as its lossing power, somthing to do with a cheap design cause theres no other reason. I will buy a scope to see if its a specific signal or just random crap. I think its just random crap cuase if I hook a anolog counter to it, it counts up to differrent amounts somtime 3 somtimes up to 6.

As to my messy code design, I'm sorry skimask. I have never had any training of any kind nor has anyone ever showed me how to write decent code. This is the first time in 15 years I have ever been on a forum for basic, quickbasic, visual basic, or pic basic pro.

I am one to learn things on my own, but as you pointed out (at my messy code) that type of learning has its problems. I do my best

I will continue this forum experience, Its al right. thank you all for your help with this one.

And thank you BigWumpus for figuring this one out for me......