Before starting to write a program, there are a number of things you need to know about laying it out.
Let’s start:
Anything you write on the page is interpreted by an ASSEMBLER. The assembler will convert anything it understands to MACHINE CODE. Any comments you write on the page are placed after the ”;” symbol.
A program is written in a set of columns. Anything in the first column is called a LABEL. If you leave more than 2 spaces, the next item is interpreted as an INSTRUCTION and the next column contains your comments ( ”;” is needed before any comments).
Start by giving a name to the program, and revision number plus date.
the ;************************************
simply creates a separator.
The next line identifies the type of microcontroller.
#include <p12f629.inc>
The assembler will need to have this file in the same directory as the assembler program so it can identify some of the words you have used in your program.
See: p12f629.inc
The next line is the configuration code. It tells the assembler if you want the Code Protection ON or OFF, and other things such as Watchdog Timer, and Internal 4MHz RC Oscillator. The configuration line starts with double underbar ”__”
One of the first things you will need to do is “list” or “name” or “equate” the files. This is the process of matching each file to a number, so the compiler can compile your program.
The PIC12F629 has 64 general purpose registers or files, starting at 20h (this is two-oh-hex) and is actually 32 files from the start: (1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10h,11h,12h,13h,14h,15h,16h,17h,18h,1h,1A,1B,1C,1D,1E,1F)
20h.
The 64 files are:
20h,21h,22h,23h,24h,25h,26h,27h,28h,29h,2Ah,2Bh,2Ch,2Dh,2Eh,2Fh,30h,31h,32h,33h,34h
35h,36h,37h,38h,39h,40h,41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,4Fh,
50h,51h,52h,53h,54h,55h,56h,57h,58h,59h,5Ah,5Bh,5Ch,5Dh,5Eh,5Fh.
These can be used to store values during the running of the program.
For instance, file 20h can be one of the files in the delay routine. We can call it delay1.
The next file can be delay2.
The next file is part of a tone routine, we will call it tone1
The next file is tone2.
These files are called “Variables” and are placed at the beginning of the program.
Each name such as delay1 has to be assigned to a file.
For instance, delay1 will be file 20h
delay2 will be file 21h etc.
This process is called “equates.” You are equating a name to a file.
;********************************************************************** ;Equates ;********************************************************************** delay1 equ 20h delay2 equ 21h tone1 equ 22h tone2 equ 23h
Instead of writing the word “equ” for each file, there is a short-cut:
It is called “CBLOCK” - for “naming a block for the named constants.”
The first line of the short-cut is: cblock and then a number that refers to the beginning of the files for the block. The number: 0x20 is the same as saying 20h. The following cblock is the same as the above.
The short-cut ends: “endc”
********************************************************************** ;Variables ;********************************************************************** cblock 0x20 ;20h is the first file of the General Purpose Registers delay1 delay2 tone1 tone2 endc
Another method of defining our files allows 2 or more files with the same name. For instance, the following allows 3 flag files. These are identified as “flags,” “flags+1,” “flags+2,” in your program. rand is identified as “rand” and “rand+1” in your program. You can also identify similar names for files on the same line, such as: temp1, temp2. In the following, 13 files have been identified and will be given the file numbers: 20h, 21h, 22h, 23h, 24h, 25h, 26h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch. To give a name such as “flags” more than one file, it is written flags:3 or flags:4 etc. It can also be written flags1, flags2, flags3, etc.
;********************************************************************** ;File Register usage ;********************************************************************** cblock 0x20 count ; counter flags:3 ; various flags rand:2 ; random number sensor ; sensor reading servo1, servo2 ; servo positions speed1, speed2 ; motor speeds temp1, temp2 ; timers endc
The next statement is called START. It is the beginning of the program.
The program starts with the statement ORG 000 or ORG 0x000. Or you can make the ORIGIN of your program 0x004 or 0x34.
This tells the assemble to put the first instruction in the program at location 000 in the program memory, or at location 4 or at location 34hex. This is called a DIRECTIVE and is information for the assembler. The first instruction in our example is “goto SetUp” The sub-routine at SetUp, sets the port bits as IN or OUT. The port is actually a file and has the name GPIO (for General Purpose In Out) and is file 05. All files have 8 bits but only the lowest 6 bits of file 05 are used. These are called GPIO,0 GPIO,1 GPIO,2 GPIO,3 GPIO,4 GPIO,5
These can be called “lines” and any or all of them can be configured as input, but only GPIO,0 GPIO,1 GPIO,2 GPIO,4 GPIO,5 can be used at output as GPIO,3 (GP3) (pin 4) is an INPUT-ONLY pin. To get a pin to “work,” two things must be done. Firstly the micro must be told if the pin is to be an input or output and them it must be made HIGH or LOW if it is an output pin. Any pin can be changed at any time during the running of a program but it is normal to set up the pins in Set-Up if they are not going to be altered. We discuss setting up the “lines” a little further down the article.
Set-Up is placed at the 7th program location. There is a reason for this. Location 04 is where the microcontroller will return when it is “interrupted.” For instance, it may be asleep, and is waiting for one of the inputs to change state. The microcontroller can be programmed to go to location 04 after an interrupt and the instructions at 04 will be carried out. We will leave three lines for three instructions, at 04, 05, 06. Location 07 is now available for your program.
At the end of SetUp, the microcontroller goes to Main.
Main is always located at the end of your program and all the subroutines are placed before Main, in alphabetical order. This allows you to easily find each sub-routine.
Any tables are placed before the sub-routines.
Here is how the program is laid out:
;********************************************************************** ; SPINNING SIGN Colin Mitchell rev 2 19-9-2007 ;********************************************************************** list p=12f629 #include <p12f629.inc> ; Set configuration register for: ; Code protection off ; Code protection DATA off ; Brown-out detect off ; MCLR disabled (use pins for InOut) ; Watch Dog timer disabled ; Power on reset delay enabled ; Enable Internal Clock Osc, (all pins for InOut) ; __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT ;********************************************************************** ;Variables ;********************************************************************** cblock 0x20 ;20h is the first file of the General Purpose Registers delay1 delay2 tone1 tone2 endc ;********************************************************************** ;Start ;********************************************************************** ORG 0x000 ; processor reset vector goto SetUp ; go to "setting up the port as In-Out etc" ORG 0x004 nop ; processor goes here after interrupt nop ; nop = no operation = 1 cycle nop SetUp instruction goes here instruction goes here goto Main ;********************************************************************** ;Tables ;*********************************************************************** ;********************************************************************** ;Sub-routines ;*********************************************************************** Main instruction goes here instruction goes here end
The “lines” are the input/out pins or “lines.”
These are called GPIO,0 GPIO,1 GPIO,2 GPIO,3 GPIO,4 GPIO,5
Any or all of them can be configured as input, but only GPIO,0 GPIO,1 GPIO,2 GPIO,4 GPIO,5 can be used at output as GPIO,3 (GP3) (pin 4) is an INPUT-ONLY pin.
The first thing to do is work out which pins are needed to be input and output. An input pin will be given the value ”1” for Input and ”0” for output. Two instructions are needed, are are highlighted:
bsf STATUS,rp0 **movlw b'00110111' movwf TRISIO** bcf status,rp0
These instructions must be placed between two instructions: bsf STATUS,rp0 and
bcf status,rp0 so your instructions are placed in the chip at a special location. These instructions are placed in a file (or register) called the TRISIO file.
The movlw b’00110111’ instruction is a binary number that directly represents each line you want to make input or output. The chip has only 6 lines so the instruction is really:
movlw b’xx110111’ as the two highest bits do not have a corresponding line. They can be 0 or 1 as they have no effect.
The lowest line is called “line 0” or “bit 0” or “GPIO,0” and to make it an input we place a ‘1’ as follows: b’xx - - - - - 1’ To make it an output: b’xx - - - - - 0’ We have already said GPIO,3 is INPUT-ONLY so the instruction starts: b’xx - - 1 - - -’ Once you have worked out if each line is to be input or output, the next decision is to make an output line HIGH or LOW.
(If you make an input line high or low, it does not have any effect on the line. It will only function at detecting the voltage applied to it from the outside world.)
To make an output line HIGH, one or two instructions are needed, depending how it is done.
To make any or all the lines HIGH, this can be done with two instructions. This is called “Byte Setting” as the whole byte is acted on in a single operation:
movlw b'00110111' movwf GPIO
If you want to make a line HIGH, you can use “Bit Setting:”
bsf GPIO,0
You cannot set more than one bit at a time, the micro does not like the following:
bsf GPIO,0 ;This makes the lowest line go HIGH
bsf GPIO,2
To set more than one line at a time, read: The In/Out Port.
;blink12F629.asm ;This program will blink a LED connected to pin 7 ;17-9-2007 list p=12F629 ;microcontroller identity ; 0x033 or 33h = hex value include "p12f629.inc" __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;********************************************************************** ;Variables ;************************************************************************* equ 20h ;this is the first available file equ 21h equ 22h equ 23h equ 24h equ 25h fileA equ 26h ;delay file A fileB equ 27h ;delay file B fileC equ 28h ;delay file C ; bits on GPIO pin7 equ 0 ;GP0 output to LED pin6 equ 1 ;GP1 pin5 equ 2 ;GP2 pin4 equ 3 ;GP3 pin3 equ 4 ;GP4 pin2 equ 5 ;GP5 Start org 0x0000 ;program starts at location 000 nop ;"org" = tells the assembler to start at this address. nop nop nop ;NOPs to get past interrupt address nop nop nop SetUp bsf STATUS,rp0 ;Bank 1 movlw b'10000110' ;Turn off T0CKI, prescaler for TMR0 = 1:128 movwf OPTION_REG movlw b'00110111' ;Set GP0 (pin 7) as output movwf TRISIO movlw 0x07 ;turn comparator off movwf CMCON ; comparator off =111 ;calibrating the internal oscillator call 0x3ff ;get the calibration value movwf OSCCAL ;calibrate oscillator bcf status,rp0 ;bank 0 clrf GPIO ;Clear GPIO of junk. This is file 05. goto Main Del movlw 40h ;Delay 0.5 sec movwf fileC DelX decfsz fileA,1 ; ,1 denotes the result of the decrement goto DelX ; is placed in the file decfsz fileB,1 goto DelX decfsz fileC,1 goto DelX retlw 00 Main bsf GPIO,pin7 ;turn on LED call Del bcf GPIO,pin7 ;turn off LED call Del goto Main ;OSCCAL calibration value org 0x3ff retlw 0x20 END
The template above consists of 6 different areas:
The first area contains the CONFIGURATION values.
The second area contains the “equates” or “variables.”
The third area contains the SET UP instructions
The fourth area contains all the sub-routines. These are placed in alphabetical order, so you can easily find them when the program gets lengthy.
The fifth area contains the MAIN routine.
The last area sets the calibration value for the oscillator and the “end” instruction.
The micro will commence at location 000 and execute the Set Up instructions.
It will then go to Main.
In “Main” it will find instructions to “call” sub-routines and return. In this way it will constantly loop “Main” and use sub-routines as required.
If you keep to this form of layout, you will be able to follow programs written by others and be able to come back to your own programs and easily modify them.
There are two ways to write a Delay Routine (and other routines). The program above uses instructions found in List of Instructions for PIC12F629. The following Delay Routine uses ”$+2” to advance the micro down the program:
Del movlw 40h ;Delay 0.5 sec movwf fileC DelX decfsz fileA,1 ; ,1 denotes the result of the decrement goto DelX ; is placed in the file decfsz fileB,1 goto DelX decfsz fileC,1 goto DelX retlw 00 Del movlw 40h movwf fileC DelX decfsz fileA,1 goto $+2 $+2 sends the micro to: goto $+2 below decfsz fileB,1 goto $+2 $+2 sends the micro to: goto DelX decfsz fileC,1 goto DelX retlw 00
The Delay Routine above can be written with only one Label.
;Delay 0.5 sec Del movlw 40h movwf fileC decfsz fileA,1 goto $+2 $+2 sends the micro to: goto $+2 below decfsz fileB,1 goto $+2 $+2 sends the micro to: goto goto $-5 decfsz fileC,1 goto $-5 $-5 sends the micro to: decfsz fileA,1 retlw 00
Creating 4 micro-second delay:
;Delay 4 micro-seconds nop ;1 uS nop ;1 uS nop ;1 uS nop ;1 uS ----------------------- goto $+1 ;2 uS, $+1 sends the micro to the next instruction goto $+1 ;2 uS, $+1 sends the micro to the next instruction
To put the micro to sleep, a number of things must be done. This routine allows the micro to go to SLEEP when it comes to the SLEEP instruction. The micro wakes up from sleep when it detects a change on GPIO,5 (pin 2). Pin 2 must have a pull-up resistor for the following program to work and a push-switch to create the change on the pin. The pull-up resistor can be external (about 47k) and a push switch to take the pin low to take the micro out of SLEEP.
Or, to turn on the weak internal 47k pull-up resistor, place the following instructions in SetUp:
bsf STATUS,RP0 ; Sel Bank 1 bcf OPTION_REG,NOT_GPPU ; enable weak pull-up bsf WPU, 5 ; enable wpu on GPIO 5 only bsf IOC, 5 ; enable Int-On-Change GPIO 5 bcf STATUS,RP0 ; Sel Bank 0
In a sub-routine, place the following instruction:
goto sleep ; goto sleep.
The following sub-routine is suitable to create a sleep condition:
Sleep movf GPIO,W ; Read GPIO clears Int-On-Change flag. Must read ; into W not back to F as it reads port not the output ; latch which may result in output data being ; inadvertently altered. bcf INTCON,GPIF bsf STATUS,RP0 ; Sel bank 1 movlw 0xFF ; Setup W for TRISIO all input movwf TRISIO ; Write to TRISIO. Reduce power in sleep mode sleep ; Go to sleep nop ; movlw b'11101000' ; Wake from sleep and set movwf TRISIO ; TRISIO for input and output for **your** project bcf STATUS,RP0 ; Sel Bank 0 movf GPIO,W ; Read GPIO register bcf INTCON,GPIF ; and clear GPIF flag in interrupt register
Suppose you want to create an instruction the assemble does not understand, such as:
movlf 0A0h,sensor
In the instruction above you want to move the value A0h into file 26h (by referring to the list above:
count ; counter flags:3 ; various flags rand:2 ; random number sensor ; sensor reading
count will be allotted file 20h, flags will be allotted file 21h, flags+1 will be give 22h, flags+2 will be give file 23h, rand will be 24h, rand+1 will be 25h and sensor will be 26h.
But the assembler does not have an instruction of the above. It requires two instructions:
movlw 0A0h movwf sensor
Creating your own instructions for the assembler is called a “macro.”
To tell the assembler how to handle an instruction in which the value 0Ah (called a “constant” or “literal”) is to be moved to file 26h (the “sensor” file), a macro can be written to allow any “literal” to be written to any “file:”
movlf macro n,f ; move literal to file movlw n movwf f endm
When the assembler sees the instruction: movlf it looks to see if a macro has been produced. The instructions in the macro are then added to the program (called the “source”).
The macro is written with a label in the first column. The word “macro” is then written to tell the assembler the next instructions are “macro instructions.” On the same line we write the parameters that will be used in the macro. The macro ends with “endm.”
If you will want to burn a chip and make sure it works in a test circuit. To help you, we have written a simple program, called “blink12F629.asm”. This will blink a LED on Pin 7.
The circuit for this is:
Click .asm and .hex for blink12F629.asm files.
;blink12F629.asm ;This program will blink a LED connected to pin 7 ;17-12-2005 list p=12F629 ;microcontroller identity ; 0x033 or 33h = hex value include "p12f629.inc" __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;Internal osc. ; globals equ 20h ;this is the first available file equ 21h equ 22h equ 23h equ 24h equ 25h fileA equ 26h ;delay file A fileB equ 27h ;delay file B fileC equ 28h ;delay file C ; bits on GPIO pin7 equ 0 ;GP0 output to LED pin6 equ 1 ;GP1 pin5 equ 2 ;GP2 pin4 equ 3 ;GP3 pin3 equ 4 ;GP4 pin2 equ 5 ;GP5 Start org 0x0000 ;program starts at location 000 nop ;"org" = tells the assembler to go to this address. nop nop nop ;NOPs to get past interrupt address nop nop nop SetUp bsf STATUS,rp0 ;Bank 1 movlw b'10000110' ;Turn off T0CKI, prescaler for TMR0 = 1:128 movwf OPTION_REG movlw b'00110111' ;Set GP0 (pin 7) as output movwf TRISIO movlw 0x07 ;turn comparator off movwf CMCON ; comparator off =111 ;calibrating the internal oscillator call 0x3ff ;get the calibration value movwf OSCCAL ;calibrate oscillator bcf status,rp0 ;bank 0 clrf GPIO ;Clear GPIO of junk. This is file 05. goto Main Del movlw 40h ;Delay 0.5 sec movwf fileC DelX decfsz fileA,1 ; ,1 denotes the result of the decrement goto DelX ; is placed in the file decfsz fileB,1 goto DelX decfsz fileC,1 goto DelX retlw 00 Main bsf GPIO,pin7 call Del ;turn on LED bcf GPIO,pin7 call Del ;turn off LED goto Main org 0x3ff ;OSCCAL calibration value retlw 0x20 END
We are now ready to start writing a program.
You will need the INSTRUCTION SET for the PIC12F629
Below is the blank12F629.asm template:
The instructions for your program are arranged in three columns.
The first column contains the “labels.” They identify the address of the first instruction for a sub-routine.
The second column contains the “instructions” - called the mnemonics. The “half-computer” “half-English” instructions that both computer and micro understands.
The third column contains the “comments.” It must have a ”;” before each line so that they are not assembled - so they don’t appear in the final .hex file!
Click .asm and .hex for “blank12F629.asm” files. The .asm file is used by your compiler (MPASM) to produce a .hex file for your ICProg burner program.
;blank12F629.asmm ;Template for PIC12F629 microcontroller 17-12-2005 ;CONFIG defines internal oscillator, code-protection OFF, pin 4 is GP3, ; watchdog timer OFF. list p=12F629 ;microcontroller identity ; 0x033 or 33h = hex value include "p12f629.inc" __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;Internal osc. ; globals equ 20h ;this is the first available file equ 21h equ 22h equ 23h equ 24h equ 25h fileA equ 26h ;delay file A fileB equ 27h ;delay file B fileC equ 28h ;delay file C ; bits on GPIO pin7 equ 0 ;GP0 pin6 equ 1 ;GP1 pin5 equ 2 ;GP2 pin4 equ 3 ;GP3 pin3 equ 4 ;GP4 pin2 equ 5 ;GP5 ;*************************************************** ;* Start of program * ;*************************************************** Start org 0x0000 ;program starts at location 000 nop ;"org" = tells the assembler to go to this address. nop nop nop ;NOPs to get past reset vector address nop nop SetUp call 0x3ff ;get the calibration value bsf STATUS,rp0 ;Bank 1 movwf OSCCAL ;calibrate oscillator movlw b'10000110' ;Turn off T0CKI, prescaler for TMR0 = 1:128 movwf OPTION_REG movlw b'00001000' ;Set GP0's as output, GP3 = input. movwf TRISIO bcf status,rp0 ;bank 0 clrf GPIO ;Clear GPIO of junk goto Main Del_1 movlw 40h ;Delay_1 0.5sec movwf fileC DelX decfsz fileA,1 ; ,1 denotes the result of the decrement goto DelX ; is placed in the file decfsz fileB,1 goto DelX decfsz fileC,1 goto DelX retlw 00 Main your instruction goes here your instruction goes here your instruction goes here call Del_1 your instruction goes here your instruction goes here your instruction goes here goto Main ;OSCCAL calibration value org 0x3ff retlw 0x20 END
The first program you will burn will be “blink12F629.asm”
Use Notepad++ or VS Code on the left-side of the screen and load it with the blink12F629.asm file by sliding it into Notepad. It will then show in Notepad.
You can now make any changes to the program.
Save the result in a folder called PIC12F629Pgms (programs).
To burn blink12F629.asm into a PIC12F629, you will need to assemble the .asm file in MPASM to create a .hex file. To do this, place MPASM in a folder (or unzip MPASM.zip in the folder) and create a shortcut to desktop.
Click on MPASM on your desktop and it will open.
Locate blink12F629.asm in PIC12F629Pgms folder and load it into MPASM.
Use:
Radix: Default, Warning Level: Default, Hex Output: Default, Generated Files: Error File and List file, Do not tick: Case Sensitive, Macro Expansion: Default, Processor PIC12F629, Tab Size: 8, Tick: Save settings on exit.
Click: Assemble.
Your blink12F629.hex file will be put into the same folder.
To burn a PIC12F629, you will need the Multi Chip Programmer. Make sure the programmer is the latest version with 628 on the underside of the PCB.
Connect it to your computer via the serial cable supplied in the kit and the green LED will illuminate.
Install IC Prog.zip
Click on the folder on the top left-hand side and locate Expt-1.hex
Make sure you have selected PIC12F629 before loading the .hex file.
The configuration settings will be automatically set according to the configuration value supplied in the program - or you can change anything before burning the new program.
Fit a chip into the programmer and click on the “lightening” icon.
The programmer will now burn the program into the chip. The LEDs on the Multi-Chip Programmer will show the action taking place.
When the chip is “burnt,” place it in the socket on the project and the LED will flash.
This might seem a lot of work to create a simple effect, but the same amount of work will produce a compete project - it’s just the size of the program will be different.
Writing a program consists of creating small routines called sub-routines.
The basic layout of a program has already been shown above.
It is now a matter of creating subroutines that perform a function.
When these are executed at high-speed, the program performs a task.
The most interesting subroutines carry out an operation that appears to have “intelligence.”
These type of subroutines can be found in a game, where the player is pitted against the computer.
The basics behind an “intelligent” sub-routine is simple. You simply provide an answer for ALL the possible combinations.
When this sub-routine is executed in the program, it creates the illusion of intelligence.
This type of sub-routine is interesting and challenging to create.
There are a number of very common games played with matches and marbles or markers, that can be converted to a program.
Once you master the technique of writing a sub-routine that solves a problem, all other routines will be easy to create.
Before we start, the PIC12F629 has only 5 output lines and this prevents it from directly driving a 7-digit display. We have designed a project called 2-Digit Counter that shows how to expand the outputs to drive the displays.
One of the things you may want to do is access a list of values from a table.
A number of files can be addressed by a sub-routine and the information can be moved into each file or read from each file. The files must be a group.
Suppose we have 8 files and need to read the contents and output it to a display.
The files are: 21h, 22h, 23h, 24h, 25h, 26h, 27h, and 28h.
There are two special files that allow a sub-routine to be created to look at the 8 files and read the contents.
They are: INDF and FSR
The INDF file is not a real file. It is like a Robot Arm. It reaches down the list of files and picks up the contents or delivers the contents of a file to the programmer. The file it reaches is determined by the value in FSR.
FSR is loaded with the address of the file you wish to read or write.
This arrangement has an advantage. By loading FSR with a value, you can reach a file and by incrementing FSR, you can reach the next file etc.
If you load a value into INDF, you will actually load the value into the file pointed to by FSR.
If you read INDF, you will actually read the contents of the file pointed to by FSR.
You can consecutively read 8, 10 or 20 files or clear 20 files or load into 20 or more files with a simple looping sub-routine. It’s a very powerful feature.
The following instructions put a value of 8Fh into file 21h.
MOVLW 21h ;Load W with start of 8 files MOVWF 04 ;Load 21h into FSR MOVLW 8Fh ;Put 8F into W MOVWF 00 ;Put 8Fh into file 21h
The animation below shows how the information passes to the files:
Using INDF and FSR
The following instructions put a value of 8Fh into files 21h, 22h, 23h, 24h, 25h, 26h, 27h and 28h.
MOVLW 08 ;8 loops of the program MOVWF 20h ;File 20h is the decrementing file MOVLW 21h ;Load W with start of 8 files MOVWF 04 ;Load 21h into FSR MOVLW 8Fh ;Put 8F into W Loop1 MOVWF 00 ;Put 8Fh into file 21h INCF 04 ;Increment FSR to make INDF go to next file DECFSZ 20h GOTO Loop1 RETLW 00
The following instructions read files 21h, 22h and 23h, and outputs to GPIO.
MOVLW 03 ;3 loops of the program MOVWF 20h ;File 20h is the decrementing file MOVLW 21h ;Load W with start of 3 files MOVWF 04 ;Load 21h into FSR Loop1 MOVF 00,0 ;Copy file 21h (or next file) into W MOVWF GPIO ;Move W to output GPIO CALL Delay ;Show value on set of 3 LEDs INCF 04 ;Increment FSR to make INDF go to next file DECFSZ 20h GOTO Loop1 RETLW 00
Quick Links
Legal Stuff
Social Media