movlp" and "
gotto", in the following example, are recognized by the PIC16F887 microcontroller as an error since they are not correctly written.
MAXIMUM EQU H’25’This means that a memory location at address 25 (hex.) is assigned the name "MAXIMUM". Every appearance of the label "MAXIMUM" in the program will be interpreted by the assembler as the address 25 (MAXIMUM = H’25’). Symbols may be defined this way only once in a program. That this directive is mostly used at the beginning of the program.
ORG 0x100 START ... ... ... ORG 0x1000 TABLE ... ...This program starts at location 0x100. The table containing data is to be stored at location 1024 (1000h).
... END ;End of program
... #include <p16f887.inc>
CBLOCK 0x20 START ; address 0x20 RELE ; address 0x21 STOP ; address 0x22 LEFT ; address 0x23 RIGHT ; address 0x24 ENDC ...
IF (VERSION>3) CALL Table_2 CALL ENDIF ...If the program is released after the version 3 (statement is right) then subroutines "Table 2" and "Extension" are executed. If the statement in parentheses is wrong (VERSION<3), two instructions calling subroutines are ignored and will not be compiled therefore. Example 2: If the value of symbol "Model" is equal to one then first two instructions after directive IF are compiled as well as instructions after directive ENDIF (all instructions between ELSE and ENDIF are ignored). Otherwise, if Model=0 then instructions between IF and ELSE are ignored, whereas instructions after directive ELSE are compiled.
IF (Model) MOVFW BUFFER MOVWF MAXIMUM ELSE MOVFW BUFFER1 MOVWF MAXIMUM ENDIF ...
... BANKSEL TRISB CLRF TRISB MOVLW B’01001101’ BANKSEL PORTB MOVWF PORTB ...
_CONFIG _CP_OFF&_WDT_OFF&PWRTE_ON&XT_OSCWhen all necessary elements are defined, the process of program writing can start. First and foremost, it is necessary to specify the address from which the microcontroller starts when the power goes on (
org 0x00) as well as the address from which the program proceeds with execution if an interrupt occurs (
org 0x04). Since this program is very simple, it is enough to use command "
goto Main" in order to direct the microcontroller to the beginning of the program. The next command selects memory bank 1 in order to enable access to the TRISB register to configure port B as output (
banksel TRISB). The main program ends by selecting memory bank 0 and setting all port B pins to logic one (1)(
movwf PORTB). It is necessary to create a loop to keep program from "getting lost" in case an error occurs. For this purpose, there is an endless loop executed all the time while the microcontroller is switched on. "
end" is required at the end of every program to inform the assembler that there are no more commands to be compiled.
macro_name macro arg1, arg2... ... sequence of instructions ... endmThe following example shows four macros. The first two macros select banks, the third one enables interrupt, whereas the fourth one disables interrupt.
bank0 macro ; Macro bank0 bcf STATUS, RP0 ; Reset RP0 bit bcf STATUS, RP1 ; Reset RP1 bit endm ; End of macro bank1 macro ; Macro bank1 bsf STATUS, RP0 ; Set RP0 bit bcf STATUS, RP1 ; Reset RP1 bit endm ; End of macro enableint macro ; Global interrupt enable bsf INTCON,7 ; Set bit endm ; End of macro disableint macro ; Global interrupt disable bcf INTCON,7 ; Reset bit endm ; End of macroMacros defined in this way are saved in a particular data file with extension INC which stands for INCLUDE data file. As seen, these four macros do not have arguments. However, macros may include arguments if needed. The following example shows macros with arguments. Pin is configured as input if the corresponding bit of the TRIS register is set to logic one (bank1). Otherwise, it is configured as output.
input macro arg1,arg2 ;Macro Input bank1 ;Bank containing TRIS registers bsf arg1,arg2 ;Set the specified bit (1=Input) bank0 ;Macro for bank 0 selection endm ;End of macro output macro arg1,arg2 ;Macro Output bank1 ;Bank containing TRIS registers bcf arg1,arg2 ;Clear the specified bit (0=Output) bank0 ;Macro for bank 0 selection endm ;End of macroMacro with arguments may be called in the following way:
... output TRISB,7 ;Pin RB7 is configured as output ...When calling this macro, the first specified argument TRISB is replaced by the first argument arg1 in macro definition. Similarly, number 7 is replaced by the argument arg2, and the following code is generated:
... bsf STATUS, RP0 ;Set RP0 bit = BANK1 bcf STATUS, RP1 ;Reset RP0 bit = BANK1 bcf TRISB,7 ;Configure RB7 as output bcf STATUS,RP0 ;Clear RP0 bit = BANK0 bcf STATUS,RP1 ;Clear RP1 bit = BANK0 ...It is clear at first sight that the program becomes more legible and flexible by using macros. The main disadvantage of macro is that it occupies a lot of memory space because every macro name in a program is replaced by its predefined code. Owing to the fact that programs often use macro, everything is more complicated if it is long.
callc macro label ;Macro callc local Exit ;Define local Label within macro bnc Exit ;If C=0 jump to Exit call label ;If C=1 call subroutine at address Label(out of macro) Exit ;Local Label within macro endm ;End of macroIn the event that a macro has labels, they must be defined as local ones by using directive local. The given example contains macro which calls a subroutine (
call labelin this case) if the Carry bit of the STATUS register is set. Otherwise, the first following instruction is executed.
; Program to add two 16-bit numbers ; Version: 1.0 Date: April 25, 2007 MCU:PIC16F887 PROCESSOR 16f887 ; Defining processor #include "p16f887.inc" ; Microchip INC database __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC Cblock 0x20 ; Beginning of RAM ARG1H ; Argument 1 higher byte ARG1L ; Argument 1 lower byte ARG2H ; Argument 2 higher byte ARG2L ; Argument 2 lower byte RESH ; Result higher byte RESL ; Result lower byte endc ; End of variables ORG 0x00 ; Reset vector goto Start Start ; Write values to variables movlw 0x01 ; ARG1=0x0104 movwf ARG1H movlw 0x04 movwf ARG1L movlw 0x07 ; ARG2=0x0705 movwf ARG2H movlw 0x05 movwf ARG2L Main ; Main program call Add16 ; Call subroutine Add16 Loop goto Loop ; Remain here Add16 ; Subroutine to add two 16-bit numbers clrf RESH ; RESH=0 movf ARG1L,w ; w=ARG1L addwf ARG2L,w ; w=w+ARG2L movwf RESL ; RESL=w btfsc STATUS,C ; Is the result greater than 255? incf RESH,f ; If greater, increment RESH by one movf ARG1H,w ; w=ARG1H addwf ARG2H,w ; w=w+ARG2 addwf RESH,f ; RESH=w return ; Return from subroutine end ; End of program
D:\Pic Projects LED Flash Project All associated files Event Count Project All associated files LED Scanning Project All associated files
;Program to set port B pins to logic one (1). ;Version: 1.0 Date: April 25,2007 MCU: PIC16F887 Programmer: John Smith ;***** Declaration and configuration of the microcontroller ***** PROCESSOR 16f887 #include "p16f887.inc" __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ;***** Variable declaration ***** Cblock 0x20 ; First free RAM location endc ; No variables ;;***** Program memory structure ***** ORG 0x00 ; Reset vector goto Main ; After reset jump to this location ORG 0x04 ; Interrupt vector goto Main ; No interrupt routine Main ; Start the program banksel TRISB ; Select bank containing TRISB clrf TRISB ; Port B is configured as output banksel PORTB ; Select bank containing PORTB movlw 0xff ; W=FF movwf PORTB ; Move W to port B Loop goto Loop ; Jump to label Loop EndThe program should be written to the ‘Blink.asm’ window or copied from disc by means of options copy/paste. When copied, the program should be compiled into executable HEX format by using option PROJECT -> BUILD ALL. A new window appears. The last sentence is the most important because it tells us whether compiling has succeeded or not. Clearly, ’BUILD SUCCEEDED’ message means that no error occurred and compiling has been successfully done. In case an error occurs, it is necessary to click twice on the message referring to it in the ‘Output’ window, which automatically switch you over to assembly program, directly to the line where the error has occurred.