EEprom help

Thread Starter

k9act

Joined Jan 25, 2014
3
I need a counter that will save the last count in event of power outage.

I have succeeded in getting the last count into EEprom and reading it back at power up cycle. It only took about two weeks, (ha ha) to figure out how to do this but now I realize that there was no way to clear it back to zero if I want it to start over.

The attached is a simple binary counter program that I am using to learn this and will use the code to update a decimal 7 segment version when I get the EEprom stuff to work.


Can someone tell me how to clear it to zero?

Thanks,

Jack

Rich (BB code):
;**********************************************************************
;                                                                     *
;    Filename:        simpleEP4.asm      

;   Puts manually entered number in first EEprom location 
;   into PortB   
	;SITS THERE TILL BUTTON PRESSED
; 	STARTS FROM LAST COUNT WHEN POWER CYCLED  js                                 *
;                                                                     *
;                                                               *
;**********************************************************************

    list      p=16F628A           ; list directive to define processor
    #include <p16F628A.inc>       ; processor specific variable definitions

    errorlevel  -302              ; suppress message 302 from list file

    __CONFIG  2330 ; _CP_OFF  & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT 


;**********************************************************************
	ORG	20h ;  this does not seem to have anything to do with
;			   anything.  js	

	
d1	equ	20
d2	equ	21
d3	equ 22
last	equ	23


	CLRF PORTA ;Initialize PORTA by setting output data latches
	MOVLW 0x07 ;Turn comparators off and
	MOVWF CMCON ;enable pins for I/O functions
	BSF STATUS, RP0;Select Bank1
	MOVLW 0x1F ;Value used to initialize data direction
	MOVWF TRISA ;Set RA<4:0> as inputs TRISA<5> always
					;read as ‘1’.TRISA<7:6>depend on oscillator mode
	

	bsf status, rp0		;	set = bank1

 		 movlw B'00000001'    ;  makes ra0 input
         movwf trisa           ; contents of W copied to PORT A ...
  
		 movlw B'00000000' 
      	 movwf trisb           ; all PORT B out
      
	     bcf status, rp0 	;	clear = bank0
		clrf	portb

	
		
	BsF STATUS, RP0 ; Bank 1

	MOVLW	00   ;FIRST LOCATION IN EEPROM JS
	MOVWF EEADR ; Address to read
	BSF EECON1, RD ; EE Read
	MOVF EEDATA, W ; W = EEDATA

	BCF STATUS, RP0 ; Bank 0

	MOVWF	PORTb


	
loopb:
	BCF	STATUS, RP0;  BANK 0
	btfss	porta,0
	incf	portb

	CALL DELAY
	
	MOVF PORTB, W

	MOVWF LAST




	MOVF	LAST,W
	BsF STATUS, RP0 ; Bank 1
	MOVWF	EEDATA
	

	bcf		stAtus,RP0	;BANK 0

	CALL EEWRITE ;Call EEPROM write routine



		goto loopb

EEWRITE:
	BSF STATUS, RP0 ; Bank 1
	BSF EECON1, WREN ; Enable write
	MOVLW 55h
	MOVWF EECON2 ; Write 55h
	MOVLW h'AA'
	MOVWF EECON2 ; Write AAh
	BSF EECON1,WR ; Set WR bit



	BcF STATUS, RP0 ; Bank 0


EEWR_WAIT: ;Wait for write cycle completed
	BTFsc PIR1,EEIF ;Write cycle completed?
	GOTO EEWR_WAIT ;No, wait
	BcF PIR1,EEIF ;Yes, we can clear write flag
	RETURN


; Actual delay = 1 seconds = 1000000 cycles

Delay
			;999990 cycles
	movlw	0x07
	movwf	d1
	movlw	0x2F
	movwf	d2
	movlw	0x03
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;6 cycles
	goto	$+1
	goto	$+1
	goto	$+1

			;4 cycles (including call)
	return



        END                       ; directive 'end of program'
 

Attachments

Last edited by a moderator:

kubeek

Joined Sep 20, 2005
5,795
The device it the code was written for looks like a fairly big one, are you sure you need to do this in assembler? If you moved to C and used the libraries provided with your compiler things would get so much easier to look at and see what needs changing and where.
 

Thread Starter

k9act

Joined Jan 25, 2014
3
I wrote it for a 16f628a so I don't really understand what you mean.

But finishing it seems pretty trivial compared to learning another new language.

I just don't happen to know how to do it.

js
 

Thread Starter

k9act

Joined Jan 25, 2014
3
I tried to explain what I am doing but I will try again.

The counter is counting turns on a machine. If the power goes off, the count is lost.

My fix it to write the current count to eeprom so that in the event of a power failure, that count is loaded into the counter when the power comes back.

It works perfectly except that when I finish the job, I want to reset and start counting from zero.

Unfortunately, the normal MCLR reset obeys the same orders and resets to the last count instead of zero.

I need a trick to outsmart my very clever code.

js
 

JohnInTX

Joined Jun 26, 2012
4,787
Unfortunately, the normal MCLR reset obeys the same orders and resets to the last count instead of zero.
So.. if the problem is to know the difference between power fail and MCLR/ reset you can examine the POR/ BOD/ TO/ PD/ bits in the STATUS and PCON registers after any reset and know what generated it.

That said, using MCLR/ as a 'reset the counter function' may prove problematic if your code grows. A reset button on the I/O that handled zeroing the counter and updating EEPROM would be my choice.

Have fun!
 

Ian Rogers

Joined Dec 12, 2012
1,136
Your code shows an eeprom write every cycle... The eeprom in the pic would last about a week before its destroyed.... You need to use "smart eeprom writing" so if the count hasn't changed... Then don't write..

You only have only 100,000 or so write cycles... Also remember that the internal eeprom requires the same write delay to update its values... 5mS or so, or the write will fail...
 

spinnaker

Joined Oct 29, 2009
7,830
That said, using MCLR/ as a 'reset the counter function' may prove problematic if your code grows. A reset button on the I/O that handled zeroing the counter and updating EEPROM would be my choice.

Have fun!
You can use the same button or function that resets / restarts your run job on the machine.

A reset button would come in real handy for the unforeseen event of "NEXT !!!"
Your code shows an eeprom write every cycle... The eeprom in the pic would last about a week before its destroyed.... You need to use "smart eeprom writing" so if the count hasn't changed... Then don't write..

You only have only 100,000 or so write cycles... Also remember that the internal eeprom requires the same write delay to update its values... 5mS or so, or the write will fail...
Assuming your MCU has a Broown Out interrupt AND the MCU is subject to the same power failure as the rest of the machine, you could use brown out to save the value of the counter.

So much fir that "clever" code I guess. :eek:
 

Ian Rogers

Joined Dec 12, 2012
1,136
spin said:
Assuming your MCU has a Broown Out interrupt AND the MCU is subject to the same power failure as the rest of the machine, you could use brown out to save the value of the counter.
I don't believe the mid range pic16 can do this... Anyway! I don't think there wouldn't be enough time to store an eeprom value...
 

kubeek

Joined Sep 20, 2005
5,795
Maybe with external undervoltage detector and a diode and a big bank of caps on the PICs supply, you could get fast enough early warning and enough energy left to complete the write.
 

spinnaker

Joined Oct 29, 2009
7,830
I don't believe the mid range pic16 can do this... Anyway! I don't think there wouldn't be enough time to store an eeprom value...
I guess the OP could ad a supercap, add code to monitor the voltage from an ADC. When the voltage starts to drop store the value. Complicated but it should work.


Not to steal the OPs thread but how many times can an EEPROM be written?
 

Ian Rogers

Joined Dec 12, 2012
1,136
spin said:
Not to steal the OPs thread but how many times can an EEPROM be written?
Just checked... 1,000,000...
I use a ramtron device (FRAM)... It's external but the endurance is 1 trillion writes and there is no write delay... I use it in winch payout systems....
 

THE_RB

Joined Feb 11, 2008
5,438
...
It works perfectly except that when I finish the job, I want to reset and start counting from zero.

Unfortunately, the normal MCLR reset obeys the same orders and resets to the last count instead of zero.

I need a trick to outsmart my very clever code.
...
What's the problem? This has been done since the dawn of eeproms.

All you need is a "job start" button that resets the count to zero and memorises it.

Any other situation (when that button is NOT pressed) the count always goes up and is always memorised.
 

atferrari

Joined Jan 6, 2004
4,770
Just checked... 1,000,000...
I use a ramtron device (FRAM)... It's external but the endurance is 1 trillion writes and there is no write delay... I use it in winch payout systems....
Not to derail the thread, Ian. What is it actually?

Could it be I know it by another name?
 
Top