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:
- Download & install MP Lab X IDE: http://www.microchip.com/mplab/mplab-x-ide
- Download & install an XC compiler: http://www.microchip.com/mplab/compilers
- 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.
; 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:
Surely there are easier, more efficient, and/or more compact ways of writing this generator, but this is my naïve first attempt.