assembly code problem

Thread Starter

dr. jones

Joined Apr 20, 2009
2
Hi there.
I'm working on a project where I try to programm a PIC16f684 with som assembly codes.
I send a digit and a data available signal from a 74c922 encoder.
It recieves a 4-bit signal on the ports RA0-RA3 and the data available on RA4
Then the pic should collect and save the digits in registers (reg0,reg1,reg2,reg3)and compare them with saved values in other registers (sreg0,sreg1,sreg2,sreg3).
If all four digits are correct the RC0 goes high.

the code works fine if only 2 digits are used no matter if it is the first or last registers are used.
I tried to test with some LEDs where the error was and I think it is burried inside the Compare part. But as a new programmer in assemby I can't figure out the error.
If anyone could look at the code it would be really appreciated.

Rich (BB code):
    list      p=16F684               ; list directive to define processor
    #include <p16F684.inc>            ; processor specific variable definitions

    errorlevel  -302                  ; suppress message 302 from list file
    errorlevel  -207                  ; suppress message 207 from list file

    __CONFIG    _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF
    org 0x000

;Deklarering af konstanter          ;makes the registers for saved values
    sreg0    equ 0x20
    movlw   b'1001'
    movwf   sreg0  
    sreg1    equ    0x21
    movlw   b'0101'
    movwf   sreg1     
    sreg2    equ    0x22
    movlw   b'0011'
    movwf   sreg2     
    sreg3    equ    0x23
    movlw   b'0001'
    movwf   sreg3     
   
;Deklarering af variable              ;makes registers for variable values
    reg0   equ    0x27
    clrf     reg0
    reg1   equ    0x28   
    clrf     reg1
    reg2   equ    0x29
    clrf     reg2
    reg3   equ    0x30
    clrf     reg3
    temp   equ   0x31
    clrf     temp

;Initialisering          ;sets RA-ports to digital. RA0-RA5 til input. All RC-ports to output
    bcf        STATUS,5
    clrf    PORTA
    movlw    0x07
    movwf    CMCON0
    bsf        STATUS,5
    clrf    ANSEL
    movlw    0x1F
    movwf    TRISA
    movlw    b'000000'
    movwf    TRISC
    bcf        STATUS,5
    clrf    PORTC
       
;sørger for at alle porte er udgange undtaget RA    3, som skal være indgang

Start                               ;tests if data available is high. If high goto Indlaes otherwise goto Start
    bcf       STATUS,5
    clrf       PORTC
    btfsc    PORTA,4
    goto     Indlaes
    goto     Start

Indlaes                              ;a shift register to move reg2 to reg3, reg1 to reg2, reg0 to reg1 and the new 4-bit to reg0
    movf      reg2,0
    movwf    reg3 
    movf      reg1,0
    movwf    reg2 
    movf      reg0,0
    movwf    reg1 
    movf      PORTA,0
    movwf    reg0    
    goto      Compare

Compare            ;compares all reg registers with sreg registers
    movf    sreg0,0
    xorwf    reg0,0 
    movwf  temp   
    btfsc    temp,0
    goto     Start  
    btfsc    temp,1
    goto     Start  
    btfsc    temp,2
    goto     Start  
    btfsc    temp,3
    goto     Start
   
    movf     sreg1,0
    xorwf    reg1,0
    movwf   temp
    btfsc    temp,0
    goto     Start
    btfsc    temp,1
    goto     Start
    btfsc    temp,2
    goto     Start
    btfsc    temp,3
    goto     Start 
       
    movf     sreg2,0
    xorwf    reg2,0
    movwf   temp
    btfsc     temp,0
    goto     Start
    btfsc    temp,1
    goto     Start
    btfsc    temp,2
    goto     Start
    btfsc    temp,3
    goto     Start
       
    movf     sreg3,0
    xorwf     reg3,0
    movwf   temp
    btfsc     temp,0
    goto      Start
    btfsc     temp,1
    goto     Start
    btfsc    temp,2
    goto     Start
    btfsc    temp,3
    goto     Start
    goto     Afbryd     ;if all four digits are correct goto Abryd

Afbryd           ;sets RC0 to high. When the user press 0x0B (11 in decimal) on the keypad the code goes back to Start
    bcf       STATUS,5
    bsf       PORTC,0       
    movf     PORTA,0
    movwf   temp
    movlw   0x0B
    xorwf    temp,1
    btfsc    temp,0       
    goto     Afbryd       
    btfsc    temp,1       
    goto     Afbryd       
    btfsc    temp,2       
    goto     Afbryd       
    btfsc    temp,3       
    goto     Afbryd       

    goto    Start
    end
 

n9352527

Joined Oct 14, 2005
1,198
The compare code seems alright, although not really efficient. I suggest using a mask when reading the PORTA in Indlaes code, something like:

movf PORTA, W
andlw 0x0F ; ----> make sure that upper nibble is zero
movwf reg0

This will make sure that the upper nibbles of regX are zero. Then to compare the value, simply use:

movf sreg0, W
xorwf reg0, W ;----> results in zero if equal
btfss STATUS, Z ;----> test result for zero (equal)
goto Start ;----> not zero (not equal)
...... ;----> zero (equal), next compare (reg1 and so on)

Another thing that caught my attention is, how long is the data available signal is asserted on RA4? Because, if the processing is faster than the the time it takes the RA4 to go low, then the data would be read twice. This creates a problem where no match will ever be found.

It is better to test RA4, and make sure it is low after reading the data and before processing. Insert this code after Indlaes and before Compare:

btfsc PORTA, 4
goto $ - 1 ;---> goto previous instruction
 

Thread Starter

dr. jones

Joined Apr 20, 2009
2
First of all thank you for looking at my code.
I had lessons today where I changed the compare part to something similiar to your suggestion. I got the same thought about the data available signal today and made some code that checked if the key had been released. But I didn't know about the goto $ - 1, which is very useful and saved me some lines of coding and made it all more logic.
The mask-function is smart to ensure the correct number is read.

Again, thank you for your time.
 
Top