How can I write into 256 bytes EEPROM with loop on assembly ?

Status
Not open for further replies.

bianchi77

Advanced Member level 4
Joined
Jun 11, 2009
Messages
1,313
Helped
21
Reputation
44
Reaction score
20
Trophy points
1,318
Location
California
Visit site
Activity points
9,442
Guys,

How can I write into 256 bytes EEPROM with loop on assembly (PIC) ?

I need to use loop for it, but not clearly understand on how to do it?
I have function for writing to EEPROM already,

Code:
movlw 0x01    ;content of eeprom
call write_eeprom;

I have 256 content, shall I use btfss status,z ? nested loop ?

any links or suggestions will be appreciated,

thanks
 

hello,

you can handle a counter of data stored into EEPROM.
counter defined as a byte so
after 255, and increment, will go to 0
so check if zero = end of eeprom
Code:
.....
clrf counter
loop:

....
code depends how do you select the data to send to EEPROM
...
....
incf [B]counter[/B],f
btfss status,z     ; //  seems OK
goto loop
....
 
Last edited:

where should I put my data ?

starting counter : movlw .255 and reduce it until zero and if it's zero, writing process is finished ?

Code:
clrf counter
loop:

....
eeprom data here ?
code depends how do you select the data to send to EEPROM
...
....
incf counter,f
btfss status,z     ; //  seems OK
goto loop
 

is this EEPROM is external or internal. if external then plz consider that pages and how much bytes in single page.
 

yes I'm using internal 256bytes EEPROM, how can I write 256bytes of data using loop ?
thanks
 

hello,

starting counter : movlw .255 and reduce it until zero and if it's zero, writing process is finished ?

clrf counter before the loop entry.
counter=0;
but incf counter,f
so counter =1 at the first loop
before testing if zero

when counter overload from 255 + 1=256 => ( remember counter has a byte size) , so 256 becomes 0
and the test on status is true, so exit of the loop.

where should I put my data ?
is your decision !

what kind of data ?
from where are comming the data ?
it's depend of your application..
explain more ...

call write_eeprom;
write the value of register W in EEPROM and must increase the adress pointed for the next value to store.
( counter can also be used as a pointer = adresse EEPROM memory)
give all details if you want more help..
 

how about I want to write 0x12 data into 0x12 address, 0x13 data into 0x13 address, 0x13 data into 0x13 address and so on from 0x00 untill 0xFF ??
 

hello,

You don't have a multiple of 13
12 + 18x13=246
remain 10 data ?
what to do with this 10 data .. store until FF end of EEPROM ?

are your data in RAM space ?

How it is organized ?

are all your data arranged in a contineous space with no gap between

or you have multiples blocs of data every where
but each bloc has itself contineous data.
1 bloc for the first 12 data
1 bloc for the first 13 data
and so on..


in case of contineous space for all blocs of data
you can use a Counter as pointer to EEPROM memory (and bytes counter!).
and a counter N for the number of data inside a bloc
and use Indirect adressage to get this data and send it to eeprom

Code:
Movlw 12   // nb of data in bloc 1
movwf N ;  // counter of data in bloc
clrf Counter,f
// star of the first bloc 
// choose the correct bank if necessary
movlw  Adresse_1erbloc
movwf FSR
Suivant:
mowf INDF,W
// now W contains the data of bloc1 
call write_eeprom;
incf Counter,f  // pointer adresse EEPROM
inc FSR,f        // pointer inside the bloc
decfsz N;f      // counter of data in the bloc
goto Suivant
// treat  Next Blocs


Movlw 13   // nb of data in bloc 2
movwf N ;  // counter of data in bloc
clrf Counter,f
// star of the second bloc 
// choose the correct bank if necessary
movlw  Adresse_2embloc
movwf FSR
Suivant1 :
mowf INDF,W
// now W contains the data of bloc1 
call write_eeprom;
incf Counter,f  // pointer adresse EEPROM
inc FSR,f        // pointer inside the bloc
decfsz N;f      // counter of data in the bloc
goto Suivant1

....etc...

you can also for all blocs of same size 13 data ,
build a subroutine and use an extra variable to pass
the adress of each bloc as a parameter.

Code:
movlw Adresse_2em_bloc
mowf Adresse_of_the_bloc
call StoreBloc13
movlw Adresse_3em_bloc
mowf Adresse_of_the_bloc
call StoreBloc13
movlw Adresse_4em_bloc
mowf Adresse_of_the_bloc
call StoreBloc13
....
movlw Adresse_19em_bloc
mowf Adresse_of_the_bloc
call StoreBloc13
........ ??? .......



StoreBloc13:
Movlw 13   // nb of data in bloc x
movwf N ;  // counter of data in bloc
clrf Counter,f
// star of the second bloc 
// choose the correct bank if necessary
movf   Adresse_of_the_bloc,w
movwf FSR
Suivantx :
mowf INDF,W   // now W contains the data of blocx 
call write_eeprom;
incf Counter,f  // pointer adresse EEPROM
inc FSR,f        // pointer inside the bloc
decfsz N;f      // counter of data in the bloc
goto Suivantx
return

nota: this code is just a guide,.. not tested
you can see a real example but with an external EEPROM on my web page datalogger 16F628 in ASM ...
be carreful with bank assignement !!
and if you data are not in same bank, you will have to adjust
adresse by bank adjustment.
 

I have written the first 0x00 to 0x07 address, how can write per 8 bytes...0x08 to 0x10, 0x11 to 0x19 and so on untill 0xFF address ?

any ideas ?
thanks folks
 

hello,

if you change your mind at every post, it wil be difficult..
write to eeprom is one thing
but from where location you get the data is another thing.
what is the source of data ?
we know destination is Eeprom.
if destination is modulo 8, it's more easy to write into eeprom..
but depend of source adresses organisation of your data.
explain more..
 

here's the code, I managed to write 0x00 to 0x07, but haven't got idea on writing the next address 0x08 to 0x10 and so on until 0xFF
Please have a look and tell me your idea,
thanks in advance
Code:
read_eeprom_transmit
		;wait for 200ms before sending datas, tested on 300ms more stable
            movf	LEDTimer,w		;for every 200 milliseconds, it sets on initialization
    	    btfss 	STATUS,Z		;check the counter if it's already zero
		    return	
        ;test with 200 ms counter
			;DEBUG
            ;bsf		PORTB,POWERLED
			;DEBUG            
    ;==========COMMAND HEADER==========
			call	initPCbuffer
			movlw	0x0F			;send data 0x0F into the buffer
			call	addPCbuffer
			movlw	0x55			;send data 0x55 into the buffer
			call	addPCbuffer
    ;==========COMMAND HEADER==========
	;==========READ AND TRANSMIT DATA 8 BYTES BEGIN HERE==============
    		
		movlw .0
		movwf Addr_Counter

loop_rd
		movf	Addr_Counter,W	
		movwf	nTheEEAddress		;set the address equal to Addr_Counter
		call	eeRead				;read data from the address from eeprom
		
		call    addPCbuffer			;put data on buffer before transmitting
		incf	Addr_Counter,f
       ;=================check if address counter is equal to 7 ( finish sending 8 bytes)
        movf	Addr_Counter,W	
		xorlw	0x08
		btfss	STATUS,Z

		goto	loop_rd	
	    
	;==========READ AND TRANSMIT DATA 8 BYTES END HERE==============	 

    ;==========COMMAND FOOTER==========
			
			movlw	0x0D			;send data 0x0F into the buffer
			call	addPCbuffer
			
    ;==========COMMAND FOOTER==========
			call	resetPCbuffer
            bsf		TX_Flag,TX2REMOTE	; this is flag usart module to start transmit  
    ;==========Transmit the buffer=====

   			;reload the timer begin here
			;DEBUGGING PURPOSE WITH 200MS, FOR SEEING THE NEXT STATE IS RUNNING ON HARDWARE
			movlw	.2							;test with 200 milliseconds 
    		BANKSEL LEDTimer					;Init the counter
			movwf 	LEDTimer					;to 2 ( 200milliseconds ) 
            ;DEBUGGING PURPOSE WITH 200MS, FOR SEEING THE NEXT STATE IS RUNNING ON HARDWARE
            ;reload the timer end here
		

    	   incf State,1
	return
;STATE 2 END
;===========================================================================================


;===========================================================================================
;STATE 3 BEGIN
;check_byte
;4.When 8 bytes are received from IR-TESTER check if all swapped bytes match with 8 bytes previously read from eeprom
;If you save all 8 bytes received overwrite previous data on eeprom with new data, toggle led ON-OFF-ON-OFF or OFF-ON-OFF-ON
;5.Repeat procedure 3-4 for the next address ie. address 0x08,0x10,0x18 and so on.
check_byte      
 	    ;wait for 200ms before checking 8 bytes data begin here
            movf	LEDTimer,w		;for every 200 milliseconds, it sets on initialization
    	    btfss 	STATUS,Z		;check the counter if it's already zero
		    return	
        ;test with 200 ms before checking 8 bytes data end here


		        ;=======================CHECK RECEIVED BYTE AND BLINK LED BEGIN HERE=========
				   BANKSEL	RX_Flag
					btfss 	RX_Flag,EOF_FROM_REMOTE				;check RX_Flag
			    	    goto 	no_rx_flag						;do this if RX_Flag is not set
						goto	rx_flag_set 						;do this if RX_Flag is set

						
						no_rx_flag
						  ;DEBUG
						 	;bsf LED_Standby,0
						  ;DEBUG 	
						  decf		State,1	
						  return	
        
						rx_flag_set
	
				;==========READ AND COMPARE DATA 8 BYTES AND WRITE RECEIVED DATA TO EEPROM==BEGIN HERE==============
								movlw .0
								movwf Addr_Counter
								call  resetPCbuffer			;reset the pointer of PCbuffer into the first byte
						read_compare
								
								;data from call readPCbuffer is stored in W register

								movf	Addr_Counter,W	
								movwf	nTheEEAddress		;set the address equal to Addr_Counter
								call	eeRead				;read data from the address from eeprom
								
								;SWAP READING RESULT FROM EEPROM
								swapf	nTheEEData,1

										
								;READ FROM BUFFER
								call 	readPCbuffer			;call readPCbuffer read each byte received in PCbuffer, 	
								;READ FROM BUFFER
								;store data from buffer to Swap_data
								movwf 	Swap_data
									
																
								;COMPARE BETWEEN nTheEEData with W register ( from PCbuffer)
								xorwf	nTheEEData
								
								;Check the comparison match with status register, is it zero ? zero means match
								btfss	STATUS,Z
								goto	invalid_byte
								goto	valid_byte
	
							invalid_byte
								
								;resend the bytes again
								decf	State,1
								return
							
							valid_byte
								;SAVE SWAPPED BYTE
								;eeprom address
								movf	Addr_Counter,W
								movwf 	nTheEEAddress	
								;eeprom data
								;movwf 	Swap_data	
								movf	Swap_data,W
								movwf 	nTheEEData

								call  	eeWrite						
								;SAVE SWAPPED BYTE	

								incf	Addr_Counter,f
						       ;=================check if address counter is equal to 7 ( finish sending 8 bytes)
						        
								
                                
								movf	Addr_Counter,W
								xorlw	0x08
								btfss	STATUS,Z
								goto	read_compare
								;BLINK LED ON-OFF-ON-OFF
								
								
								bsf		LED_Flag,0
							
								
								
		        ;==========READ AND COMPARE DATA 8 BYTES AND WRITE RECEIVED DATA TO EEPROM==BEGIN HERE==============

		;reload the timer begin here 										
			;DEBUGGING PURPOSE WITH 200MS, FOR SEEING THE NEXT STATE IS RUNNING ON HARDWARE
			movlw	.2							;test with 200 milliseconds 
    		BANKSEL LEDTimer					;Init the counter
			movwf 	LEDTimer					;to 2 ( 200milliseconds ) 
            ;DEBUGGING PURPOSE WITH 200MS, FOR SEEING THE NEXT STATE IS RUNNING ON HARDWARE
        ;reload the timer end here

            
		   incf		State,1	
		   
	return
;STATE 3 END
;=======================================================================================================

;Repeat procedure 3-4 for the next address ie. address 0x08,0x10,0x18 and so on..
 

hello,

if i have a good understanding, your data from PC buffer must have an index value of 0 to 7
and you want to store up to 32 blocs of data into your EEPROM space
is it ?

for getting dta from PCbuffer you can use the same Adress_Counter but
you must mask the LSB of adresse bit a AND logical

Movf Adrees_Counter,W
Andlw 0x07
and use W as pointer of PCBuffer
so only cover 0 to 7 without modify the EEPROM pointer Adress_Counter



Code:
   ;=================check if address counter is equal to 7 ( finish sending 8 bytes)

		incf	Addr_Counter,f		// counter evoluate betwwen 0 to 7 inside each bloc of 8 bytes
		btfss Addr_Counter, 3  ; 		//test bit3 =8
		goto	read_compare

		movlw 0x8
		addwf Add_Counter,f		; reinit at next adresse modulo 8
		btfss	STATUS,Z		; if 248+8=256  =>0   because byte size	
		goto	read_compare
		
		;BLINK LED ON-OFF-ON-OFF
		bsf	LED_Flag,0
 

yes you're right I have 8 bytes and I want to write 32 blocks of 8 bytes.....

is that how I can do that ?
thanks
 

see the attached code in post #12...

allways mask Adress_Counter with a ANDLW 0x07 to get data from PCbuffer : so adress is limited to 0 to 7
use Adress_Counter without mask to put data in EEPROM
so adress of EEPROM will be 0..7 ..8...16 17..32 etc
so you will get 32 times the PCbuffer data 0 to 7 and store them in the 32 spaces of eeprom in sequence
at least when Adress_Counter =00 = FIN

show details on "call addPCbuffer"
show detail on "call resetPCbuffer"
it seems you use same Adress_Counter ?
if true, you need to use the mask when you treat the PCbuffer adress
and maybe code could be more simple !


Code:
;State3 
               ....
                movf Addr_Counter,w   ; adresse for EEPROM
                Andlw  0x07               ; Mask to keep only base adresse 0 to 7
                result in W 
                so use it for adressing data in PCBuffer  
                .....

;=================check if address counter is equal to 7 ( finish sending 8 bytes)

		incf	Addr_Counter,f	; Addr_Counter (masked) evolute betwwen 0 to 7 inside each bloc of 8 bytes for PCbuffer adress, not for eeprom adress
		btfss	STATUS,Z		; if 255+1 =>256 =>0   because byte size for aAddr_counter	
		goto	read_compare
		
		;BLINK LED ON-OFF-ON-OFF
		bsf	LED_Flag,0
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…