Hi guys,
I'm trying to use EEPROM fro PIC16F684 to keep some variables values stores for when the power is turned of.
When I write to EEPROM and then read it back, I get only crap, can you check it out?
I think it may be the LCDout of my variables contents because I use a led that blinks to show the value (i.e.: blink 3X if the value is 3)
Here is the code.
Thanks for any help.
----
DEFINE OSC 8 'set OSC value to 8MHz for instructions PAUSE, PAUSEus and SOUND. will use 8mhz int hs osc (default after reset: 4MHz)
'-----------------------------------------
'DEFINES FOR LCD
'MEMO: LCD can take about 1s to initialize
' Set LCD Data port
DEFINE LCD_DREG PORTC
' Set starting Data bit (0 or 4) if 4-bit bus = portC bit 0 for LCD Data bit 4
DEFINE LCD_DBIT 0
' Set LCD Register Select port, ENABLER WPU pour ce bit !!!!!!!!!!!!!!
DEFINE LCD_RSREG PORTA
' Set LCD Register Select bit
DEFINE LCD_RSBIT 4
' Set LCD Enable port
DEFINE LCD_EREG PORTA
' Set LCD Enable bit
DEFINE LCD_EBIT 5
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set data delay time in us
DEFINE LCD_DATAUS 50
'-----------------------------------------
'PIC16F684: 2048 WORDS of flash program memory (datasheet p1)
'MEMO: PIC16F684 has 256 BYTES of EEPROM memory (datasheet p71-p74)
'Access: using WRITE and READ instruction in PBPpro
'Related registers: EECON1, EEDAT, EEADR
'EEIF bit (PIR1<7>) interrupt flag is set when write is complete. It must be cleared in software.
'INTERRUPTS MUST be disabled during read !!!!
'good practice: verify the data written after a write.
'IF USING assembler code to read and write, there is a specific sequence for instructions, see datasheet, p73
'WRITE
'WRITE Address,Value
'Write Value to the on-chip EEPROM at the specified Address.
'WRITE is used to set the values of the on-chip EEPROM at runtime.
'To set the values of the on-chip EEPROM at programming-time, use the DATA or EEPROM statement.
'Each WRITE is self-timed and takes about 10 milliseconds to execute on a PICmicro.
'If interrupts are used in a program, they must be turned off (masked, not DISABLEd) before executing a WRITE, and turned back on (if desired) after the write instruction is complete. An interrupt occurring during a WRITE may cause it to fail.
' WRITE 5,B0 ' Send value in B0 to EEPROM location 5
'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
'READ
'READ Address,Var
'Read the on-chip EEPROM at the specified Address and stores the result in Var.
' READ 5,B2 ' Put the value at EEPROM location 5 into B2
'To read a word, each of the 2 bytes that make up the word must be read separately:
'w Var Word
'READ 0, w. BYTE0
'READ 1, w. BYTE1
'-----------------------------------------
'VARIABLES
max_mags VAR BYTE 'max carried mags
max_medics VAR BYTE 'max carried medic kits
rem_mags VAR BYTE 'remaining mags
rem_medics VAR BYTE 'remaining medic kits
i VAR BYTE 'counter var
'EEPROM memory locations for the backup of the variables
mem_max_mags CON 1
mem_max_medics CON 2
mem_rem_mags CON 3
mem_rem_medics CON 4
'--------------------------------------------------------------------------------------------------------------------------------------------
CLEAR
OSCCON = %01110001 'int osc, hs, 8mhz
CMCON0 = %00000111 'comparators OFF, val = 7
ANSEL = %00000000 'choose digital i/o, val = 0
OPTION_REG = %01111111 'enable internal porta weak pullups resistors (no weak pull-up available for porta.3), p12. they bring pin to High state; to set a change, pull pin to ground
WPUA = %010011 'enable weak pull ups individually on portA, rem: porta.3 (MCLR) has no internal weak pullups
INTCON = %10001000 'enable GIE and porta interrupts on change, datasheet p13
IOCA = %000011 'enable interrupts on change individually (for porta)
TRISA = %000011 'a4 and a5 are outputs (to lcd pins)
TRISC = %000000
PORTA = %000000 'turn off porta pins (initialize to Low state = 0v)
PORTC = %000000 'turn off portc pins (initialize to Low state = 0v)
'porta pins with weak pullups will be set to high (i.e. 5v by the pullups)
'--------------------------------------------------------------------------------------------------------------------------------------------
Symbol ammo = PORTA.0 'for interrupt request
Symbol medic = PORTA.1
'Symbol unuseda1 = PORTA.2
'Symbol unuseda2 = PORTA.3
Symbol en = PORTA.4
Symbol rs = PORTA.5
Symbol data0 = PORTC.0
Symbol data1 = PORTC.1
Symbol data2 = PORTC.2
Symbol data3 = PORTC.3
Symbol backlight = PORTC.4
Symbol signal = PORTC.5
'--------------------------------------------------------------------------------------------------------------------------------------------
'SETTING VARIABLES 'CLEAR command has reset them
max_mags = 1 'available ammo mag when device is turned on
max_medics = 2 'available medic kits when device is turned on
rem_mags = 3 'remaining ammo mags
rem_medics = 4 'remaining medic kits
'--------------------------------------------------------------------------------------------------------------------------------------------
ON INTERRUPT GOTO mainroutine 'when interrupt occurs on portA pin a0 or pin a1 go to int routine
'--------------------------------------------------------------------------------------------------------------------------------------------
START:
FLAGS = 0 'IF LCD IS powered off while in action
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
HIGH backlight 'turn on backlight
LCDOUT $FE, 1 'clear
LCDOUT $FE, 2 'to home position
LCDOUT "SUPPLIER"
LCDOUT $FE, $c0 'move at begining of 2nd line
LCDOUT "MODULE"
PAUSE 3000 'pause 3s
LCDOUT $FE, 1 'clear
LOW backlight 'turn of backlight
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
HIGH signal
PAUSE 500
LOW signal
GOSUB displayval
max_mags = 0 'available ammo mag when device is turned on
max_medics = 0 'available medic kits when device is turned on
rem_mags = 0 'remaining ammo mags
rem_medics = 0 'remaining medic kits
GOSUB displayval
WRITE mem_max_mags,5
WRITE mem_max_medics,6
WRITE mem_rem_mags,7
WRITE mem_rem_medics,8
READ mem_max_mags,max_mags
READ mem_max_medics,max_medics
READ mem_rem_mags,rem_mags
READ mem_rem_medics,rem_medics
GOSUB displayval
'--------------------------------------------------------------------------------------------------------------------------------------------
loop1: 'main program is a stupid loop waiting for a int on change triggered on porta.0 or porta.1 (high to low)
'shortest pause possible to quickly jump to int routine
'at 8MHz, minimum delay is 12 uS (or 24 uS at 4MHz)
HIGH signal
PAUSE 500
LOW signal
PAUSE 500
GOTO loop1
'or should we use SLEEP, an int will wake the uc up (uses WatchDogTimer !)
'--------------------------------------------------------------------------------------------------------------------------------------------
DISABLE 'disable interrupts while executing the interrupt routine (do not put check interrupts calls after each instruction)
mainroutine: 'int routine code starts here
'-------------
donothing:
RESUME 'resume program where it left for the interrupt routine
ENABLE
displayval:
HIGH backlight
LCDOUT $FE, 1 'clear
LCDOUT $FE, 2 'to home position
LCDOUT "maxmag"
LCDOUT $FE, $c0 'move at begining of 2nd line
LCDOUT max_mags
PAUSE 2000 'pause 3s
LCDOUT $FE, 1
FOR i = 0 to max_mags
HIGH signal
PAUSE 300
LOW signal
next i
'clear
LCDOUT $FE, 1 'clear
LCDOUT $FE, 2 'to home position
LCDOUT "maxmed"
LCDOUT $FE, $c0 'move at begining of 2nd line
LCDOUT max_medics
PAUSE 2000 'pause 3s
LCDOUT $FE, 1 'clear
FOR i = 0 to max_medics
HIGH signal
PAUSE 300
LOW signal
next i
LCDOUT $FE, 1 'clear
LCDOUT $FE, 2 'to home position
LCDOUT "remmag"
LCDOUT $FE, $c0 'move at begining of 2nd line
LCDOUT rem_mags
PAUSE 2000 'pause 3s
LCDOUT $FE, 1 'clear
FOR i = 0 to rem_mags
HIGH signal
PAUSE 300
LOW signal
next i
LCDOUT $FE, 1 'clear
LCDOUT $FE, 2 'to home position
LCDOUT "remmed"
LCDOUT $FE, $c0 'move at begining of 2nd line
LCDOUT rem_medics
PAUSE 2000 'pause 3s
LCDOUT $FE, 1
FOR i = 0 to rem_medics
HIGH signal
PAUSE 300
LOW signal
next i
LOW backlight
RETURN
END
Bookmarks