Useful Tools

contact us contact tutor/group email to a friend accessibility options report a fault
Microcontrollers

Microcontrollers

Even More Assembler Tutorials for both MPLAB Simulation and Downloading to the MMM development Board. These examples need the MMM selection switches to be set with S2 to be in RC mode with S4 set to FAST.


Code TUTMM12.ASM

; TUTMM12.ASM - similar toTUTMM9.ASM, showing use of CALL and RETURN
; simply reading the 5 switches on Port A,
; and showing their replicated status on Port B LED's.
  LIST p=16F84  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data for running the code on the MMM development board.
; PICmicro MCU type: 16F84
; Oscillator: RC mode, fast, VR1 fully clockwise (max.rate)
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
__CONFIG H'3FFB' ; RC mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
;
STATUS EQU H'03' ; user-created variable called COUNT stored in location 20 hex
TRISA EQU H'85' ; Data Direction Register for PORTA @ 085 address
PORTA EQU H'05' ; Port A data register (PORTA at address 0x05)
TRISB EQU H'86' ; Data Direction Register for PORTB @ 086 address
PORTB EQU H'06' ; Port B data register (PORTB at address 0x06)
W EQU 0 ;
;
; ****** MAIN PROGRAM ******
  ORG 0 ; Reset Vector
  GOTO 5 ; Goto start of program
  ORG 4 ; Interrupt vector
  GOTO 5 ; Goto start of program
  ORG 5 ; Start of program memory
;
  CLRF PORTB ; Clear PORTB register - makes all Port B pins to logic 0
  PAGE1   ; access page1 of memory
  MOVLW B'00011111' ; load literal value of '31' into W
  MOVWF TRISA ; set all Port A as inputs (RA0 to RA4)
  CLRF TRISB ; clear TRISB making all Port B pins outputs (PB0 to PB7)
  PAGE0   ; back to page0 of memory
;
LOOP CALL PROG1 ; goto the subroutine 'PROG1'
  MOVWF PORTB ; move the value of PORTA (obtained from PROG1) onto PORTB LED's
  GOTO LOOP ; go back to LOOP, and repeat
;
PROG1 MOVF PORTA,W ; read Port A, & store reading in W.
  RETURN   ; return from PROG1 call
  END   ; final statement

This simple demo illustrates the Call and Return Instructions to implement using a subroutine. On the MMM board it simply displays the status of the PORT A switches-pressed on the PORT B LED's. Like the previous examples this code can again be simulated within the MPLAB environment then the machine code can be downloaded to the MMM development board.

 


Code TUTMM13.ASM

This example of code uses the 4 PortA switches (SA0 to SA3) to be read to provide any one of fifteen different PortB LED options from within a TABLE within the code.

e.g. if '1' is read (0001) at Port A switches, it lights LB0 (0000 0001); if '3' is read (0011) at Port A switches, it lights NONE (0000 0000); if '4' is read (0100) at Port A switches, it lights '31' (0001 1111); etc. Check to see what is entered in the code for the rest of the table.

; TUTMM13.ASM
; showing use of a table
  LIST p=16F84  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data for running the code on the MMM development board.
; PICmicro MCU type: 16F84
; Oscillator: RC mode, fast, VR1 your choice of setting
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
__CONFIG H'3FFB' ; RC mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
;
PCL EQU H'02' ; Program Counter at address 0x02
STATUS EQU H'03' ; Status register at address 0x03
TRISA EQU H'85' ; Data Direction Register for PORTA @ 085 address
PORTA EQU H'05' ; Port A data register (PORTA at address 0x05)
TRISB EQU H'86' ; Data Direction Register for PORTB @ 086 address
PORTB EQU H'06' ; Port B data register (PORTB at address 0x06)
W EQU 0 ;
F EQU 1 ;
Z EQU 2 ;
STORE EQU H'20' ; User created Variable, named 'Store'
;
; ****** MAIN PROGRAM ******
  ORG 0 ; Reset Vector
  GOTO 5 ; Goto start of program
  ORG 4 ; Interrupt vector
  GOTO 5 ; Goto start of program
  ORG 5 ; Start of program memory
;
  CLRF PORTB ; Clear PORTB register - makes all Port B pins to logic 0
  PAGE1   ; access page1 of memory
  MOVLW B'00011111' ; load literal value of '31' into W
  MOVWF TRISA ; set all Port A as inputs
  CLRF TRISB ; clear TRISB making all Port B pins outputs (PB0 to PB7)
  PAGE0   ; back to page0 of memory
  MOVLW H'F0' ; load literal value of '240' into W so as to give the variable an initial value
  MOVWF STORE ; gives the variable STORE its initial value of 240 (= H'F0' = B'11110000')
  GOTO LOOP ; Go to 'LOOP' in the code
;
TABLE ANDLW H'0F' ; AND with 15 to limit jumps to 0-15
  ADDWF PCL,F ; ADD result to program counter
  RETLW D'255' ; 0 returns with 255 in W (11111111)
  RETLW D'1' ; 1 returns with 1 in W (00000001)
  RETLW '5' ; 2 returns with ASCII value for 5 (53)
  RETLW 0 ; 3 returns with 0 in W
  RETLW D'31' ; 4 returns with 31 in W
  RETLW D'193' ; 5 returns with 193 in W
  GOTO OTHER ; 6 jump to routine at OTHER
  RETURN   ; 7 returns with value in W unchanged
  RETLW B'10101010' ; 8 returns with this value in W
  RETLW H'C7' ; 9 returns with this value in W
  RETLW 'A' ; 10 returns with ASCII value for A (65)
  RETLW D'65' ; 11 returns with this value in W
  RETLW 'B' ; 12 returns with ASCII value for B
  RETLW 'x' ; 13 returns with ASCII value for x
  GOTO OTHER1 ; 14 jump to routine at OTHER1
  MOVF STORE,W ; 15 get value within STORE
  RETURN   ; return with STORE value now in W
;
LOOP MOVF PORTA,W ; read (switch settings value) Port A, & store in W
  CALL TABLE ; Go to TABLE subroutine - get table value for that setting value
  MOVWF PORTB ; Output TABLE value of PORT A switches onto PORTB LEDS
  GOTO LOOP ; Loop around endlessly
;
OTHER RETLW STORE ; returns with equated value for STORE in W
;
OTHER1 MOVLW D'128' ; Move the literal value of 128 (decimal) & store in W
  ADDWF PORTA,W ; Adds Switch value to the 128 value, (in W)
  RETURN   ; Returns with this value in W
  END   ; final statement

Assemble and compile this program and download it to the MMM board via the C2C environment. Simulate this program within the MPLAB environment and step through it to understand the code structure.  Notice how the first line of the table limits the switches pressed on PortA to a value from 0 to 15, to always stay within the range of the 16 table values.  Pay attention to the ‘OTHER’ function which is implemented from the 6th row in the table and also ‘OTHER1’ which is implemented from the 14th row of the table. 

Modify the 16 options within the table to customise the response of the microcontroller LED’s to your own patterns or preference.


Code TUTMM14.ASM

; TUTMM14.ASM - example of XOR-ing
; simply reading the 5 switches on Port A, this is then XOR-ed with B'11110010'
; and shows their status on Port B
  LIST p=16F84  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data for running the code on the MMM development board.
; PICmicro MCU type: 16F84
; Oscillator: RC mode, fast, VR1 your choice of setting
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
__CONFIG H'3FFB' ; RC mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
;
STATUS EQU H'03' ; STATUS register stored in location 03 hex
TRISA EQU H'85' ; Data Direction Register for PORTA @ 085 address
PORTA EQU H'05' ; Port A data register (PORTA at address 0x05)
TRISB EQU H'86' ; Data Direction Register for PORTB @ 086 address
PORTB EQU H'06' ; Port B data register (PORTB at address 0x06)
W EQU 0 ;
;
; ****** MAIN PROGRAM ******
  ORG 0 ; Reset Vector
  GOTO 5 ; Goto start of program
  ORG 4 ; Interrupt vector
  GOTO 5 ; Goto start of program
  ORG 5 ; Start of program memory
;
  CLRF PORTB ; Clear PORTB register - makes all Port B pins to logic 0
  PAGE1   ; access page1 of memory
  MOVLW B'00011111' ; load literal value of 1F (hex) into W
  MOVWF TRISA ; set all Port A as inputs (RA0 to RA4)
  CLRF TRISB ; clear TRISB making all Port B pins outputs (PB0 to PB7)
  PAGE0   ; back to page0 of memory
;
GETKEY MOVF PORTA,W ; read Port A, & store reading in W.
  ANDLW B'00011111' ; just read the 5 switches, RA4 to RA0
  XORLW B'11110010' ; XOR it
  MOVWF PORTB ; output result to PortB
  GOTO GETKEY ; go back to reading PortA
  END   ; final statement

This simple demo illustrates XORing. Like the previous examples this code can again be simulated within the MPLAB environment then the machine code can be downloaded to the MMM development board.

LED's LB5, LB6 and LB7 are ON all the time with this code example. Prior to pushing any buttons on PortA, LED's LB1 & LB4 are illuminated. By using XOR and B'11110010' we find that SA0 pressed switches LB0 on, SA1 pressed switches LB1 off, SA2 pressed switches LB2 on, SA3 pressed switches LB3 on and SA4 pressed switches LB4 off.


Code TUTMM15.ASM

This simple code demo illustrates more XOR-ing.

; TUTMM15.ASM - another example of XOR-ing
; simply reading the 5 switches on Port A, this is then XOR-ed with B'11110010'
; and shows their status on Port B again.
  LIST p=16F84  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data for running the code on the MMM development board.
; PICmicro MCU type: 16F84
; Oscillator: RC mode, fast, VR1 your choice of setting
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
__CONFIG H'3FFB' ; RC mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
;
STATUS EQU H'03' ; STATUS register stored in location 03 hex
TRISA EQU H'85' ; Data Direction Register for PORTA @ 085 address
PORTA EQU H'05' ; Port A data register (PORTA at address 0x05)
TRISB EQU H'86' ; Data Direction Register for PORTB @ 086 address
PORTB EQU H'06' ; Port B data register (PORTB at address 0x06)
W EQU 0 ;
Z EQU 2 ;
;
; ****** MAIN PROGRAM ******
  ORG 0 ; Reset Vector
  GOTO 5 ; Goto start of program
  ORG 4 ; Interrupt vector
  GOTO 5 ; Goto start of program
  ORG 5 ; Start of program memory
;
  CLRF PORTB ; Clear PORTB register - makes all Port B pins to logic 0
  PAGE1   ; access page1 of memory
  MOVLW B'00011111' ; load literal value of 1F (hex) into W
  MOVWF TRISA ; set all Port A as inputs (RA0 to RA4)
  CLRF TRISB ; clear TRISB making all Port B pins outputs (PB0 to PB7)
  PAGE0   ; back to page0 of memory
;
GETKEY MOVF PORTA,W ; read Port A, & store reading in W.
  ANDLW B'00011111' ; just read the 5 switches, RA4 to RA0
  XORLW B'00010010' ; XOR it
  MOVWF PORTB ; output result to PortB
  BTFSC STATUS,Z ; IS IT ZERO?
  BSF PORTB,7 ; Only when it is ZERO, set flag/LED on RB7
  GOTO GETKEY ; go back to read PortA
  END   ; final statement

Like the previous examples this code can again be simulated within the MPLAB environment then the machine code can be downloaded to the MMM development board.

LED's LB5 & LB6 are OFF all the time with this code example. Prior to pushing any buttons on PortA, LED's LB1 & LB4 are illuminated. By using XOR and B'00010010' we find that SA0 pressed switches LB0 on, SA1 pressed switches LB1 off, SA2 pressed switches LB2 on, SA3 pressed switches LB3 on and SA4 pressed switches LB4 off. LB7 lights when SA1 and SA4 are pressed simultaneously.


Code TUTMM16.ASM

This code uses the devices internal Timer register under different rates, showing an incremental count on LB3 to LB7 (from 00001XXX to 11111XXX) and prescaler-rate on LB0 to LB2 (from XXXXX000 to XXXXX111) of the 8 LEDs on PortB on the board.

; TUTMM16.ASM
; This code uses the Timer with different rates, showing count/rate on 8 LEDs.
; It uses the devices internal Timer register under different pre-scaler rates,
; showing the incrementing COUNT (on LB3 to LB7)
; and the prescaler-rate (on LB0 to LB2) of the 8 LEDs on PortB.
  LIST p=16F84  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Configuration data
; PICmicro MCU type: 16F84
; Oscillator: RC mode, fast, VR1 fully anticlockwise (min.rate)
; LCD display: off
; 7-segment display: off
; Version 2 board settings: J14 links: Digital
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
; The following line embeds configuration data into the PICmicro
__CONFIG H'3FFB' ; RC mode
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
#DEFINE PAGE0 BCF STATUS,5
#DEFINE PAGE1 BSF STATUS,5
;
OPSHUN EQU H'81' ; OPTION_REG located at address 0x81
STATUS EQU H'03' ; STATUS register located at address 0x03
PORTB EQU H'06' ; Port B data register (PORTB at address 0x06)
TRISB EQU H'86' ; Data Direction Register for PORTB @ 086 address
INTCON EQU H'0B' ; INTCON register (located at address 0x0B)
W EQU 0 ;
F EQU 1 ;
C EQU 0 ;
;
RATE EQU H'20' ; variable used to control speed of count via TMR0 pre-scaler
COUNT EQU H'21' ; general counter - user-created variable (located at 0x21)
;
;
; ****** MAIN PROGRAM ******
  ORG 0 ; Reset Vector
  GOTO 5 ; Goto start of program
  ORG 4 ; Interrupt vector
  GOTO 5 ; Goto start of program
  ORG 5 ; Start of program memory
;
  CLRF PORTB ; Clear PORTB register - makes all Port B pins to logic 0
  PAGE1   ; access page1 of memory
  CLRF TRISB ; clear TRISB making all Port B pins outputs (PB0 to PB7)
  MOVLW B'00000000' ; load literal value of 00 (hex) into W (for OPSHUN)
  MOVWF OPSHUN ; set TMR0 prescaler to 1:2 (PS2,PS1&PS0 - bit2 to bit0)
  PAGE0   ; back to page0 of memory
  CLRF RATE ; clear initial value of RATE
  MOVLW D'08' ; load the value of 00001000
  MOVWF COUNT ; into Count - to start count at bit 3.
  BCF INTCON,2 ; clear the Timer0 Interrupt flag
;
INTRPT BTFSS INTCON,2 ; Has a TMR0 Interrupt been detected?
  GOTO INTRPT ; if no - go back to Intrpt label
  BCF INTCON,2 ; if yes - Clear Timer0 Interrupt Flag
  MOVLW B'00001000' ; Load '8' into W (to add to portB)
  ADDWF PORTB,F ; add result to PortB & output
  BTFSS STATUS,C ; Is there a CARRY?
  GOTO INTRPT ; if no CARRY - go back to Intrpt label
  DECFSZ COUNT,F ; CARRY detected - decrement count and test if it is zero
  GOTO INTRPT ; Count not Zero - go back to Intrpt label
  BSF COUNT,3 ; Count IS Zero - set to 00001000 (start of count)
  INCF RATE,W ; copy & increment RATE into W
  ANDLW H'07' ; AND RATE with 00000111 in W
  MOVWF RATE ; move the value into RATE
  MOVWF PORTB ; move same value to PORTB
  PAGE1   ; move to memory bank 1
  MOVWF OPSHUN ; AND RATE with 00000111 in W
  PAGE0   ; move back to memory bank 0
  GOTO INTRPT ; - go back to Intrpt label
;
  END   ; final statement

Assemble and compile this program and download it to the MMM board via the C2C environment. Simulate this program within the MPLAB environment and step through it to understand the code structure.  This code makes use of a simple interrupt delay loop, working closely with the STATUS, INTCON and OPTION registers.  It displays the count on LB3 to LB7 (i.e 00001XXX to 11111XXX) and the prescaler value on LB0 to LB2 (i.e XXXXX000 to XXXXX111) on the PortB LED's of the MMM development board. Once you have understood how the code structure works, alter the code to make the count increment on LB0 to LB7 (i.e going from 00000000 to 11111111 on PortB), and show the prescaler value on LA0 to LA2 (i.e. from 00000 to 00111 on PortA).


[back to top]

 

Updated 20.02.08 ML

Site Search

Powered by Google
Site Map