Continue to Site

# ASM - 16F1827 bulk clear GPR's with FSR

#### augustinetez

##### Active Member
Having a "Seniors Moment", could somebody please confirm I've got this right for the 16F1827 - clearing the GPR's without doing the clrf xxxx ad infinitum at the begining of the program:-

Code:
start
movlw    LOW 0x20  ; initialize pointer
movwf    FSR0L ; to RAM
movlw    HIGH 0x20 ; initialize pointer
movwf    FSR0H ; to RAM
next
clrf    INDF0 ; clear INDF register
incf    FSR0L  ; inc pointer
btfss    FSR0L,7  ; all done?
goto    next; no clear next
; yes continue

#### Diver300

##### Well-Known Member
That looks correct to me.

I assume that you want to clear everything between 0x0020 and 0x007F

If you are using the registers in banks 1 - 6 (higher banks don't have any general purpose registers) then you need to repeat with different starting values for FSR0L and FSR0H.
You cannot keep going beyond 0x7F because that will end up in bank 1 and it will start clearing the special function registers including FSR0L itself. For bank 1 you would need to start again with FSR0L = 0xA0

You should be able to run that code on the Microchip simulator. You can fill the registers with random data before running the simulation to check that it's all getting cleared.

#### jpanhalt

##### Well-Known Member
Agreed, that should work. Howvever the Enhanced mid-range chips have some new instructions. In this case, "movwi FSR0++" will auto increment.

Code:
start
movlw    LOW 0x20  ; initialize pointer
movwf    FSR0L ; to RAM
movlw    HIGH 0x20 ; initialize pointer
movwf    FSR0H ; to RAM
next
movwi   INDF0++
;    clrf    INDF0 ; clear INDF register
;    incf    FSR0L  ; inc pointer
btfss    FSR0L,7  ; all done?
goto    next; no clear next
; yes continue
Note, HIGH(0x20) = 0 . Also on all resets, FSRxH = 0, so you could replace those steps with clrw.

Last edited:

#### Diver300

##### Well-Known Member
I've just seen that you can clear the registers in the range 0x20 - 0x6F for all banks by using the linear memory model. All those registers are accessible using indirect address, in the range 0x2000 - 0x29AF

As there are only 6 1/2 banks of memory that are implemented, you wouldn't need to go all the way to 0x29AF.

The access registers, 0x70 - 0x7F, are not in the linear memory model and would have to be cleared separately.

#### Nigel Goodwin

##### Super Moderator
I've just seen that you can clear the registers in the range 0x20 - 0x6F for all banks by using the linear memory model.

Must admit, I originally moved to the 16F1827 (a good many years ago) specifically because of the linear memory option - it was for a GSM project for a friend (who I now work with), and I wanted to be able to receive an entire text message in a buffer, and process it after reception.

Just had a quick dig, and managed to find the original assembler code from 2011

Here's my routine for clearing the buffer, Buff_Size was obviously 240.

Clr_Buffer
banksel 0x00 ; ensure bank 0
movlw Buff_Size
movwf count ; set number of bytes to clear
movlw high Buff
movwf FSR0H ; set buffer address
movlw low Buff
movwf FSR0L
BuffLoop clrw
movwi FSR0++ ; clear each GPR in turn
decfsz count, f ; check if all cleared
bra BuffLoop
return

And buffer was here:

cblock 0x2050 ;receive buffer starting in bank1
endc

#### augustinetez

##### Active Member
Thanks Gentlemen.

Yes, I want to clear everything between 0x20 and 7F.

Getting near bed time so will run this through tomorrow to check it works,

Replies
4
Views
789
Replies
42
Views
12K
Replies
37
Views
2K
Replies
8
Views
941
Replies
0
Views
2K