1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

XOR Function with 2 pushbuttons and an LED(assembly project)

Discussion in 'Microcontrollers' started by Cantafford, Sep 28, 2016.

  1. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2
    Ok last thread I will do today I swear.

    I'm trying to implement an XOR function in assembly. I have two push buttons. If they are in different positions(one pressed one not pressed) the led will light up. Otherwise the LED will stay off.

    This is how I connected them:
    [​IMG]

    And this is the code I wrote:
    Code (text):

    #include "p16F870.inc"

    ; CONFIG
    ; __config 0xFF3A
     __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_ALL


    RES_VECT  CODE    0x0000            ; processor reset vector
        GOTO    MAIN                  ; go to beginning of program

    ; TODO ADD INTERRUPTS HERE IF USED

    MAIN_PROG CODE                      ; let linker place main program

    MAIN

        BANKSEL ADCON1    ;(RA0 and RA1 are digital)
        movlw b'00000111'
        movwf ADCON1
       
        movlw b'00000011' ;buttons(RA0, RA1 are inputs)
        movwf TRISA
       
        movlw b'11111100' ;leds(RB0, RB1 are outputs)
        movwf TRISB
       
        BANKSEL PORTB ; leds are initially off
        clrf PORTB
       
         
        btfss PORTA, RA0 ;check if button on RA0 is pressed | 'f' is '0', the next instruction is executed
        goto FirstButtonPressed
        goto FirstButtonNotPressed
       
       
        GOTO MAIN  
       
        FirstButtonNotPressed ;RA0 = 1
        btfss PORTA, RA1  ;If RA1 = 0 execute next instruction else skip
        bsf PORTB, RB0
        bcf PORTB, RB0
        return
       
        FirstButtonPressed ;RA0 = 0
        btfss PORTA, RA1 ;If RA1 = 0 execute next instruction else skip
        bcf PORTB, RB0
        bsf PORTB, RB0
        return

        END
     
    My program won't run as expected. If I press button on RA0 the LED lights up no matter what position button on RA1 is on. Please help me correct this if possible. Thank you.
     
  2. upand_at_them

    upand_at_them Member

    Joined:
    Apr 23, 2005
    Messages:
    609
    Likes:
    8
    Location:
    Pennsylvania, U.S.
    If you are using RETURN then you have to use CALL to get there, not GOTO.

    When you use GOTO the program counter is not pushed onto the stack. So the next RETURN is disastrous.

    Read:
    http://tutor.al-williams.com/pic-inst.html

    Then we can talk about switch bouncing/debouncing.
     
  3. upand_at_them

    upand_at_them Member

    Joined:
    Apr 23, 2005
    Messages:
    609
    Likes:
    8
    Location:
    Pennsylvania, U.S.
    Also, it's not good practice to set pins as inputs that aren't actually connected to anything. (Your RB2 through RB7.) These floating pins can cause problems. It's much better to set unused pins as outputs.

    Which means you might as well set TRISC to b'00000000' as well.
     
    • Like Like x 1
    • Agree Agree x 1
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,142
    Likes:
    907
    Location:
    Rochdale UK
    ONLINE

    Also... No superloop... This means initializing every cycle...
     
    • Like Like x 1
  6. Rich D.

    Rich D. Member

    Joined:
    Feb 3, 2014
    Messages:
    191
    Likes:
    13
    Location:
    West Chester, PA
    ONLINE
    You know, they make 74HC32 chips that have FOUR of these circuits for only 32 cents each. And they produce the output in about 6 nanoseconds with no programming or debugging!

    (Just Kidding) I know this is about learning, I just couldn't stop myself. Maybe it's because Halloween is coming.


    To avoid re-initializing every time, I would put GOTO something right before this line instead of GOTO MAIN.

    That way it repeats the input pin test and adjusts the outputs but will not keep re initializing the I/O pins. I guess that's what Ian is referring to as the superloop.
     
  7. Jon Wilder

    Jon Wilder Active Member

    Joined:
    Oct 22, 2010
    Messages:
    859
    Likes:
    82
    Location:
    Fresno, CA
    First off...there is no such thing as "input" or "output" mode. That's just Microchip's abstract way of explaining it.

    Clearing a TRIS bit enables the output drivers. When enabled, the pin can only be internally driven to one of two possible states...high or low.

    Setting a TRIS bit disables the output drivers. When disabled and not externally driven, the pin is in a 3rd state...or "tristate"...which is a high impedance state...basically disconnected (TRIS is actually short for TRISTATE).

    This means the pin can be treated as an input as its externally driven state can be read from the PORT register files. However, by placing a pull up resistor on the pin, it now works as an open drain output with a weak pull up. Writing a 0 to the pins port latch allows the pin to be pulled low when clearing it's corresponding TRIS bit, while being pulled high by the weak pull up when setting its TRIS bit.

    This information allows you to do some clever programming that will make the pin behave as an open drain output.
     
    Last edited: Sep 28, 2016
  8. dougy83

    dougy83 Well-Known Member

    Joined:
    May 18, 2008
    Messages:
    2,672
    Likes:
    215
    Location:
    Brisbane, Australia
    Is there any reason you don't just use the built-in XORWF instruction? e.g.
    Code (text):
    movfw PORTA
    movwf temp
    rrf temp,w
    xorwf temp
    The LSb of temp will now be RA0 XOR RA1
     
  9. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2
    I just started learning assembly. I'm doing this as an exercise.
     
  10. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2
    Ok. Got it. I have modified the code like this:

    Code (text):

    #include "p16F870.inc"

    ; CONFIG
    ; __config 0xFF3A
     __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_ALL


    RES_VECT  CODE    0x0000            ; processor reset vector
        GOTO    MAIN                  ; go to beginning of program

    ; TODO ADD INTERRUPTS HERE IF USED

    MAIN_PROG CODE                      ; let linker place main program

    MAIN

        BANKSEL ADCON1    ;(RA0 and RA1 are digital)
        movlw b'00000111'
        movwf ADCON1
       
        movlw b'00000011' ;buttons(RA0, RA1 are inputs)
        movwf TRISA
       
        movlw b'00000000' ;leds(RB0, RB1 are outputs)
        movwf TRISB
       
        BANKSEL PORTB ; leds are initially off
        clrf PORTB
         
        loop
        btfss PORTA, RA0 ;check if button on RA0 is pressed | 'f' is '0', the next instruction is executed
        goto FirstButtonPressed
        goto FirstButtonNotPressed
       
       
        FirstButtonNotPressed ;RA0 = 1
        btfss PORTA, RA1  ;If RA1 = 0 execute next instruction else skip
        bsf PORTB, RB1
        bcf PORTB, RB1
        goto loop
       
        FirstButtonPressed ;RA0 = 0
        btfss PORTA, RA1 ;If RA1 = 0 execute next instruction else skip
        bcf PORTB, RB1
        bsf PORTB, RB1
        goto loop

        END
     
    Now the simulation behaves as this:

    If both switches are not pressed the LED stays off(good).
    If I press switch on RA0 the LED lights up(good).
    If I press switch on RA1 the LED flashes real fast(not good, it should be on).
    If I press both switches the LED flashes real fast(just like when I press RA1 only. Again not good).

    :(
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,142
    Likes:
    907
    Location:
    Rochdale UK
    ONLINE
    Looky here.... test and skip.... if RA0 = 1 then bcf POTRB,RB1...

    THEN!!! if RA0 = 0 it sets RB1 THEN!! clears it!!!
    Code (asm):

        FirstButtonNotPressed ;RA0 = 1
        btfss PORTA, RA1  ;If RA1 = 0 execute next instruction else skip
        bsf PORTB, RB1
        bcf PORTB, RB1
        goto loop
     


    Code (asm):


    #include "p16F870.inc"

    ; CONFIG
    ; __config 0xFF3A
     __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _CP_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _WRT_ALL


    RES_VECT  CODE    0x0000            ; processor reset vector
        GOTO    MAIN                  ; go to beginning of program

    ; TODO ADD INTERRUPTS HERE IF USED

    MAIN_PROG CODE                      ; let linker place main program

    MAIN

        BANKSEL ADCON1    ;(RA0 and RA1 are digital)
        movlw b'00000111'
        movwf ADCON1
       
        movlw b'00000011' ;buttons(RA0, RA1 are inputs)
        movwf TRISA
       
        movlw b'00000000' ;leds(RB0, RB1 are outputs)
        movwf TRISB
       
        BANKSEL PORTB ; leds are initially off
        clrf PORTB
         
        loop
        btfss PORTA, RA0 ;check if button on RA0 is pressed | 'f' is '0', the next instruction is executed
        goto FirstButtonPressed
        goto FirstButtonNotPressed
       
       
        FirstButtonNotPressed ;RA0 = 1
        btfss PORTA, RA1  ;If RA1 = 0 execute next instruction else skip
        goto on1
        bsf PORTB, RB1
        goto loop
    on1
        bcf PORTB, RB1
        goto loop
       
        FirstButtonPressed ;RA0 = 0
        btfss PORTA, RA1 ;If RA1 = 0 execute next instruction else skip
        goto on2
        bcf PORTB, RB1
        goto loop
    on2
        bsf PORTB, RB1
        goto loop

        END
     
    Now only one will be executed!!
     
    • Like Like x 1
  12. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2
    Thanks it works now.
     

Share This Page