assembly code problem

Discussion in 'Embedded Systems and Microcontrollers' started by dr. jones, Apr 20, 2009.

  1. dr. jones

    Thread Starter New Member

    Apr 20, 2009
    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.

    Code ( (Unknown Language)):
    2.     list      p=16F684               ; list directive to define processor
    3.     #include <>            ; processor specific variable definitions
    5.     errorlevel  -302                  ; suppress message 302 from list file
    6.     errorlevel  -207                  ; suppress message 207 from list file
    9.     org 0x000
    11. ;Deklarering af konstanter          ;makes the registers for saved values
    12.     sreg0    equ 0x20
    13.     movlw   b'1001'
    14.     movwf   sreg0  
    15.     sreg1    equ    0x21
    16.     movlw   b'0101'
    17.     movwf   sreg1    
    18.     sreg2    equ    0x22
    19.     movlw   b'0011'
    20.     movwf   sreg2    
    21.     sreg3    equ    0x23
    22.     movlw   b'0001'
    23.     movwf   sreg3    
    25. ;Deklarering af variable              ;makes registers for variable values
    26.     reg0   equ    0x27
    27.     clrf     reg0
    28.     reg1   equ    0x28  
    29.     clrf     reg1
    30.     reg2   equ    0x29
    31.     clrf     reg2
    32.     reg3   equ    0x30
    33.     clrf     reg3
    34.     temp   equ   0x31
    35.     clrf     temp
    37. ;Initialisering          ;sets RA-ports to digital. RA0-RA5 til input. All RC-ports to output
    38.     bcf        STATUS,5
    39.     clrf    PORTA
    40.     movlw    0x07
    41.     movwf    CMCON0
    42.     bsf        STATUS,5
    43.     clrf    ANSEL
    44.     movlw    0x1F
    45.     movwf    TRISA
    46.     movlw    b'000000'
    47.     movwf    TRISC
    48.     bcf        STATUS,5
    49.     clrf    PORTC
    51. ;sørger for at alle porte er udgange undtaget RA    3, som skal være indgang
    53. Start                               ;tests if data available is high. If high goto Indlaes otherwise goto Start
    54.     bcf       STATUS,5
    55.     clrf       PORTC
    56.     btfsc    PORTA,4
    57.     goto     Indlaes
    58.     goto     Start
    60. Indlaes                              ;a shift register to move reg2 to reg3, reg1 to reg2, reg0 to reg1 and the new 4-bit to reg0
    61.     movf      reg2,0
    62.     movwf    reg3
    63.     movf      reg1,0
    64.     movwf    reg2
    65.     movf      reg0,0
    66.     movwf    reg1
    67.     movf      PORTA,0
    68.     movwf    reg0    
    69.     goto      Compare
    71. Compare            ;compares all reg registers with sreg registers
    72.     movf    sreg0,0
    73.     xorwf    reg0,0
    74.     movwf  temp  
    75.     btfsc    temp,0
    76.     goto     Start  
    77.     btfsc    temp,1
    78.     goto     Start  
    79.     btfsc    temp,2
    80.     goto     Start  
    81.     btfsc    temp,3
    82.     goto     Start
    84.     movf     sreg1,0
    85.     xorwf    reg1,0
    86.     movwf   temp
    87.     btfsc    temp,0
    88.     goto     Start
    89.     btfsc    temp,1
    90.     goto     Start
    91.     btfsc    temp,2
    92.     goto     Start
    93.     btfsc    temp,3
    94.     goto     Start
    96.     movf     sreg2,0
    97.     xorwf    reg2,0
    98.     movwf   temp
    99.     btfsc     temp,0
    100.     goto     Start
    101.     btfsc    temp,1
    102.     goto     Start
    103.     btfsc    temp,2
    104.     goto     Start
    105.     btfsc    temp,3
    106.     goto     Start
    108.     movf     sreg3,0
    109.     xorwf     reg3,0
    110.     movwf   temp
    111.     btfsc     temp,0
    112.     goto      Start
    113.     btfsc     temp,1
    114.     goto     Start
    115.     btfsc    temp,2
    116.     goto     Start
    117.     btfsc    temp,3
    118.     goto     Start
    119.     goto     Afbryd     ;if all four digits are correct goto Abryd
    121. Afbryd           ;sets RC0 to high. When the user press 0x0B (11 in decimal) on the keypad the code goes back to Start
    122.     bcf       STATUS,5
    123.     bsf       PORTC,0      
    124.     movf     PORTA,0
    125.     movwf   temp
    126.     movlw   0x0B
    127.     xorwf    temp,1
    128.     btfsc    temp,0      
    129.     goto     Afbryd      
    130.     btfsc    temp,1      
    131.     goto     Afbryd      
    132.     btfsc    temp,2      
    133.     goto     Afbryd      
    134.     btfsc    temp,3      
    135.     goto     Afbryd      
    137.     goto    Start
    138.     end
  2. n9352527

    AAC Fanatic!

    Oct 14, 2005
    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
  3. dr. jones

    Thread Starter New Member

    Apr 20, 2009
    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.