0% found this document useful (0 votes)
62 views

Programming The PIC16F877 in PIC MPASM Assembly Language

This document discusses programming the PIC16F877 microcontroller in PIC MPASM assembly language. It provides information on the PIC16xxx instruction set categories and formats. It also gives examples of common instructions like MOVLW, MOVWF, BSF and BTFSC. The document includes two examples, one using software delays and one using Timer 0, to flash an LED when a switch is pressed with a 1 second period. It provides details on configuring I/O ports and registers to implement the LED flasher functionality.

Uploaded by

farhan ghafoor
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views

Programming The PIC16F877 in PIC MPASM Assembly Language

This document discusses programming the PIC16F877 microcontroller in PIC MPASM assembly language. It provides information on the PIC16xxx instruction set categories and formats. It also gives examples of common instructions like MOVLW, MOVWF, BSF and BTFSC. The document includes two examples, one using software delays and one using Timer 0, to flash an LED when a switch is pressed with a 1 second period. It provides details on configuring I/O ports and registers to implement the LED flasher functionality.

Uploaded by

farhan ghafoor
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 28

Programming the PIC16F877 in

PIC MPASM Assembly Language

11/21/22 ECE331 PIC Assembly (KEH) 1


PIC16xxx Family Instruction Set
• Each instruction is a single 14-bit word
• THREE basic categories:
– Byte Oriented
– Bit Oriented
– Literal (Immediate Constant) and Control
• One instruction cycle consists of FOUR clock
oscillator periods. Hence for a 20 MHz clock, an
instruction takes 4/20MHz = 200 ns to execute.
• Any transfer of control (call, jump, conditional
test, or goto) instruction takes two 200 ns cycles
to allow the instruction queue to be refilled.
11/21/22 ECE331 PIC Assembly (KEH) 2
PIC 16xxx Family
Instruction Format

11/21/22 ECE331 PIC Assembly (KEH) 3


PIC16XXX Byte-Oriented Instructions

11/21/22 ECE331 PIC Assembly (KEH) 4


PIC16xxx Bit-oriented and Literal
and Control Instructions

11/21/22 ECE331 PIC Assembly (KEH) 5


Setting the directional bit “d”
• If you add the include file to your assembly
program:

#include "p16f877A.inc“

Then the directional bit “d” value is pre-defined


as “w equ 0” and “f equ 1”. So we may write

mydat equ 0x20


addwf mydat,f ;mydat  mydat + W
addwf mydat,w ;W  mydat + W

11/21/22 ECE331 PIC Assembly (KEH) 6


Some examples
• MOVLW 0x12 ;Move $12 into accumulator “W”
;”Literal” => Immediate constant
• MOVWF mydat ;Move W into reg file “mydat”
• MOVF mydat,w ;Move reg file “mydat” into W
• MOVF mydat,f ;What good is this instruction?
;(It sets the Z flag, allowing us to
;see if reg file “mydat” contains 0)
• BSF mydat,3 ;Set Bit #3 of mydat |
;(Bit #0 is the LSB on right)

11/21/22 ECE331 PIC Assembly (KEH) 7


Branch to location “TARGET” if
W =< mydat
(in an unsigned sense)
SUBWF mydat,f ;mydat – W
BTFSC 3,0 ;Test Bit #0 of STATUS reg (the C flag) and
;skip next instruction if C is clear
;implying that a borrow was requested,
;thus implying that mydat is less than W in
;an unsigned sense.
;Remember on PIC the borrow flag is the
;inverse of the C flag (unlike the HC12).
GOTO Target
....EXECUTE THESE INSTRUCTIONS IF W>mydat...
Target NOP ;Branch here if W =< mydat
11/21/22 ECE331 PIC Assembly (KEH) 8
Status Register

11/21/22 ECE331 PIC Assembly (KEH) 9


Example #1 LED Flasher using Software Delay Loops
;***** PIC16F877A MPASM Example #1 *****
;NOTE: When setting up the project, be sure to choose the active
;toolsuite to be "Microchip MPASM Toolsuite" instead of the
;"Hi-Tech PICC Toolsuite" as you did with C programs.
;
;This is a simple I/O Example. When input RA0 goes HIGH,
;LED connected to output RA1 will FLASH ON/OFF at 1 s rate
;1 second delay obtained using two nested software timing loops
;**************************
list p=16F877A
#include "p16f877A.inc" ;include register definitions file
;also W is defined to equal 0 and
;F is defined to equal 1, so the
;destination bit(D)can be set using
;the W and F symbols. (W => result in
;working register w, while F => result
;in indicated register file location.

radix dec ;make default numbers decimal values


org 0 ;Reset vector is at prog loc 0x00.
goto start ;Skip over INT vector at prog loc 0x04.

CBLOCK 0x20 ;Use CBLOCK and ENDC to reserve a block of register file locations
;starting at address 0x20 in register file space
count1 ;count1 = 0x20
count2 ;count2 = 0x21
count3 ;count3 = 0x22
count4 ;count4 = 0x23
ENDC

11/21/22 ECE331 PIC Assembly (KEH) 10


org 0x05 ;Start assembling program at location 5 in program space.
start
clrf PORTA ;Initialize port A by zeroing
;output data latches.
banksel ADCON1 ;This directive switches to data bank that
;ADCON1 is found in (Bank 1). It results in
;the assembly of the following instruction:
;"bsf STATUS,5" (Set RP0 = 1)
movlw 0x06
movwf ADCON1 ;Configure PORTA for digital I/O (out of reset, PORTA is analog)
movlw 0x01 ;Set RA0 for input, RA1 for output
movwf TRISA

banksel PORTA ;This directive switches to data bank


;that is found in (Bank 0) in following
;instruction: "bcf STATUS,5" Set RP0 = 0.
waitsw btfsc PORTA,0 ;check RA0
goto waitsw ;wait until switch on RA0 pressed down (RA0 goes low).
movlw 5 ;Flash LED 5 times.
movwf count4
flshagn bsf PORTA,1 ;turn ON LED on RA1 (LED cathode tied to ground)
call wait_swloop
bcf PORTA,1 ;turn OFF LED on RA1
call wait_swloop
decfsz count4,f
goto flshagn
done goto waitsw
;
11/21/22 ECE331 PIC Assembly (KEH) 11
;Subroutine wait_swloop -- delays about 1 second using nested
; software delay loops.
wait_swloop
movlw 80 ;all three loops count to 80
movwf count1 ;thus doubling this number
loopout movwf count2 ;increases delay time by 2^3 = 8!
loopmid movwf count3
loopinr decfsz count3,f
goto loopinr
decfsz count2,f
goto loopmid
decfsz count1,f
goto loopout
return
end

11/21/22 ECE331 PIC Assembly (KEH) 12


Example 2. LED Flasher using Timer 0
;***** PIC16F877 MPASM Example #2 *****
;Simple I/O Example. When input RA0 goes HIGH,
;LED connected to output RA1 will FLASH ON/OFF at 1 s rate
;1 second delay obtained using TMR0 to wait out 100 ten-ms intervals
;**************************
list p=16F877
#include "p16f877.inc" ;include register definitions file
;also W is defined to equal 0 and
;F is defined to equal 1, so the
;destination bit(D)can be set using
;the W and F symbols. (W => result in
;working register w, while F => result
;in indicated register file location.

radix dec ;make default numbers decimal values


org 0 ;Reset vector is at prog loc 0x00.
goto start1 ;Skip over INT vector at prog loc 0x04.

CBLOCK 0x20 ;Reserve reg file locns, starting at adr 0x20 in reg file
space
count3 ;count3 = 0x20
count4 ;count4 = 0x21
ENDC

11/21/22 ECE331 PIC Assembly (KEH) 13


org 0x05 ;Start assembling program at location 5 in program space.
start1
banksel OPTION_REG
movlw b'00000111'
movwf OPTION_REG ;timer tick period = (4/10E6)*256 = 75.85 microseconds
banksel PORTB ;note that 10 ms / 75.85 = 131.8, so 132 timer ticks lasts about 10 ms
clrf PORTB ;Initialize port A by zeroing
;output data latches.
banksel TRISB ;This directive switches to data bank that
;TRISB is found in (Bank 1). It results in
;the assembly of the following instruction:
;"bsf STATUS,5" (Set RP0 = 1)
movlw 0x01 ;Set RA0 for input, RA1 for output
movwf TRISB
banksel PORTB ;This directive switches to data bank
;that PORTB is found in (Bank 0) in following
;instruction: "bcf STATUS,5" Set RP0 = 0.
waitsw btfsc PORTB,0 ;check RA0
goto waitsw ;wait until switch on RA0 pressed down (RA0 goes low).
movlw 5 ;Flash LED 5 times.
movwf count4
flshagn bsf PORTB,1 ;turn ON LED on RA1 (LED cathode tied to ground)
call wait_1s_tmr0
bcf PORTB,1 ;turn OFF LED on RA1
call wait_1s_tmr0
decfsz count4,f
goto flshagn
done goto waitsw
;

11/21/22 ECE331 PIC Assembly (KEH) 14


;Subroutine wait_swloop -- delays about 1 second using nested sw delay loops
;
wait_1s_tmr0
movlw 100
movwf count3 ;repeat 10 ms loop 100 times to wait 1 second
wait_loop
movlw 256 - 132;
movwf TMR0 ;schedule TMR0 to wrap (overflow) in 10 ms.
bcf INTCON,2 ;clear TMR0IF flag (bit #2 of INTCON reg)
wt10ms
btfss INTCON,2 ;Wait till TMR0 overflows.
goto wt10ms
decfsz count3,f
goto wait_loop
return
end

11/21/22 ECE331 PIC Assembly (KEH) 15


Example 3. 220 Hz Square Wave using TMR0 Interrupts

;***** PIC16F877 MPASM Example #3 *****


;Interrupt Example. 220 Hz square wave generated on RB1
;**************************
list p=16F877 ;change to 16F877A if necessary
#include "p16f877.inc"
radix dec ;make default numbers decimal values
org 0 ;Reset vector is at prog loc 0x00.
goto startpgm ;Skip over INT vector at prog loc 0x04.
org 4 ;Interrupt Vector
goto int_service
CBLOCK 0x20 ;Reserve reg file locns, starting at adr 0x20
w_temp ;w_temp = 0x20
status_temp ;status_temp = 0x21
ENDC
org 0x05 ;Start assembling program at location 5 in program space.
startpgm
banksel OPTION_REG
movlw b'00000111‘ ;Prescale TMR0 by 256. Assuming a 13.5 MHz crystal osc freq,
;timer tick = (4/13.5 Mhz)*256 = 75.85 microseconds
movwf OPTION_REG

11/21/22 ECE331 PIC Assembly (KEH) 16


banksel PORTB
clrf PORTB ;Initialize port B by zeroing
;output data latches.
banksel TRISB
movlw 0xFD ;Set RB1 for output
movwf TRISB
banksel TMR0
movlw 256 – 30 ;(1/440.)/75.85 microseconds = 30.0
movwf TMR0 ;Schedule Timer0 to interrupt in 1/440th of a second.
bcf INTCON,2 ;clear TMR0IF flag
movlw b'10100000'
movwf INTCON ;enable TMR0 interrupts
idle_loop
goto idle_loop
;
; ***** END OF MAIN PROGRAM ******

11/21/22 ECE331 PIC Assembly (KEH) 17


; ************* Start of INTERRUPT SERVICE ROUTINE *******
int_service
movwf w_temp ;save w and status regs in temp locns
swapf STATUS,w
movwf status_temp
banksel TMR0
bcf INTCON,2 ;clear TMR0IF flag (shut the baby up)
movlw 256 - 30
movwf TMR0 ;schedule next TMR0 interrupt
movf PORTB,W ;get PORTB into W
xorlw 0x02 ;invert Bit #1 of W
movwf PORTB ;Send inverted result out to RB1
swapf status_temp,w ;restore w and status flags fm temp locns
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie
end

11/21/22 ECE331 PIC Assembly (KEH) 18


Ex 4. Light Show: Indirect Addressing
;***** PIC Example #4 *****
;Use of Indirect Addressing
;(via FSR and INDF register) to
;implement a simple
;Light Sequencer. Recall that
;the INDF register (at locn
;0x00, 0x80, 0x100, 0x180)
;actually is no register at all, but
;rather it becomes whatever register
;whose addr is loaded into FSR
;(at locn 0x04, 0x84, 0x104, 0x184). If
;FSR contains 0x20, then writing to INDF
;to the register at 0x20, and reading
;from INDF reads from the register at 0x20.
;
;When SW on RA0 goes HIGH,
;4 LEDs connected to outputs
;RA1, RA2, RA3, and RA4
;are sequenced according to
;entries in a table placed
;in RAM.
;**************************
11/21/22 ECE331 PIC Assembly (KEH) 19
list p=16F877A
#include "p16F877A.inc"
radix decimal

CBLOCK 0x20 ;start allocating RAM at first free locn (0x20)


count1 ;count1 = 0x20
count2 ;count2 = 0x21
count3 ;count3 = 0x22
iter_cnt ;inter_cnt = 0x23
seq_tbl: 10 ;table with 10 light pattern entries
;seq_tbl = 0x24 (starting adr of table)
temp ;temp = 0x2E
ENDC
org 0 ;Reset vector is at prog loc 0x00.
goto beginpgm ;Skip over INT vector at prog loc 0x04.
org 0x05

11/21/22 ECE331 PIC Assembly (KEH) 20


beginpgm
banksel ADCON1
movlw 6
movwf ADCON1
banksel PORTA
clrf PORTA ;initialize port A by zeroing
;output data latches.
banksel TRISA
movlw 0x01 ;Set RA0 for input, rest outputs
movwf TRISA
banksel PORTA ;switch back to bank 0

11/21/22 ECE331 PIC Assembly (KEH) 21


;*** initialize RAM table
movlw B'0001'
movwf seq_tbl+0
movlw B'0010'
movwf seq_tbl+1
movlw B'0100'
movwf seq_tbl+2
movlw B'1000'
movwf seq_tbl+3
movlw B'1100'
movwf seq_tbl+4
movlw B'1110'
movwf seq_tbl+5
movlw B'1111'
movwf seq_tbl+6
movlw B'0000'
movwf seq_tbl+7
movlw B'1001'
movwf seq_tbl+8
movlw B'0110'
movwf seq_tbl+9
11/21/22 ECE331 PIC Assembly (KEH) 22
waitsw btfss PORTA,0 ;check RA0
goto waitsw ;wait until switch on RA0 is UP.
movlw 5
movwf iter_cnt
wrap_to_top
movlw seq_tbl ;initialize fsr reg to point to start of table
movwf FSR
get_next_pattern
movf INDF,w ;get next light pattern from table
movwf temp
rlf temp,f ;rotate temp one bit to left, since LEDs are on RA1 - RA4
movf temp,w
movwf PORTA ;put out new light pattern
call wait_swloop
incf FSR,f
movf FSR,w
sublw seq_tbl+10
btfss STATUS,2 ;Skip next instruction if Z = 1
goto get_next_pattern
decfsz iter_cnt,f
goto wrap_to_top
done goto done
;
11/21/22 ECE331 PIC Assembly (KEH) 23
;Subroutine wait_swloop -- delays about 1 second using nested sw loop
;
wait_swloop
movlw 80
movwf count1
loopout movwf count2
loopmid movwf count3
loopinr decfsz count3,f
goto loopinr
decfsz count2,f
goto loopmid
decfsz count1,f
goto loopout
return
end

11/21/22 ECE331 PIC Assembly (KEH) 24


Ex 5. Light Show with Table in Program Memory

;Use of Lookup Table (in program memory)


;to implement a simple Light Sequencer.
;
;When SW on RA0 goes HIGH, 4 LEDs connected to outputs
;RA1, RA2, RA3, and RA4 are sequenced according to
;entries in a table placed in Program ROM
;**************************
list p=16F877
#include "P16F877.inc"
radix decimal
CBLOCK 0x20 ;first free Reg File locn
;data locations 0x00 - 0x0B.
count1
count2
count3
iter_cnt
tbl_ptr
temp
ENDC

11/21/22 ECE331 PIC Assembly (KEH) 25


org 0 ;Reset vector is at prog loc 0x00.
goto beginpgm ;Skip over INT vector at prog loc 0x04.

org 0x05

beginpgm
banksel ADCON1
movlw 6
movwf ADCON1
banksel PORTA
clrf PORTA ;initialize port A by zeroing
;output data latches.
banksel TRISA
movlw 0x01 ;Set RA0 for input, RA1 for output
movwf TRISA
banksel PORTA

11/21/22 ECE331 PIC Assembly (KEH) 26


waitsw btfss PORTA,0 ;check RA0
goto waitsw ;wait until switch on RA0 is UP.
movlw 5
movwf iter_cnt
wrap_to_top
movlw 0
movwf tbl_ptr
get_next_pattern
call pattern_subroutine
movwf temp
rlf temp,f ;rotate temp one bit to left,
movf temp,w ;since LEDs are on RA1 - RA4

movwf PORTA ;put out new light pattern


call wait_swloop
incf tbl_ptr,f
movf tbl_ptr,w
sublw 10
btfss STATUS,2 ;Skip next instruction if Z = 1
goto get_next_pattern
decfsz iter_cnt,f
goto wrap_to_top
done goto done

11/21/22 ECE331 PIC Assembly (KEH) 27


;Subroutine wait_swloop -- delays about 1 second using nested sw loop
wait_swloop
movlw .80
movwf count1
loopout movwf count2
loopmid movwf count3
loopinr decfsz count3,f
goto loopinr
decfsz count2,f
goto loopmid
decfsz count1,f
goto loopout
return
;Pattern lookup table - part of program space the "Define Table" (DT) directive assembles
;a series of "retlw" instructions. The table below consists of retlw 1, retlw 2, retlw 4, retlw 8,
; etc. Upon return from this routine, w contains the looked up "light pattern" value.
pattern_subroutine
movf tbl_ptr,w
addwf pcl,f ;compute index into table and jump there and execute
;the appropriate retlw instruction!
seq_tbl dt B'0001',B'0010',B'0100',B'1000',B'1100',B'1110',B'1111',B'0000'
dt B'1001',B'0110'
end

11/21/22 ECE331 PIC Assembly (KEH) 28

You might also like