Continue to Site

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.

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
Most Helpful 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
Most Helpful 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
Most Helpful 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
Most Helpful 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.

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 :D

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
Buff:Buff_Size ;240 character receive buffer
endc
 

Latest threads

New Articles From Microcontroller Tips

Top