PIC assembly switch statement

Thread Starter

levi22

Joined Mar 24, 2021
4
I am quite new to assembly programming and I am trying to create a switch statement. I was using the Microchips example but it does not seem to work in my simulation. Here is my code. It supposed to go to label2 but it skips all the conditions. Any help will be appreciated

Mod: wrapped your code in General Code insert.


Code:
MAIN

MOVLW 0X01

MOVWF CASE1

MOVLW 0X02

MOVWF CASE2

MOVLW 0X03

MOVWF CASE3

MOVLW 0X02

MOVWF SWITCH


START

movf  SWITCH, W

xorlw  CASE1

btfsc  STATUS, Z ; If SWITCH = CASE1, jump to LABEL1

goto  LABEL1

movf  SWITCH, W

xorlw  CASE2

btfsc  STATUS, Z  ; If SWITCH = CASE2, jump to LABEL2

goto  LABEL2

movf  SWITCH, W

xorlw  CASE3

btfsc  STATUS, Z  ; If SWITCH = CASE3, jump to LABEL3

goto  LABEL3



LABEL1

NOP

NOP

NOP

GOTO START


LABEL2

NOP

NOP

NOP

GOTO START


LABEL3

NOP

NOP

NOP

GOTO START
 

Sensacell

Joined Jun 19, 2012
3,098
You could also do a relative jump by adding the switch value to the program counter.

You just need to be sure your value is legal first, so you don't jump into the weeds.
 

LesJones

Joined Jan 8, 2017
3,905
You have not associated your variables with file register locations.
You can manually define them using EQU (Equate.) statements or let the assembler allocate them in sequence using the cblock command.
Your variables are CASE1, CASE2 and CASE3.

below is an example of using cblock.

Code:
;  Define GENERAL PURPOSE RAM AREA 

;*******************************************************************************
; File Register Variables
;*******************************************************************************
; Bank 0
        cblock  0x20

param1:    1          ; parameter 1    (Used in delay cycles routine)
param2:    1          ; parameter 2    (Used in delay cycles routine)

Count_L:1        ;Count of number of cycles of tone (Low byte.)
Count_H:1        ;Count of number of cycles of tone (High byte.)
Charge: 1        ; Counter for capacitor charge time.

Temp_1:    1        ;Used in 2 second delay 

tmpData:    1        ;

; delay counters
Del_Count:     1        
; byte counter
    bytcnt:     1

        endc
The first line defines the first available register location that is available. (Or that you want to use.)
In the example (Which is for a PIC12F1840) the first available register location in bank 0 is address 0x20.
You need to put a colon after the variable name and follow it with the number of bytes required by the variable. In the example all the variables are only 1 byte.

Les.
 
Code:
MAIN

MOVLW 0X01

MOVWF CASE1

MOVLW 0X02

MOVWF CASE2

MOVLW 0X03

MOVWF CASE3

MOVLW 0X02

MOVWF SWITCH


START

movf  SWITCH, W

xorlw  CASE1

btfsc  STATUS, Z ; If SWITCH = CASE1, jump to LABEL1

goto  LABEL1

movf  SWITCH, W

xorlw  CASE2

btfsc  STATUS, Z  ; If SWITCH = CASE2, jump to LABEL2

goto  LABEL2

movf  SWITCH, W

xorlw  CASE3

btfsc  STATUS, Z  ; If SWITCH = CASE3, jump to LABEL3

goto  LABEL3



LABEL1

NOP

NOP

NOP

GOTO START


LABEL2

NOP

NOP

NOP

GOTO START


LABEL3

NOP

NOP

NOP

GOTO START
Basically you are comparing the wrong values.

Code:
MOVLW 0X01
MOVWF CASE1
means move 1 to memory address case1 (not defined in your code)

Code:
movf  SWITCH, W
xorlw  CASE1
means to move the data at memory address SWITCH to W then
xor W with the memory address CASE1... not the data at the memory of address CASE1

If you want to xor the value at SWITCH with the data at address CASE1 you want to use xorwf instead. Keep in mind using xorwf can replace the data at location CASE1. Use xorwf CASE1, w to store the result in W, or xorwf CASE1, f to store the result back into the CASE1 memory location.

Basically anything instruction ending in 'lw' means the literal value after the instruction is used to modify the working register (w).
Anything ending in 'wf' means use the value in (w) to modify the contents of the memory address following the instruction.
 
Top