Hey,
I've written a subroutine to increment a counter stored in EEPROM memory on a PIC16F690.
The routine reads the previous value, increments it and then writes the new value. The routine works but only if I have a delay greater than 200 ms between reading and writing the new value. If the delay isn't there, the value is incremented by 8 (or 6 or 14...not sure what determines the value).
I've copy and pasted my code below. Let me know what you think.
Thanks,
-Phil
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
cblock 0x20
Delay1 ; Assign an address to Delay variables
Delay2
Delay3
Delay4
DATA_EE_DATA
COUNT
COUNT2
COUNT3
endc
org 0
Start
;************************Initialize PORT A***************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTA ;Init PORTA
BSF STATUS,RP1 ;Bank 2
CLRF ANSEL ;digital I/O
BSF STATUS,RP0 ;Bank 1
BCF STATUS,RP1 ;
MOVLW b'00000000' ;Port A all output
MOVWF TRISA
BCF STATUS,RP0 ;Bank 0
;************************Initialize PORT B****************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTB ;Init PORTB
BSF STATUS,RP1 ;Bank 2
CLRF ANSELH ;digital I/O
BSF STATUS,RP0 ;Bank 1
MOVLW b'00000000' ; all output
MOVWF TRISB ;
BCF STATUS,RP0 ;Bank 0
;************************Initialize PORT C***************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTC ;Init PORTC
BSF STATUS,RP1 ;Bank 2
CLRF ANSEL ;digital I/O
BSF STATUS,RP0 ;Bank 1
BCF STATUS,RP1 ;
MOVLW b'00000000'; all output.
MOVWF TRISC
BCF STATUS,RP0 ;Bank 0
;******************************************Read counter value
bsf PORTC,0
BANKSEL EEADR
MOVlw 05h;
MOVWF EEADR ;Data Memory
;Address to read
BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BANKSEL EEDAT ;BANK 2
MOVF EEDAT, W ;W = EEDAT
banksel TMR0 ; BANK 0
movwf COUNT;
BSF PORTC,1 ;Turn an LED on
;********************************************Increment counter
INCF COUNT,1
;********************************************Write the new value
movlw 0x02
movwf Delay3
Readdelay
decfsz Delay1,f ;
goto Readdelay ; ~400ms delay
decfsz Delay2,f ;
goto Readdelay ; Without this delay, the values
decfsz Delay3,f ; are incremented by 8 rather than 1
goto Readdelay ;
BANKSEL EEADR ;Bank 2
movlw 05h;
MOVWF EEADR ;Data Memory Address to write
banksel TMR0 ;Bank 0
MOVF COUNT,0;
BANKSEL EEDAT ;Bank 2
MOVWF EEDAT ;Data Memory Value to write
BANKSEL EECON1 ;Bank 3
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, WREN ;Enable writes
BCF INTCON, GIE ;Disable INTs.
BTFSC INTCON, GIE ;SEE AN576
GOTO $-2
MOVLW 0x55 ;
MOVWF EECON2 ;Write 55h
MOVLW 0xAA ;
MOVWF EECON2 ;Write AAh
BSF EECON1, WR ;Set WR bit to begin write
Wait2 btfsc EECON1,WR ; Wait for write complete
goto Wait2
bcf EECON1,WREN ; Disable write
BCF EECON1, WREN ;Disable writes
banksel TMR0 ;Bank 0
bsf PORTC,2 ;Turn some LEDS on
bsf PORTC,3
bsf PORTC,1;
end
I've written a subroutine to increment a counter stored in EEPROM memory on a PIC16F690.
The routine reads the previous value, increments it and then writes the new value. The routine works but only if I have a delay greater than 200 ms between reading and writing the new value. If the delay isn't there, the value is incremented by 8 (or 6 or 14...not sure what determines the value).
I've copy and pasted my code below. Let me know what you think.
Thanks,
-Phil
#include <p16F690.inc>
__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
cblock 0x20
Delay1 ; Assign an address to Delay variables
Delay2
Delay3
Delay4
DATA_EE_DATA
COUNT
COUNT2
COUNT3
endc
org 0
Start
;************************Initialize PORT A***************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTA ;Init PORTA
BSF STATUS,RP1 ;Bank 2
CLRF ANSEL ;digital I/O
BSF STATUS,RP0 ;Bank 1
BCF STATUS,RP1 ;
MOVLW b'00000000' ;Port A all output
MOVWF TRISA
BCF STATUS,RP0 ;Bank 0
;************************Initialize PORT B****************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTB ;Init PORTB
BSF STATUS,RP1 ;Bank 2
CLRF ANSELH ;digital I/O
BSF STATUS,RP0 ;Bank 1
MOVLW b'00000000' ; all output
MOVWF TRISB ;
BCF STATUS,RP0 ;Bank 0
;************************Initialize PORT C***************
BCF STATUS,RP0 ;Bank 0
BCF STATUS,RP1 ;
CLRF PORTC ;Init PORTC
BSF STATUS,RP1 ;Bank 2
CLRF ANSEL ;digital I/O
BSF STATUS,RP0 ;Bank 1
BCF STATUS,RP1 ;
MOVLW b'00000000'; all output.
MOVWF TRISC
BCF STATUS,RP0 ;Bank 0
;******************************************Read counter value
bsf PORTC,0
BANKSEL EEADR
MOVlw 05h;
MOVWF EEADR ;Data Memory
;Address to read
BANKSEL EECON1 ;
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, RD ;EE Read
BANKSEL EEDAT ;BANK 2
MOVF EEDAT, W ;W = EEDAT
banksel TMR0 ; BANK 0
movwf COUNT;
BSF PORTC,1 ;Turn an LED on
;********************************************Increment counter
INCF COUNT,1
;********************************************Write the new value
movlw 0x02
movwf Delay3
Readdelay
decfsz Delay1,f ;
goto Readdelay ; ~400ms delay
decfsz Delay2,f ;
goto Readdelay ; Without this delay, the values
decfsz Delay3,f ; are incremented by 8 rather than 1
goto Readdelay ;
BANKSEL EEADR ;Bank 2
movlw 05h;
MOVWF EEADR ;Data Memory Address to write
banksel TMR0 ;Bank 0
MOVF COUNT,0;
BANKSEL EEDAT ;Bank 2
MOVWF EEDAT ;Data Memory Value to write
BANKSEL EECON1 ;Bank 3
BCF EECON1, EEPGD ;Point to DATA memory
BSF EECON1, WREN ;Enable writes
BCF INTCON, GIE ;Disable INTs.
BTFSC INTCON, GIE ;SEE AN576
GOTO $-2
MOVLW 0x55 ;
MOVWF EECON2 ;Write 55h
MOVLW 0xAA ;
MOVWF EECON2 ;Write AAh
BSF EECON1, WR ;Set WR bit to begin write
Wait2 btfsc EECON1,WR ; Wait for write complete
goto Wait2
bcf EECON1,WREN ; Disable write
BCF EECON1, WREN ;Disable writes
banksel TMR0 ;Bank 0
bsf PORTC,2 ;Turn some LEDS on
bsf PORTC,3
bsf PORTC,1;
end