Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F887, Learning FSR & Index/Indirect Addressing

Not open for further replies.


New Member
Right now I'm taking a college class, but the book we have doesn't go into FSR too well, and the instructor's notes are vague at best. Having nothing to work off of, I was hoping maybe some of the bright minds here could get me in the know. I get the idea but I'm sure I have some things to work on.

I have three different files I'm playing around with, using MPLAB v7.50 as my assembler, and PICFLASH to write .HEX files to the board.

First Program:
My objective here is to clear locations 120h to 129h. I've included a link to a .txt file you can view in your browser, and an attached .asm you can download called "firstprogram.asm." I think I have this one down.


Second Program:
In this program, I'm filling A0h through A9h with the value of FFh. I probably should assign FFh to A0h instead of WALK (variable) though. Again, I've included a .txt link for quick viewing pleasure, and an have included a "secondprogram.asm" file for good measure.


Thrid Program:
I haven't tested this yet because I'm not sure how to go about it. I would like to start out by having equate equations load A0h through A9h with values of 0 through 9 respectively. Then, I want to move those values from A0h through A9h to 120h through 129h.

I appreciate all the feedback in advance. Other than this site and some of the examples I've found, are there any other sites dedicated to learning the code? I read through the stickies, but I haven't found anything yet of incredible help.


  • firstprogram.asm
    2.4 KB · Views: 376
  • secondprogram.asm
    2.6 KB · Views: 243


Well-Known Member

The FSRs are not detailed well for a beginner, you might find some help here at section 6.3.4 https://ww1.microchip.com/downloads/en/devicedoc/31006a.pdf

Your two code examples do not look too far off the mark, your third test would be easier if your chip had more than one FSR as some other chips do.
However you can get round that by using a temp register to save its values to.

Would also suggest you update to Mplab v8.36, and if you have not done already start to use the Debugger, MPLAB Sim_ulator function to run your code on - here you can set up Watch Windows to see your SFR like the FSR being incrementeted as you Single Step through the code.
It also allows you to View your File Registers as they update.


New Member
Thanks for the reply and the link!

I already use the debugger and the mplab simulator. I can do a little bit with timing functions and know how to use the watch window and timer. But I did not know about watching the file registers. I'll have to check that out, because that would be extremely helpful to know how I'm working with FSR.

I'll update to the latest version of mplab. I decided to use 7.5 since that's what my professor uses for I assume older class videos.
Last edited:


Well-Known Member
Most Helpful Member
The FSR register is only 8 bits wide and so loading it with 0x120 will actually load it with 0x20. The 9th bit of the FSR register is contained in the STATUS register and is called the Indirect Register Pointer. To access 0x120 you set FSR to 0x20 and do bsf STATUS,IRP to set the 9th bit.

In the second program you are confusing the address of a variable and what it contains.

WALK is located at address 0x9F and contains 0xff.

movf WALK will move WALK to WALK - w unchanged but Z flag set/cleared
movf WALK,w will move the contents of walk to W therefore W=0xff
movlw WALK will move the address of WALK to W therefore W=0x9f

Hope that helps.

Last edited:


New Member
That makes sense. So to clear the IRP status to zero, I could write:


So if I do something like this for my first program...

        selbank2	        ;switch to bank two
	movlw	0x20	;load w with first address
	movwf	FSR	;load File Select Register
	[COLOR="Red"]bsf	STATUS, IRP[/COLOR] ;Enable 9th Bit for Indirect Addressing
[COLOR="Blue"]loop[/COLOR]	clrf	INDF	;clear the Target Register
	incf	FSR	;point to next register
	movlw	0x2A	;check for last register
	xorwf	FSR,W	;compare to 1 past last register
	btfss	STATUS, Z ;keep looping if not there yet
	goto	loop	;[COLOR="Blue"]loop[/COLOR] to write again
	selbank0	;back to bank zero
        bcf     STATUS, IRP ;clear IRP
	movlw	0xFF	;load W with all ones
	movwf	PORTB	;light all portb LEDS when done
quit	goto	quit	;loop forever!

I don't have to loop the STATUS, IRP function since it remains set until I clear it correct?
Last edited:


New Member
Actually, for what I have set up, adding selbank does nothing (it makes it worse). I'm better off without it the more I play around with it. Thanks for the feedback!

Complete Huge Edit: I solved what I needed help on! Here's the base code for my main program (program 3 mentioned above). It moves the contents of 0xA0 through 0xA9 into 0x120 to 0x129. I believe this works!

	movlw	0xA0
	movwf	strfsr1

	movlw	0x20
	movwf	strfsr2

loop	movf	strfsr1, W
	movwf	FSR
	movf	INDF, W
	movwf	strINDF

	movf	strfsr2, W
	movwf	FSR
	movf	strINDF, W
	movwf	INDF

	incf	strfsr1, F
	incf	strfsr2, F
	movlw	0x2A
	xorwf	FSR, W
	btfss	STATUS, Z
	goto 	loop
quit	goto	quit

Going back to Program2, I have
start	selbank1
	movlw	0xA0	;get address 0xA0
	movwf	FSR	;point to 0xA0
loop	movlw	0xFF
	movwf	INDF	;write 0xFF to FSR
	incf	FSR	;increment FSR pointer
	movlw	0xAA
	xorwf	FSR, W	;check to see if we're done (has 0xFF been written to 0xA9?)
	btfss	STATUS, Z
	goto 	loop
quit	goto	quit

Oddly, when I loop through the first time, I write 0xFF to 0xA0. But when I go through the loop other times, sometimes after "movlw 0xFF" it unexplainable steps back up to START. Hmm... EDIT: Nevermind, "loop" was in wrong place. This works!

Thanks so much for the help everyone!
Last edited:
Not open for further replies.

EE World Online Articles