| ; 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.
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.
| ; 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.
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.
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).
Updated 20.02.08 ML
Powered by Google
Site Map