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

Pic debounce routine

Discussion in 'Microcontrollers' started by ssaguiar, Jun 7, 2010.

  1. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    You haven't cleaned up set_up. Just use the following for bank selection:

    bcf SSPCON,SSPEN ; Disable Synchronous Serial Port which bank is this in???????????????

    Code (text):
    set_up
        ;bcf        STATUS,RP0        ; RP0 = 0
        bsf        STATUS,RP1        ; 0 -> Bank 2
        clrf    ANSEL            ; digital I/O
        clrf    ANSELH            ;    "    "    "
        ;movlw    B'00000000'        ; To disable comparators
        clrf    CM1CON0            ; disable comparator
        ;movlw    B'00000000'        ; Not necessary?
        clrf    CM2CON0            ; disable 2nd comparator
        ;movlw    B'00000000'        ; Not necessary?
        clrf    CM2CON1            ; disable 3rd comparator
        bcf        STATUS,RP1        ; 2 -> Bank 0
        bsf        STATUS,RP0        ; 0 to 1
        movlw    B'00001000'        ; RA0,RA1,RA2,RA4,RA5,RA6 and RA7 output - RA3 input
        movwf    TRISA            ;
        ;movlw    B'00000000'        ;
        clrf    TRISB            ; All PORTB output
        movlw    B'10000010'        ; RC0,RC2,RC3,RC4,RC5,RC6 output - RC1 and RC7 inputs
        movwf    TRISC            ; Set it
        bcf        STATUS,RP0        ; 1 to bank 0
        ;bcf        STATUS,RP1        ; RP1 = 0 -> Bank 0
        bcf        SSPCON,SSPEN    ; Disable Synchronous Serial Port   which bank is this in???????????????

        ; Turn off all displays and leds
        bsf        LED_CMN            ; Leds off
        bsf        DISP1            ; Display1 off
        bsf        DISP2            ; Display2 off
        bsf        DISP3            ; Display3 off
        movlw    D'180'            ; Init temperature with 180 degrees Celsius
        movwf    temper            ; Put it in temper file
        movlw    D'40'            ; Start timer with 40 minutes
        movwf    timer            ; Put it in timer file
        clrf    units            ; Clear dislay's files
        clrf    tens            ;
        clrf    hundreds        ;
        movlw    D'255'
        movwf    buz_length        ; Buzzer initial duration
        movlw    B'11110001'        ; Leds initial state (led onoff blinking, up, down and temperature on)
        movwf    leds_s            ; Set leds state
        clrf    k_pressed        ; Zero keys pressed state
        clrf    Key_deb            ; Zero Keys debounce flag
        clrf    Key_off            ; Zero Key off flag
        movlw    D'255'            ; Value to preload to
        movwf    Led_blink        ; Led blink time control
        clear the "key pressed" flag file
        clear the "not pressed" flag file
        goto    main
       
           
     
    Last edited: Jun 22, 2010
  2. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    For the 16F677, the SSPCON register is in bank0, as stated in page 20 of manual, so:
    Code (text):

        bcf     STATUS,RP0      ; RP0 = 0 (removed the bcf STATUS,RP1 - I was n page 1 before)
        bcf     SSPCON,SSPEN    ; Disable Synchronous Serial Port
            bsf     STATUS,RP0      ; RP0 = 1 goto Bank 1
     
    is correct, isn't?
     
  3. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    Show the full program and include the sub-routine to turn the LEDs on and off
     
  4. dave

    Dave New Member

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


     
  5. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil

    The full program is in post #98
    I will work in the sub-routine to turn leds on/off and will put all the program here again.
     
  6. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    There is nothing on post #98

    Before you provide any sort of message like this, test the result.

    This is exactly the same thing I am trying to impress on you with writing the program.
     
  7. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Can you, please, explain the theory of your code?
    Can't get to understand how it works.

    Thanks
     
  8. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    Which code?
     
  9. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    The keys code.
     
  10. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I have already explained how they work in the program.

    All you have to do is match up each flag with turning on a particular LED. It could not be easier.
     
  11. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    First of all:
    Without this code inside he keys rutine, the keys detection will not work. I tested it with and without (the Microchip manual is correct):
    Code (text):

        movlw   B'00110100'     ; 1 = enable pull-up - 0 disable it.
        movwf   WPUA            ; Enable RA2, RA4 and RA5 pull-up internal resistors
        bcf     STATUS,RP0      ; RP0 = 0 -> Bank 2
        bsf     STATUS,RP1      ; RP1 = 1 -> "   "
        movlw   B'11110000'     ; 1 = enable pull-up - 0 disable it.
        movwf   WPUB            ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
        bsf     STATUS,RP0      ; RP0 = 1 -> Back to Bank 1
        bcf     STATUS,RP1      ; RP1 = 0 -> "   "
        bsf     OPTION_REG,7    ; Set RABPU flag
     
    Second:
    I have put the code to only detect the keypress of KEY_UP and KEY_DWN, so it's easier to follow.
    Case the KEY_UP is pressed, the temperature (temper file) is increased (this works).
    Case the KEY_DWN is pressed, the temperature was suposed to decrease, but isn't (this don't work).
    Code (text):


        ;This section has a number of sub-routines to detect a key press, set a flag and turn on a LED
        ;This routine detects if a key is pressed for the second
        ;time so that a LED can be turned off. It does this by detecting the
        ;key is pressed and looking to see if the "not-pressed" flag has been
        ;set to indicate the key has been released between detections.

        btfsc   KEY_UP          ; When KEY_UP pressed, input=0
        goto    $+5             ; Not pressed, goto exit (l1)...
        btfss   k_not_pressed,6 ; key pressed - look to see if second pressing
        goto    $+3             ; (if k_not_pressed,6 is set, key has been released between detections)
        bcf     k_pressed,6     ; clear the KEY_UP flag
        incf    temper,F        ; increment temperature

        btfsc   KEY_DWN         ; When KEY_UP pressed, input=0
        goto    $+5             ; Not pressed, goto exit (l1)...
        btfss   k_not_pressed,0 ; key pressed - look to see if second pressing
        goto    $+3             ; (if k_not_pressed,6 is set, key has been released between detections)
        bcf     k_pressed,0     ; clear the KEY_UP flag
        decf    temper,F        ; decrement temperature

        ;This routine detects if a key is released

        btfss   KEY_UP          ; Was the key released? When KEY_UP not pressed, input=1
        goto    $+2             ; No, it's still being pressed...
        bsf     k_not_pressed,6 ; Key is not pressed, set flag "not pressed"

        btfss   KEY_DWN         ; Was the key released? When KEY_UP not pressed, input=1
        goto    $+2             ; No, it's still being pressed...
        bsf     k_not_pressed,0 ; Key is not pressed, set flag "not pressed"

        ;This routine just detects if a key is pressed.
        ;If a key is pressed, it will set the corresponding flag
        ;Another routine will detect that the key has been released.
        ;and other routine will deal with doing something will the "key-pressed" flag.
        ;and another routine will deal with turning off the "key-pressed" flag.
        ;clear the flags file in start_up

        btfsc   KEY_UP          ; Is KEY_UP pressed, then input=0
        goto    $+3             ; No, it's not pressed, exit...
        bsf     k_pressed,6     ; Yes, it's pressed, set flag
        bcf     k_not_pressed,6 ; Clear the flag which indicates the key as not pressed.

        btfsc   KEY_DWN         ; Is KEY_UP pressed, then input=0
        goto    $+3             ; No, it's not pressed, exit...
        bsf     k_pressed,0     ; Yes, it's pressed, set flag
        bcf     k_not_pressed,0 ; Clear the flag which indicates the key as not pressed.
     
    Files are being ini in setup as:
    Code (text):

        clrf    k_pressed       ; Zero keys pressed state
        clrf    Key_deb         ; Zero Keys debounce flag
        clrf    k_not_pressed   ; Set Key off flag (all keys not pressed)
     
    In he case of file k_not_pressed I had before made this:
    Code (text):

    movlw     D'11111111'
    movw     k_not_pressed
     
    But it seems not make any diference.
     
  12. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    For the KEY_UP routine, put decf temper, f instead of incf temper,f to see if it works
     
  13. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Just tested as you asked and it works. The temperature in display decrements ok.
     
  14. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Just in case, there is all the code attached.
     

    Attached Files:

  15. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    Something is wrong with the circuit if the KEY_DWN does not work.
     
  16. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    There's no problem with the circuit.
    When I disable the leds, in main loop as this:
    Code (text):

        ; Leds code:
        bsf     LEDS_ON         ; Flag leds on
        bsf     LED_CMN         ; Turn off the leds anode (transistor Q6)
        call    DelayAA         ; delay
        call    H_keeping       ; delay 2 ms

     
    The up and down keys work fine.
    It seems that all problem is with leds timing.
     
    Last edited: Jun 23, 2010
  17. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Let's do this: as I already lost this service (job), I wish continue to learn to program this aplication.
    I will change this processor and make a test board.
    I will use the PIC18F4620, so it's easier to port this software to any other pic.
    Do you agree on helping to make this work using this aproach?
    Thanks
     
  18. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I cannot help you with PIC18F4620
     
  19. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Ok, anyway, thank you.
     
  20. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    For those who continue to follow this thread:
    The problem with the keys not being read was really related to the leds/displays timing.
    After having modified the sequence of leds/displays a little bit, all keys are working now.
    The code of house keeping and main are now:
    Code (text):

    ;/****************************************************************************
    ;* DESCRIPTION: House keeping and delay routine.
    ;*****************************************************************************/
    H_keeping:

        ; Leds:
        ;   7       6       5       4       3       2       1       0
        ; blink   onoff     up     down   light    toast   time    temp

        btfss   leds_s,7        ; Is led blink enabled?
        goto    contled         ; No, it's not enabled
        btfsc   leds_s,6        ; Is led on/off on?
        goto    $+3
        bcf     LED_ONOFF       ; No - it's activated directly, not using LED_CMN
        goto    $+2
        bsf     LED_ONOFF       ; Yes - it's activated directly, not using LED_CMN

        decfsz  Led_blink,F     ; Blink control = 0?
        goto    contled         ; No
        movlw   D'255'          ; Value to preload to
        movwf   Led_blink       ; Led blink time control
        btfsc   leds_s,6        ; Is led on/off on?
        goto    setledoff       ; Yes, turn it off.
        bsf     leds_s,6        ; No, turn it on
        goto    contled         ; Continue
    setledoff:
        bcf     leds_s,6        ; Led on/off in off
    contled:
        btfsc   leds_s,5        ; Is led up on?
        goto    $+3
        bsf     LED_UP          ; No
        goto    $+2
        bcf     LED_UP          ; Yes
        btfsc   leds_s,4        ; Is led down on?
        goto    $+3
        bsf     LED_DWN         ; No
        goto    $+2
        bcf     LED_DWN         ; Yes
        btfsc   leds_s,3        ; Is led light on?
        goto    $+3
        bsf     LED_LIGHT       ; No
        goto    $+2
        bcf     LED_LIGHT       ; Yes
        btfsc   leds_s,2        ; Is led toast on?
        goto    $+3
        bsf     LED_TOASTER     ; No
        goto    $+2
        bcf     LED_TOASTER     ; Yes
        btfsc   leds_s,1        ; Is led time on?
        goto    $+3
        bsf     LED_timer       ; No
        goto    $+2
        bcf     LED_timer       ; Yes
        btfsc   leds_s,0        ; Is led temp on?
        goto    $+3
        bsf     LED_TEMP        ; No
        goto    $+2
        bcf     LED_TEMP        ; YES

        ; Test_Keys (k_pressed):
        ;   7       6       5       4       3       2       1       0
        ;   X      up     timer   onoff    light   toast   temp    down

        bsf     STATUS,RP0      ; RP0 = 1 goto Bank 1
        movlw   B'00111100'     ; 0 = output - 1 = input
        movwf   TRISA           ; Make RA2, RA4, RA3 and RA5 inputs (RA3 is a sensor)
        movlw   B'11110000'     ; 0 = output - 1 = input
        movwf   TRISB           ; Make RB4, RB5, RB6 and RB7 inputs
        movlw   B'00110100'     ; 1 = enable pull-up - 0 disable it.
        movwf   WPUA            ; Enable RA2, RA4 and RA5 pull-up internal resistors
        bcf     STATUS,RP0      ; RP0 = 0 -> Bank 2
        bsf     STATUS,RP1      ; RP1 = 1 -> "   "
        movlw   B'11110000'     ; 1 = enable pull-up - 0 disable it.
        movwf   WPUB            ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
        bsf     STATUS,RP0      ; RP0 = 1 -> Back to Bank 1
        bcf     STATUS,RP1      ; RP1 = 0 -> "   "
        bsf     OPTION_REG,7    ; Set RABPU flag
        bcf     STATUS,RP0      ; RP0 = 0 -> Back to Bank 0 (RP1 already = 0)

        ;==================================================================================

        ;This section has a number of sub-routines to detect a key press, set a flag and turn on a LED
        ;This routine detects if a key is pressed for the second
        ;time so that a LED can be turned off. It does this by detecting the
        ;key is pressed and looking to see if the "not-pressed" flag has been
        ;set to indicate the key has been released between detections.

        btfsc   KEY_UP          ; When KEY_UP pressed, input=0
        goto    $+5             ; Not pressed, goto exit (l1)...
        btfss   k_not_pressed,6 ; key pressed - look to see if second pressing
        goto    $+3             ; (if k_not_pressed,6 is set, key has been released between detections)
        bcf     k_pressed,6     ; clear the KEY_UP flag
        incf    temper,F        ; increment temperature

        btfsc   KEY_DWN         ; When KEY_UP pressed, input=0
        goto    $+5             ; Not pressed, goto exit (l1)...
        btfss   k_not_pressed,0 ; key pressed - look to see if second pressing
        goto    $+3             ; (if k_not_pressed,6 is set, key has been released between detections)
        bcf     k_pressed,0     ; clear the KEY_UP flag
        decf    temper,F        ; decrement temperature

        ;This routine detects if a key is released

        btfss   KEY_UP          ; Was the key released? When KEY_UP not pressed, input=1
        goto    $+2             ; No, it's still being pressed...
        bsf     k_not_pressed,6 ; Key is not pressed, set flag "not pressed"

        btfss   KEY_DWN         ; Was the key released? When KEY_UP not pressed, input=1
        goto    $+2             ; No, it's still being pressed...
        bsf     k_not_pressed,0 ; Key is not pressed, set flag "not pressed"

        ;This routine just detects if a key is pressed.
        ;If a key is pressed, it will set the corresponding flag
        ;Another routine will detect that the key has been released.
        ;and other routine will deal with doing something will the "key-pressed" flag.
        ;and another routine will deal with turning off the "key-pressed" flag.
        ;clear the flags file in start_up

        btfsc   KEY_UP          ; Is KEY_UP pressed, then input=0
        goto    $+3             ; No, it's not pressed, exit...
        bsf     k_pressed,6     ; Yes, it's pressed, set flag
        bcf     k_not_pressed,6 ; Clear the flag which indicates the key as not pressed.

        btfsc   KEY_DWN         ; Is KEY_UP pressed, then input=0
        goto    $+3             ; No, it's not pressed, exit...
        bsf     k_pressed,0     ; Yes, it's pressed, set flag
        bcf     k_not_pressed,0 ; Clear the flag which indicates the key as not pressed.

        ;==================================================================================

        bsf     STATUS,RP0      ; RP0 = 1 -> Goto Bank 1 (RP1 already = 0)
        bcf     WPUA,7
        bcf     WPUB,7
        bcf     OPTION_REG,7    ; Set RABPU flag
        movlw   B'00001000'     ;
        movwf   TRISA           ; Make A0,A1,A2,A4,A5,A6 and A7 outputs.
        movlw   B'00000000'     ;
        movwf   TRISB           ; Make all PORTB output.
        bcf     STATUS,RP0      ; RP0 = 0 -> Back to Bank 0 (RP1 already = 0)
        retlw    00

    ;/****************************************************************************
    ;* DESCRIPTION: Main Program
    ;*****************************************************************************/

    Main:
        movf    temper,W        ; Put temperature in W
        call    bin2bcd         ; Decode Temperature to bcd

        movf    units,W         ; copy units to W
        call    decdisp_a       ; convert
        movwf   PORTA           ; put it in PORTA
        movf    units,W         ; copy units to W
        call    decdisp_b       ; convert
        movwf   PORTB           ; put it in PORTA
        bcf     DISP1           ; display 1 on
        call    DelayAA         ; delay
        call    H_keeping       ; delay 2 ms
        bsf     DISP1           ; display 1 off

        movf    tens,W          ; copy tens to W
        call    decdisp_a       ; convert
        movwf   PORTA           ; put it in PORTA
        movf    tens,W          ; copy tens to W
        call    decdisp_b       ; convert
        movwf   PORTB           ; put it in PORTA
        bcf     DISP2           ; display 2 on
        call    DelayAA         ; delay
        call    H_keeping       ; delay 2 ms
        bsf     DISP2           ; display 2 off

        movf    hundreds,W      ; copy hundeds to W
        call    decdisp_a       ; convert
        movwf   PORTA           ; put it in PORTA
        movf    hundreds,W      ; copy hundeds to W
        call    decdisp_b       ; convert
        movwf   PORTB           ; put it in PORTA
        bcf     DISP3           ; display 3 on
        call    DelayAA         ; delay
        call    H_keeping       ; delay 2 ms
        bsf     DISP3           ; display 3 off

        ; Leds code:
        call    H_keeping       ; delay 2 ms
        bcf     LED_CMN         ; Turn on the leds anode (transistor Q6)
        call    DelayAA         ; delay
        bsf     LED_CMN         ; Turn off the leds

        goto    Main            ; Back to main loop

        END
     
    I will continue to post any progress I have, here because it's important to learn and share.
    The knowledge is one of most important things and we need to share our victories and defeats, so we can always continue to learn with these.
    I have lost the service but not the desire to solve this.

    Sergio
     
  21. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    This is the latest version of oven.asm.
    It uses timer1 interrupt to handle displays and leds and uses timer0 interrupt to handle key.
    This is the best way to make it work.
    See the up and down keys routnes, where I implemented debounce and 2 levels of autoincrement for these keys (one normal - twice per second - and, after this, a turbo one - 10 times a second).

    Sergio
     

    Attached Files:

Share This Page