Microcontroller

PIC Microcontroller Assembly – Fibonacci

PIC 8-bit Microcontroller Assembly

I’m currently working on a project that I need a basic micro-controller for. I’m exploring potential options, and have some PIC chips on hand that I’d like to make use of so I’m considering using a PIC12F629, by Microchip.com. I’ve found the Microchip documentation and community to be quite helpful in getting started. It’s as simple as:

  1. Download & install MP Lab X IDE: http://www.microchip.com/mplab/mplab-x-ide
  2. Download & install an XC compiler: http://www.microchip.com/mplab/compilers
  3. Peruse the PIC12F69 documentation: http://ww1.microchip.com/downloads/en/devicedoc/41190c.pdf
    • Read Page 9, 10 (Memory layout)
    • Read Page 21, 22 (I/O Pin config)
    • Read Page 71 (Instruction Set Summary)
    • Refer to Page 72 (Instruction Table)

I’m interested in understanding the lowest level operation of the chip, so I’ve started with writing assembly instead of C. Here is a short and simple implementation of a Fibonacci sequence generator. Since this is an 8-bit chip, the maximum number I’m able to represent is 255, but for convenience of detecting the end of the generator, I end on the 16th step, which also demonstrates the 8-bit overflow.

  1. ; PIC 12F629 Register Addresses
  2. #define INDF 0x00
  3. #define STATUS 0x03
  4. #define RP0 0x05 ; STATUS<RP0> bit selects the bank
  5. #define FSR 0x04
  6. #define GPIO 0x05 ; bank 0
  7. #define TRISIO 0x05 ; bank 1
  8. ; Global Variables
  9. #define TMP1 0x31
  10. #define TMP2 0x32
  11. #define FIB 0x20 ; fibonacci seq array
  12. RES_VECT CODE 0x0000 ; processor reset vector
  13. GOTO START ; go to beginning of program
  14. ; TODO ADD INTERRUPTS HERE IF USED
  15. MAIN_PROG CODE ; let linker place main program
  16. START
  17. bcf STATUS, RP0 ; select Bank 0
  18. ; Build the fibonacci sequence in a memory block
  19. movlw 0x20 ; start at 0x20
  20. movwf FSR ; set the indirect addressing address
  21. ; Initialize sequence with 0,1
  22. movlw 0x00 ; F_0
  23. movwf TMP1 ; store it in working var
  24. movwf INDF ; store it in memory block
  25. incf FSR ; increment the File Select Register
  26. movlw 0x01 ; F_1
  27. movwf TMP2 ; store it in working var
  28. movwf INDF ; store it in memory block
  29. incf FSR; ; increment the File Select Register
  30. ; Continue the sequence from F_2 on
  31. NEXT
  32. ; Add the two last numbers
  33. movf TMP1,0 ; W = TMP1
  34. addwf TMP2,0 ; W = W + TMP2
  35. movwf INDF ; store W in data block at FSR
  36. ; update TMP1 and TMP2.. .tmp1=tmp2, tmp2=W
  37. movf TMP2,0 ; W = TMP2
  38. movwf TMP1 ; TMP1 = W
  39. movf INDF,0 ; W = Value at FSR
  40. movwf TMP2 ; TMP2 = W
  41. incf FSR ; increment the File Select Register
  42. btfss FSR, 4 ; skip goto when bit 4 of FSR is 1, eg FSR = 0bx1xxxx
  43. goto NEXT
  44. END
; PIC 12F629 Register Addresses
#define INDF	0x00
#define STATUS	0x03
#define RP0	0x05	; STATUS<RP0> bit selects the bank
#define FSR	0x04
#define GPIO	0x05	; bank 0
#define TRISIO	0x05	; bank 1

; Global Variables
#define TMP1	0x31
#define TMP2	0x32
#define FIB	0x20	; fibonacci seq array
 
RES_VECT  CODE    0x0000            ; processor reset vector
    GOTO    START                   ; go to beginning of program

; TODO ADD INTERRUPTS HERE IF USED

MAIN_PROG CODE                      ; let linker place main program
 
 
START
    bcf	    STATUS, RP0		; select Bank 0
    
    ; Build the fibonacci sequence in a memory block
    movlw   0x20    ; start at 0x20
    movwf   FSR	    ; set the indirect addressing address
    
    ; Initialize sequence with 0,1
    movlw   0x00    ; F_0
    movwf   TMP1    ; store it in working var
    movwf   INDF    ; store it in memory block
    incf    FSR	    ; increment the File Select Register
    
    movlw   0x01    ; F_1
    movwf   TMP2    ; store it in working var
    movwf   INDF    ; store it in memory block
    incf    FSR;    ; increment the File Select Register
    
    ; Continue the sequence from F_2 on
NEXT
    ; Add the two last numbers
    movf    TMP1,0  ; W = TMP1
    addwf   TMP2,0  ; W = W + TMP2
    movwf   INDF    ; store W in data block at FSR
    
    ; update TMP1 and TMP2.. .tmp1=tmp2, tmp2=W
    movf    TMP2,0  ; W = TMP2
    movwf   TMP1    ; TMP1 = W
    movf    INDF,0  ; W = Value at FSR
    movwf   TMP2    ; TMP2 = W
    
    incf    FSR	    ; increment the File Select Register
    btfss   FSR, 4  ; skip goto when bit 4 of FSR is 1, eg FSR = 0bx1xxxx
    goto    NEXT

    END

Here is a screenshot of the memory management tool in the MP Lab IDE’s simiulator:

Fibonacci Sequence Generator Program Memory Map

Fibonacci Sequence Generator, simulation memory map

 

Surely there are easier, more efficient, and/or more compact ways of writing this generator, but this is my naïve first attempt.

Sunday, March 6th, 2016 Microcontroller, Projects 2 Comments
Psst.. There is no more.