Subject:
Possible 'gpsim' 16F877 EEPROM Data Write Bug
From:
"Tom Alldread, VA7TA" ####@####.####
Date:
15 Oct 2002 17:51:05 -0000
Message-Id: <5.1.0.14.2.20021015100301.00a14ec0@mail.island.net>
Greetings All:
Many thanks to Declan Moriarty for the helpful tips!
I may have encountered a bug with 'gpsim' regarding writes to EEPROM data
memory.
I found that if I try to simulate the code which follows the PIC16F877
data sheet (DS30292C page 43) example where the EECON1,WR bit is tested
upon subroutine entry for a busy condition prior to writing a new byte to
data memory that 'gpsim' locks up in the busy loop waiting for the WR bit
to clear. The code is shown in example A below. This code does run OK and
the data does get written OK in the Win98 MPLAB (sorry I had to mention
here that I tried this!) simulator. As I would much prefer to use 'gpsim' I
decided to try and identify the problem.
I found that if I move the busy loop to the end of the subroutine after
the byte is written and before the WREN bit is cleared as shown in example
B the routine works fine (with the exception that the clearing of the WR
bit occurs after approximately 16 instruction cycles when in actuality it
should take 4-8 mS or about 6000 cycles at the 4 MHz clock rate).
The significant operational disadvantage of leaving the busy loop at the
end of the subroutine is that during realtime operation the writing of a
single byte to data memory will stop the program flow for 4-8 mS while
waiting for the WR flag to clear. If the busy test is left at the entry of
the subroutine this delay only occurs during multiple writes to data memory
within 8 mS of each other. In my application the data memory usually gets
changed a single byte at a time initiated by user input thus the 8 mS stop
in the program flow would never occur. The stop in program flow from
example B would, however, affect some 1 mS timing events.
I hope this information is of value and thanks again for 'gpsim'!
Tom Alldread
EXAMPLE A:
;****************************************************************************************
EEProg:
; Program EEPROM byte - enter with data preloaded in global variables
; byte to be written in data1 & address in data0
;****************************************************************************************
btfsc INTCON,GIE ;skip next if global interrupts disabled
at entry
bsf GIEFlag ;set the GIEflag if GIE enabled at entry
bsf STATUS,RP1 ;select bank 2
bcf STATUS,RP0 ;select bank 2
movf data0,w ;get the address
movwf EEADR ;put it in EE adr register
movf data1,w ;get the data
movwf EEDATA ;put it in EE data register
bsf STATUS,RP0 ;select bank3
EEPLoop ;ensure previous write cycle has completed
btfsc EECON1,WR ;is write cycle complete?
goto EEPLoop ;wait for write to finish
EEReady
bcf EECON1,EEPGD ;point to data memory
bsf EECON1,WREN ;enable EEPROM write
bcf INTCON,GIE ;disable interrupts
movlw h'55'
movwf EECON2 ;write 55
movlw h'AA'
movwf EECON2 ;write AA
bsf EECON1,WR ;start write
btfsc GIEFlag ;enable interrupts only if enabled at entry
bsf INTCON,GIE ;enable interrupts
bcf EECON1,WREN ;disable writes
RtnBk0 bcf STATUS,RP1 ;select bank 0
bcf STATUS,RP0 ;select bank 0
bcf GIEFlag ;clear the GIE flag
return
;==================================================================================
EXAMPLE B:
;****************************************************************************************
EEProg:
; Program EEPROM byte - enter with data preloaded in global variables
; byte to be written in data1 & address in data0
;****************************************************************************************
btfsc INTCON,GIE ;skip next if global interrupts disabled
at entry
bsf GIEFlag ;set the GIEflag if GIE enabled at entry
bsf STATUS,RP1 ;select bank 2
bcf STATUS,RP0 ;select bank 2
movf data0,w ;get the address
movwf EEADR ;put it in EE adr register
movf data1,w ;get the data
movwf EEDATA ;put it in EE data register
bsf STATUS,RP0 ;select bank3
;EEPLoop ;ensure previous write cycle has completed
; btfsc EECON1,WR ;is write cycle complete?
; goto EEPLoop ;wait for write to finish
;EEReady
bcf EECON1,EEPGD ;point to data memory
bsf EECON1,WREN ;enable EEPROM write
bcf INTCON,GIE ;disable interrupts
movlw h'55'
movwf EECON2 ;write 55
movlw h'AA'
movwf EECON2 ;write AA
bsf EECON1,WR ;start write
EEPLoop ;ensure write cycle has completed
btfsc EECON1,WR ;is write cycle complete?
goto EEPLoop ;wait for write to finish
EEReady
btfsc GIEFlag ;enable interrupts only if enabled at entry
bsf INTCON,GIE ;enable interrupts
bcf EECON1,WREN ;disable writes
RtnBk0 bcf STATUS,RP1 ;select bank 0
bcf STATUS,RP0 ;select bank 0
bcf GIEFlag ;clear the GIE flag
return
;==================================================================================
---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.377 / Virus Database: 211 - Release Date: 02/07/15