KEMBAR78
Examples in Assembler | PDF | Assembly Language | Digital Electronics
0% found this document useful (0 votes)
14 views11 pages

Examples in Assembler

This document explains basic concepts of assembly language for microcontrollers, including instructions such as EQU, #DEFINE, and ORG. It also describes the use of labels, subroutines, and the importance of order when programming. An example program is provided that uses a delay subroutine to generate a blinking signal on a port.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views11 pages

Examples in Assembler

This document explains basic concepts of assembly language for microcontrollers, including instructions such as EQU, #DEFINE, and ORG. It also describes the use of labels, subroutines, and the importance of order when programming. An example program is provided that uses a delay subroutine to generate a blinking signal on a port.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

MICROCONTROLLERS

DEFINITIONS AND EXAMPLES OF 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.

• An example of this is labels, we can assign a name to a record of


memory, this is done using the instruction EQU. For example:

VARIABLE1 EQUALS 0CH

From now on, instead of writing 0CH, we can write VARIABLE1

With CONEQU we can also name constants in the same way.

• 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:

#DEFINE BANK1 BSF STATUS,5


#DEFINE BANK0 BCF STATUS,5

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:

A little bit of order:

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 *
*
;************************************

;(It is advisable to put a title and a


small explanation of what
(make the program)

(First the ECU and the #DEFINE)

STATUS EQU 03H


TRISA EQU 05H
PORTA EQU 05H

#DEFINE BANK0BCF STATUS,5


#DEFINE BANK1BSF STATUS,5

(Then we start with the program)

ORG 00H We always start writing in this direction.


BANK1 We went to bank 1 to do some
;configurations
BCF TRISA,0 We configure RA0 as output
BSF TRISA,1 We configure RA1 as input
BANK0 We return to bank 0

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

A subroutine or subprogram is a part of a program that does something


concrete and is often repeated, to save memory and effort and to
to make the program more understandable, it is grouped in the form of a subroutine.
A subroutine must always be executed by calling it with the instruction
CALL y at the end of that subroutine there must always be a RETURN.
The diagram on the right shows how subroutines work:

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 *
;******************************************

STATUS EQU 03H


TRISB EQU 06H
PORTB EQU 06H

ACCOUNT1 EQU 0CH The variables that we always use to


from address 0Ch
ACCOUNT2 EQU 0DH

F EQU 1
w EQU 0

ORG 00H
BSF STATUS,5 bank 1
BCF TRISB,0 RB0 as output
BCF STATUS,5 bank 0

START BSF TRISB,0 Set "1" RB0 (turn on)


CALL DELAY Call the delay subroutine
BCF TRISB,0 When he returns from the delay put
;a "0" RB0 (turns off)
CALL DELAY call the delay subroutine
GO TO START when he/she comes back from the delay

3
MICROCONTROLLERS
execute the GOTO

;===================================================
DELAY: Delay subroutine =
;= Modify the following records: =
;= ACCOUNT1 =
;= ACCOUNT2 =
;= Accumulator =
;= STATUS =

It is advisable to make a small summary of what


Each subroutine can be very useful for us to
use it in other programs)

DELAY MOVLW 010H Load the accumulator with the value


10H (16 in decimal)
MOVWF COUNT1 Move the contents of the accumulator
; ACCOUNT1
ACA1 MOVLW 0FFH Load the accumulator with the value FFH
MOVWF COUNT2 Move the contents of the accumulator
to account2
ACA DECFSZ COUNT2,F Decrement COUNT2, save the result
;in f, and if it is zero it skips the next one
instruction
GO TO HERE decrease again while
;ACCOUNT2 should not be zero
DECFSZ ACCOUNT1, F CUENTA1 is decremented every time
ACCOUNT2 reaches zero
GOTO ACA1 while COUNTER1 does not reach zero, reload
COUNT2 and repeat the process
RETURN returns to the main program

;= =
= END OF THE DELAY SUBROUTINE =
;===================================================

END End of the program

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:

1. Due to a change in the bits RB4-RB7


2. By the state of RB0
3. Due to overflow of the Timer-counter
4. Finally, end of the data EEPROM writing cycle

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 *
;*******************************************

STATUS EQU 03H


TRISA EQU 05H
PORTA EQU 05H
TRISB EQU 06H
PORTB EQU 06H
INTCON EQU 0BH

CURRENT EQU 0CH


STAT EQU 0DH

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:
;=========================

ORG 04H The pic jumps to this address when it occurs.


an interruption
BCF INTCON,0 ;bit that indicates a change in RB4-RB7, remember that
it must be set to "0" by program, this is the
moment

we start by saving the content of the accumulator


and the STATUS to restore them before leaving from
the interruption (it is advisable to do this
as long as interrupts are used)

Move W to ACUM Copy the accumulator to the ACUM register


MOVF STATUS, W Store STATUS in the accumulator

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

We invert the state of RA0:


;============================

BTFSC PORTA,0 if RA0 is "0" skip the next instruction


GO TO ESUNO go to ESUNO
BSF PORTA,0 Set RA0 to "1" (because it was "0")
GO TO DONE RA0 is already inverted, go to DONE.

ESUNO BCF PORTA,0 Set RA0 to "0" (Because it was "1")

The state of RA0 has already been inverted.


;===================================

now we need to restore the STATUS values and


;clear the accumulator before exiting the interrupt:

MOVE STAT,W Store the content of STAT in the accumulator


Move W to STATUS Restore the STATUS
SWAPF ACUM,F Turn the ACUM record around.
SWAPF ACUM,W Go back around the ACUM record and restore it.
the accumulator (With the SWAPF instruction to not
change the STATUS, the MOVF instruction alters the
bit 2 of the STATUS
RETFIE end of the interruption

End of the interruption


;======================

START BANK1 We go to bank 1


MOVLW 0FFH All bits of the accumulator to '1'
Move W to TRISB we configure the entire port B as inputs
BCF TRISA,0 ;RA0 as output
BANK0 We return to bank 0

Interrupt configuration:
;====================================

BSF INTCON,7 Enable global interrupts


BSF INTCON,3 Enable the interrupt on port B change

;====================================
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)

NOTHING GOES TO NOTHING In this example, nothing is done in the program.


principal, it is simply expected to jump the
interruption. The true utility of the
interruptions mean that you can do "things"
while not worrying about the interruption

END END OF PROGRAM


6
MICROCONTROLLERS
9. Timer - Counter TMR0

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)

The following example uses overflow interruption ofTMR0to obtain a wave


square at the output RB0:

;*******************************************
;* 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 *
;*******************************************

OPTIONR EQU 01H TMR0 Configuration Register


STATUS EQU 03H
TRISB EQU 06H
PORTB EQU 06H
INTCON EQU 0BH

Right now 0CH


STAT EQU 0DH

F EQU 1
w EQU 0

#DEFINE BANCO0BCF STATUS,5


#DEFINE BANK1BSF STATUS,5

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

The interruption begins:


;=========================

ORG 04H The chip jumps to this address when it occurs.


an interruption
BCF INTCON,2 Bit that indicates overflow of TMR0, remember
that has to be set to "0" per program, this is
the moment

we start by saving the contents of the accumulator


and of the STATUS to restore them before leaving
the interruption (it is advisable to do this
as long as interrupts are used)

Move W to ACUM Copy the accumulator to the ACUM register


MOVF STATUS,W Store STATUS in the accumulator
BANK0 Just in case, you never know where
main program skips the interrupt
Move W register
STAT to file register
Copy the accumulator to the STAT register

To generate a square wave, we invert the


RB0 state each time an interrupt occurs
;=================================================

BTFSC PORTB,0 If RB0 is '0', skip the next instruction


GOTO ESUNO go to ESUNO
BSF PORTB,0 Set RB0 to "1" (because it was "0")
GO TO FACT RB0 is already inverted, go to DONE

ESUNO BCF PORTB,0 Set RA0 to "0" (Because it was "1")

The state of RB0 has already been inverted.


;===================================

now we need to restore the STATUS values and


clear the accumulator before leaving the interruption:

MOVE STAT,W Load the content of STAT into the accumulator


Move W to STATUS Restore the STATUS
SWAPF ACUM,F Turn around the ACUM register
SWAPF ACUM,W Turn the ACUM record back and restore
the accumulator (With the SWAPF instruction to not
change the STATUS, the MOVF instruction alters the
bit 2 of STATUS
RETFIE end of the interruption

End of the interruption


;======================

START BANK1 We go to bank 1


BCF TRISB,0 ;RB0 as output
BCF OPTIONR,3 We assign the prescaler to TMR0
BCF OPTIONR,0 ;\
8
MICROCONTROLLERS
BCF OPTIONR,1 Prescaler 1/2
BCF OPTIONR,2 ;/
BCF OPTIONR,5 TMR0 entry per cycle of
internal instruction (starts counting)
BANK0 We return to bank 0

Interrupt configuration:
;====================================

BSF INTCON,7 Enable interrupts globally


BSF INTCON,5 Enable the overflow interrupt for TMR0

;====================================
the interrupts are already configured,
From now on, when TMR0 overflows
will jump to the interrupt (at address 04h of
;program)

NOTHING GOES TO NOTHING In this example, nothing is done in the program.


principal, you just have to wait for it to jump
interruption. The true usefulness of the
interruptions mean that you can do "things"
while not worrying about the interruptions

END ;END OF PROGRAM

10. Push buttons and switches (bounces)

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 *
;************************************

STATUS EQU 03H


TRISB EQU 05H
PORTB EQUALS 05H

ACCOUNT 0CH Register where we will count


DELAY EQU 0DH Delay registration

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

CLRF ACCOUNT; Resets the account to zero

START BTFSS PORTB,0 if RB0 is "1" skip the next instruction


CALL SUMA1 Call the subroutine SUMA1 (because RB0 is "0" and,
therefore, the button has been pressed
GO TO START go back to START

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

SUMA1 INC. ACCOUNT,F Increase the ACCOUNT record


CALL REBOUND Call the subroutine that prevents bounces
EXPECTED BFSS PORTB,0 ;\
GOTO WAIT Wait for the button to be released to return
RETURN ;/

; End of SUMA1
;================================================

;================================================
; BOUNCE: Subroutine that makes a small
; timing to prevent
; the rebounds

REBOTEMOVLW 0FFH Load the accumulator with 0FFh


MOVWF RETARD Move the contents of the accumulator to DELAY
REBO DECFSZ RETARDO,F ;\
GOTO REBO Does not return until DELAY reaches zero
RETURN ;/

; End of REBOUND
;=================================================

END Indicates the end of the program

11

You might also like