Examples in Assembler
Examples in Assembler
We can use Windows Notepad to write the programs, once written it is saved.
with the .asm extension and is converted (assembled) with an assembler program, the MPASM. The
the result is a file with a .hex extension that we can transfer to the PIC16F84. All of this is explained
more detailed in PIC16F84 Programmer.
There are a series of instructions that are for the assembler and help us with the task of
simpler and more readable programming.
• Another instruction for the assembler that we will use will be the #DEFINE instruction.
It's similar to EQU, except that here we don't label a record, we can label one.
whole instruction, For example:
From now on, when we write BANK1, the bank selection bit will be set to '1' and
we will switch to bank 1, when writing BANK0 we will switch to bank 0
• Indicate to the assembler the address (of program memory) where it will be stored
instruction that follows. For example:
ORG 00H
CLRF VARIABLE1
The CLRF instruction is at program memory address 00H (it will be the first instruction
in being executed by the pic)
• END: It is written at the end of the program to indicate that it has finished. (it is mandatory, otherwise it will not give
error)
• Labels for Program addresses: very useful for use with CALL instructions.
subroutine) oGOTO(Jump). For example:
It is important to bring a little order when writing the program, it will help us a lot:
• First go the EQUs and the #DEFINEs, then we start with the program.
• The program is written in four columns separated by tabs:
o In the first column, the labels for program addresses are placed.
oIn the second column, the instructions (BSF, CLRF, BTFSC... etc.) are placed.
oIn the third column, the records or parameters that it affects are placed.
instruction.
oIn the fourth column, you can include any comments you deem appropriate (the more, the better)
better) followed by a semicolon.
1
MICROCONTROLLERS
Example of a well-organized program (it could be improved ;):
;************************************
EXAMPLE 1: WELL-ORDERED PROGRAM
;************************************
The following program configures
RA1 as input and RA0 as *
output and makes the output (RA0)
be the inverse of the input *
*
;************************************
START BTFSC PORTA,1 Check the input (RA1), if it is "0" skip the
next instruction
GO TO ESUNO if the input (RA1) is "1" it goes to ESUNO
BSF PORTA,0 Set output RA0 to "1". Execute this instruction.
because input RA1 was "0"
GO TO START Check the status again.
Entry RA1
ESUNO BCF DOOR,0 Set output RA0 to '0'. Execute this instruction
because the input RA1 was "1"
GO TO START Check the status again.
;entry RA1
END Indicates the end of the program
2
MICROCONTROLLERS
7. Subroutines
During the main program, the SUBR subroutine is called several times.
(the the name is the least important) with the CALL instruction. When the pic executes
one The CALL instruction saves the code address in memory.
program that must return in such a way that when it
find with the RETURN instruction go back to the main program
where he left it.
A subroutine can not only be called from the main program, it can also be done from
another subroutine (a subroutine that calls another subroutine) or from an interrupt (right away the
we will see).
The following example shows a program that uses a delay subroutine called DELAY.
This delay subroutine is done by decrementing the CUENTA2 register from FFh to 00h 16
times (the times that CUENTA2 is decremented are counted backwards by CUENTA1) From this
how to waste time (the lost time with this subroutine depends on the frequency at which
Let the pic operate
;******************************************
;* EXAMPLE 2 USE OF SUBROUTINES *
;******************************************
This program configures RB0 as output.
and generates an intermittence in said
output *
;******************************************
F EQU 1
w EQU 0
ORG 00H
BSF STATUS,5 bank 1
BCF TRISB,0 RB0 as output
BCF STATUS,5 bank 0
3
MICROCONTROLLERS
execute the GOTO
;===================================================
DELAY: Delay subroutine =
;= Modify the following records: =
;= ACCOUNT1 =
;= ACCOUNT2 =
;= Accumulator =
;= STATUS =
;= =
= END OF THE DELAY SUBROUTINE =
;===================================================
8. Interruptions
When an interruption occurs, the PIC automatically leaves whatever it is doing and goes straight to the
address 04h of the program and executes what it finds from there until it encounters the
RETFIE instruction that will make you leave the interruption and return to the place where you were before.
of such interruption occurring.
In order for an interrupt to occur, global interrupts must be enabled and the
specific interruption that we want to use (with the recordINTCONThis pic has 4 types of
possible interruptions:
While an interrupt is being executed, another interrupt cannot occur, the PIC does not allow it.
allows.
4
MICROCONTROLLERS
An important thing to consider when using interrupts is that when they occur
we could be working with registers that can be modified in the interrupt itself, such as
the accumulator or theSTATUSSo that the interruption does not spoil the good functioning of
In the main program, it is advisable to store the values of these registers in other variables that we do not intend to use.
to modify. Before leaving the interruption, we restore the saved values and everything
resolved.
The following example shows a program that uses the interrupt by change in port B.
pins RB4 to RB7
;*******************************************
Example 3: Use of Interruptions *
;*******************************************
This program toggles the state of the pin
RA0 each time the state is modified
of some of the pins RB4, RB5, RB6 or
* RB7. To do this, enable the interrupt *
for change of RB4-RB7 *
;*******************************************
F EQU 1
w EQU 0
#DEFINE BANK0BCF 5
#DEFINE BANK1BSF 5
ORG 00H
GO TO START we put this GOTO at the beginning to be able to put
the interrupt subroutine from
the address 04h
Interruption begins:
;=========================
5
MICROCONTROLLERS
BANK0 Just in case, you never know in which part of
main program skip the interruption
Move W to STAT Copy the accumulator to the STAT register
Interrupt configuration:
;====================================
;====================================
the interrupts are already configured,
From now on, when there is a change in RB4-RB7
will jump to the interruption (to address 04h of
;program)
The recordTMR0it can count internal instruction cycles or input pulses by RA4 according to the value
from bit 5 of the registerOPTION( TOCSIf this bit is '1'TMR0counts pulses by RA4 and is given
It calls the Counter; if the bit is at "0", it counts internal instruction cycles and is called Timer.
Each instruction cycle lasts 4 times the clock cycle of the PIC (for a 4MHz clock ==> Cycle
Clock = 0.25 µSec ==> Instruction cycle = 4 X 0.25 = 1 µSec)
When we use it as a counter (By RA4) we can determine if the increment will occur on the edge.
ascending or descending with bit 4 of the registerOPTION( TOSE)
We can read or write the record.TMR0at any time. When we write in it, it stops
count for two cycles, when we read it nothing happens.
We can assign the prescaler to theTMR0If we do this, we can choose the factor in which it will be seen.
divided the count through thebits from 0 to 2from the recordOPTIONaccording to thedivision factor table.
For example, if we choose a division factor of 1/2, 2 pulses have to enter forTMR0be
increment by one, if it is at 1/4 there must be 4... etc.
We can also use the interruption that occurs when it overflows.TMR0, that is to say,
when it goes from FFh to 00h. (it is configured from the registerINTCON)
;*******************************************
;* EXAMPLE 4: USE OF TMR0 *
;*******************************************
This program creates a square wave
the RB0 output, for this it uses the TMR0
and the interruption due to overflow of
same. The prescaler will be assigned with
;* a division factor of 1/2. From this *
The interruptions will jump to *
fixed time intervals. Investing *
the state of RB0 during the *
interruptions will achieve a wave
perfect square *
;*******************************************
F EQU 1
w EQU 0
7
MICROCONTROLLERS
ORG 00H
GO TO START we put this GOTO at the beginning to be able to put
the interrupt subprogram starting from
the address 04h
Interrupt configuration:
;====================================
;====================================
the interrupts are already configured,
From now on, when TMR0 overflows
will jump to the interrupt (at address 04h of
;program)
It is very common to use buttons or switches on one of the inputs of the pic to control it.
These buttons do not make a perfect and instant connection as we might think: a button
is composed of two metal parts that come into contact (hit each other) when operated. This
shock generates tiny bounces that happen so quickly they are imperceptible to
We, however, are not for the PIC that works at those speeds. This is a problem.
very common that can drive us crazy if we don't know it but that you will solve without problems when
You have just read this page. The following diagram shows what would happen when pressing a button:
The solution is simple, just add a small delay in our program from the moment it
detects the first pulse until the button input is read again. This delay must be
long enough to ensure that by the time it ends the bounces have already subsided, but
also short enough to be imperceptible to us.
In the following example, the pulses introduced to the PIC by RB0 are counted. The diagram is the
next
9
MICROCONTROLLERS
Notice that when the button is pressed, the RB0 input goes to '0'. To avoid counting the bounces
a delay subroutine called REBOTE is called, this subroutine works well for oscillators
of 4MHz.
;************************************
EXAMPLE 5: AVOIDING BOUNCES
;************************************
The following program counts the *
* times that a button is pressed *
connected to RB0 and prevents the
bounces of the same through the
* bounce delay subroutine *
;************************************
F EQU 1
w EQU 0
#DEFINE BANK0BCF 5
#DEFINE BANK1BSF 5
ORG 00H
BANK1 We go to bank 1
BSF TRISB,0 We configure RB0 as Input
BANK0 We return to bank 0
10
MICROCONTROLLERS
;================================================
; SUMA1: Subroutine that adds one to the register
; COUNT and wait for it to be released
; button connected to RB0. It has in
; count the rebounds
; End of SUMA1
;================================================
;================================================
; BOUNCE: Subroutine that makes a small
; timing to prevent
; the rebounds
; End of REBOUND
;=================================================
11