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. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    OK.
    This is the code.
    For the main loop:
    Code (text):

    main_loop:
        movf    temper,W        ; Put temperature in W
        call    bin2bcd         ; Decode Temperature to bcd
        movf    units,W         ; copy units to W
        call    decdisp_a       ; convert
        bsf     LED_CMN         ; Leds off
        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    H_keeping       ; delay 2 ms
        movf    tens,W          ; copy tens to W
        call    decdisp_a       ; convert
        bsf     DISP1           ; display 1 off
        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    H_keeping       ; delay 2 ms
        movf    hundreds,W      ; copy hundeds to W
        call    decdisp_a       ; convert
        bsf     DISP2           ; display 2 off
        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    H_keeping       ; delay 2 ms
        bsf     DISP3           ; display 3 off

        ; Leds code:
        bsf     LEDS_ON         ; Flag leds on
        bcf     LED_CMN         ; Leds on
        call    H_keeping       ; delay 2 ms

        goto    main_loop       ; Back to main loop
     
    for the housekeeping:
    Code (text):

    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     ; not enabled    ; No, get out!

        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

    ;notenabled:
        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
        bsf     leds_s,6    ; Led on/off in on
        goto    contled
    setledoff:
        bcf     leds_s,6    ; Led on/off in off

    contled:
        btfss   LEDS_ON
        goto    endleds
        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
    endleds:
        bcf     LEDS_ON


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

        bsf     STATUS,RP0  ; Bank 1
        ;bcf    STATUS,RP1  ;  "   "
        bcf     OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag

        movlw   B'00111100' ;
        movwf   TRISA       ; Make RA2, RA4, RA3 and RA5 inputs (RA3 is a sensor)
        movlw   B'11110000' ;
        movwf   TRISB       ; Make RB4, RB5, RB6 and RB7 inputs
        movlw   B'00110100' ;
        movwf   WPUA        ; Enable RA2, RA4 and RA5 pull-up internal resistors

        bcf     STATUS,RP0  ; Bank 2
        bsf     STATUS,RP1  ;  "   "
        movlw   B'11110000'
        movwf   WPUB        ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
        bsf     STATUS,RP0  ; Back to Bank 1
        bcf     STATUS,RP1  ;  "   "
        bsf     OPTION_REG,7    ; Set RABPU flag
        bcf     STATUS,RP0      ; Bank 0

        btfss   KEY_UP          ; KEY_UP pressed?
        incf    temper,F        ; Yes

        btfsc   KEY_UP          ; Key Up pressed?
        goto    $+3             ; No
        bsf     k_pressed,6     ; Yes, set flag
        goto    $+2             ; Exit
        bcf     k_pressed,6     ; No, reset flag
        btfsc   KEY_timer       ;
        goto    $+3             ;
        bsf     k_pressed,5     ;
        goto    $+2             ;
        bcf     k_pressed,5     ;
        btfsc   KEY_ONOFF       ;
        goto    $+3             ;
        bsf     k_pressed,4     ;
        goto    $+2             ;
        bcf     k_pressed,4     ;
        btfsc   KEY_LIGHT       ;
        goto    $+3             ;
        bsf     k_pressed,3     ;
        goto    $+2             ;
        bcf     k_pressed,3     ;
        btfsc   KEY_TOASTER     ;
        goto    $+3             ;
        bsf     k_pressed,2     ;
        goto    $+2             ;
        bcf     k_pressed,2     ;
        btfsc   KEY_TEMP        ;
        goto    $+3             ;
        bsf     k_pressed,1     ;
        goto    $+2             ;
        bcf     k_pressed,1     ;
        btfsc   KEY_DWN         ;
        goto    $+3             ;
        bsf     k_pressed,0     ;
        goto    $+2             ;
        bcf     k_pressed,0     ;

        bsf     STATUS,RP0      ; Bank 1
        bcf     WPUA,7
        bcf     WPUB,7
        bcf     OPTION_REG,7    ; Set RABPU flag
        movlw   B'00001000'     ;
        movwf   TRISA           ;
        movlw   B'00000000'     ;
        movwf   TRISB           ;
        bcf     STATUS,RP0      ; Bank 0

        retlw    00
     
    Now, with the correct paging for the WPUB register, the value in display continues to update while the key up is pressed, without problems.
    The flashing rate is increased (almost twice a seond, because there were the timming inside the beep routine which is gone) and we are at the limit for the counter in Led_blink file.
    Another thing: while the key is pressed and the display is being updated, the leds which were suposed to be off , blinks.
     
    Last edited: Jun 21, 2010
  2. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    1. Add a small "do-nothing" delay in housekeeping to get the blink correct and when you add more instructions to H_Keeping, you can reduce this delay.

    2. Another thing: while the key is pressed and the display is being updated, the leds which were suposed to be off , blinks.
    Which key? what update?

    3. bcf LEDS_ON ; you have to comment on each instruction because I have absolutely no idea what is happening because most of this is negative logic. And when you come back to it later, YOU won't know what is happening either.

    4. To get into bank 2 you have to set RP1 NOT RP0


     
    Last edited: Jun 21, 2010
  3. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    I will do the nop timing.

    To test the keys, I test the key_up and, if pressed, I just increment the temper file (temperature) which is updated in display during the first to third parts of SCAN.

    Code (text):

        btfss   KEY_UP          ; KEY_UP pressed?
        incf    temper,F        ; Yes
     
    Ok, I will comment more.
     
  4. dave

    Dave New Member

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


     
  5. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia

    4. To get into bank 2 you have to set RP1 NOT RP0
     
  6. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Ok, but isn't:
    RP0 RP1 BANK
    0 0 0
    0 1 1
    1 0 2
    1 1 3
    So, as I am in bank 1, if I just sets RP1, I will be in bank 3, not bank 2.

    I just added another file (aux_file) and this code to the house keeping, so, now, the display bright is ok.
    Code (text):

        decfsz  aux_file,F
        goto    $-1
     
     
    Last edited: Jun 21, 2010
  7. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Just to help, one of the leds is on, when it should be off and 2 leds (in reality all, because the others are on and you can't see), are blinking when the key up is pressed and the display is being updated.
    I have put one movie in youtube, to see what is going on.
    The lower right led should be off;
    The leds should not be blinking while the display is updated.
    You can see a small movie (6 seconds) at:
    YouTube - MVI_0893.avi
     
    Last edited: Jun 21, 2010
  8. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    1. To get in to bank 2 you have to finish with bank 1 and get back into bank then bsf RP1 your instructions were correct but your comments were wrong and that's what messed me up. GET YOUR COMMENTS CORRECT.
    2. Load aux_file with a value so you can reduce it later.
     
  9. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I don't know what LEDs should be on and what should be off, so the video is not use to me.

    Just explain clearly what is happening. It looks the display should be incremented more slowly.
     
  10. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    The leds wich should be off are the 2 in the bottom (light and toaster) and the left one (timeset).
    This can be seen in the start of the code:
    Code (text):

        movlw   B'11110001'     ; Leds initial state (led onoff blinking, up, down and temperature on)
        movwf   leds_s          ; Set leds state
     
    The display should be incremented more slowly, yes, but we need to work the debounce / autoincrement code, as you said before.
     
  11. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I need to see the full code as you have used negative logic
     
  12. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    The guy who projected the circuit used negative logic - I would never done that.
    The code is:
    Code (text):


    ;/****************************************************************************
    ;* DESCRIPTION: System definitions.
    ;*****************************************************************************/

        ERRORLEVEL -302 ;remove message about using proper bank

        LIST  P=16F677
        INCLUDE <P16F677.INC>
        __CONFIG _BOR_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

    ;/****************************************************************************
    ;* DESCRIPTION: Program variables and constant definitions.
    ;*****************************************************************************/

    temper      equ 0x20                        ; Store temperature
    units       equ 0x24                        ; units
    tens        equ 0x25                        ; tens
    hundreds    equ 0x26                        ; hundreds
    aux         equ 0x27                        ; GENERAL aux. REGISTER
    tempo0      equ 0x28
    tempo1      equ 0x29
    flags       equ 0x2B                        ; General use flags
    timer       equ 0x2D                        ; Timer register
    buz_file    equ 0x2E                        ; Buzzer file
    buz_length  equ 0x2F                        ; Buzzer length
    leds_s      equ 0x30                        ; Leds state
    k_pressed   equ 0x31                        ; Keys pressed state
    Key_deb     equ 0x32                        ; Keys debounce flag
    Key_off     equ 0x33                        ; Key off flag
    Led_blink   equ 0x34                        ; Led blink time - for debounce
    aux_file    equ 0x35                        ; timing auxiliar file

    sw_flag     equ 0x35                        ; For keys routines
    fastcount   equ 0x36                        ; For keys routines

    #define     LEDS_ON             flags,0     ; Flag to see if the leds should be on

    ; Leds
    #define     LED_CMN             PORTC,2     ; Leds Anodes

    #define     LED_UP              PORTA,4     ; Led UP
    #define     LED_timer           PORTB,6     ; Led timer
    #define     LED_TEMP            PORTB,5     ; Led TEMP
    #define     LED_DWN             PORTA,2     ; Led DWN
    #define     LED_LIGHT           PORTB,4     ; Led LIGHT
    #define     LED_TOASTER         PORTA,5     ; Led TOASTER
    #define     LED_ONOFF           PORTC,6     ; Led ONOFF
    #define     TRIS_LED_ONOFF      TRISC,6     ; Led ONOFF TRIS

    ; Displays
    #define     DISP1               PORTC,3     ; Anode display DIS0
    #define     DISP2               PORTC,4     ; Anode display DIS1
    #define     DISP3               PORTC,5     ; Anode display DIS2

    ; Keys
    #define     KEY_UP              PORTB,7     ; KEY_UP
    #define     KEY_timer           PORTB,6     ; KEY_timer
    #define     KEY_ONOFF           PORTB,5     ; KEY_ONOFF
    #define     KEY_LIGHT           PORTB,4     ; KEY_LIGHT
    #define     KEY_TOASTER         PORTA,5     ; KEY_TOASTER
    #define     KEY_TEMP            PORTA,4     ; KEY_TEMP
    #define     KEY_DWN             PORTA,2     ; KEY_DWN

    ; Buzzer
    #define     buz                 PORTC,0     ; Buzzer

    ;/****************************************************************************
    ;* DESCRIPTION: Start of program.
    ;*****************************************************************************
        ORG     0x0000
        goto    start

    ;/****************************************************************************
    ;* DESCRIPTION: Decodes value in W register to display segments for PORTA.
    ;* return:      result in W
    ;*****************************************************************************/

    decdisp_a:
        addwf   PCL,F       ; compute the jump value
                            ;   |7|6|5|4|3|2|1|0| - Bits PORTA
                            ;   |-|-|B|E|-|A|-|-|
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 0
        retlw   B'00010100' ;   |-|-|B|X|-|X|-|-| - 1
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 2
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 3
        retlw   B'00010100' ;   |-|-|B|X|-|X|-|-| - 4
        retlw   B'00110000' ;   |-|-|X|X|-|A|-|-| - 5
        retlw   B'00100000' ;   |-|-|X|E|-|A|-|-| - 6
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 7
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 8
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 9


    ;/****************************************************************************
    ;* DESCRIPTION: Decodes value in W register to display segments, for PORTB.
    ;* return:      result in W
    ;*****************************************************************************/

    decdisp_b:
        addwf   PCL,F       ; compute the jump value
                            ;   |7|6|5|4|3|2|1|0| - Bits PORTB
                            ;   |C|F|D|G|-|-|-|-| -
        retlw   B'00010000' ;   |C|F|D|X|-|-|-|-| - 0
        retlw   B'01110000' ;   |C|X|X|X|-|-|-|-| - 1
        retlw   B'11000000' ;   |X|X|D|G|-|-|-|-| - 2
        retlw   B'01000000' ;   |C|X|D|G|-|-|-|-| - 3
        retlw   B'00100000' ;   |C|F|X|G|-|-|-|-| - 4
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 5
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 6
        retlw   B'01110000' ;   |C|X|X|X|-|-|-|-| - 7
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 8
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 9

    ;/****************************************************************************
    ;* DESCRIPTION: House keeping and delay routine.
    ;*****************************************************************************/
    H_keeping:
        movlw   D'255'          ; Load W with 255 (0xFF)
        movwf   aux_file        ; Load aux_file counter with 255
        decfsz  aux_file,F      ; Decrement it untill it reaches 0
        goto    $-1             ; Keep doing till aux_file is 0

        ; 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         ; not enabled    ; No, get out!
        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:
        btfss   LEDS_ON         ; Are leds enabled? Without this, there were weird display's segments behaviour.
        goto    endleds         ; No, get out
        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
    endleds:
        bcf     LEDS_ON         ; Here, I turn on the leds anode (transistor Q6)

        ; 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
        bcf     OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag

        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)

        btfss   KEY_UP          ; KEY_UP pressed?
        incf    temper,F        ; Yes

        btfsc   KEY_UP          ; Key Up pressed?
        goto    $+3             ; No
        bsf     k_pressed,6     ; Yes, set flag
        goto    $+2             ; Exit
        bcf     k_pressed,6     ; No, reset flag
        btfsc   KEY_timer       ;
        goto    $+3             ;
        bsf     k_pressed,5     ;
        goto    $+2             ;
        bcf     k_pressed,5     ;
        btfsc   KEY_ONOFF       ;
        goto    $+3             ;
        bsf     k_pressed,4     ;
        goto    $+2             ;
        bcf     k_pressed,4     ;
        btfsc   KEY_LIGHT       ;
        goto    $+3             ;
        bsf     k_pressed,3     ;
        goto    $+2             ;
        bcf     k_pressed,3     ;
        btfsc   KEY_TOASTER     ;
        goto    $+3             ;
        bsf     k_pressed,2     ;
        goto    $+2             ;
        bcf     k_pressed,2     ;
        btfsc   KEY_TEMP        ;
        goto    $+3             ;
        bsf     k_pressed,1     ;
        goto    $+2             ;
        bcf     k_pressed,1     ;
        btfsc   KEY_DWN         ;
        goto    $+3             ;
        bsf     k_pressed,0     ;
        goto    $+2             ;
        bcf     k_pressed,0     ;
        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: binary_to_bcd - 8-bits
    ;* INPUT:       temper   - 8-bit binary number
    ;* return:      hundreds - the hundreds digit of the BCD conversion
    ;*              tens     - the tens digits of the BCD conversion
    ;*              units    - the ones digits of the BCD conversion
    ;*****************************************************************************/
    bin2bcd:

        movwf   aux             ; save the value to convert in aux
        clrf    units           ;
        clrf    tens            ;
        clrf    hundreds        ; RESET variables
        movf    aux,F           ;
        btfsc   STATUS,Z        ; Is the value to convert = 0?
        return                  ; Yes - Return
                                ; No
        incf    units,F         ; Increment unit
        movf    units,W         ;
        xorlw   0X0A            ;
        btfss   STATUS,Z        ; unit = 10d ?
        goto    $+3             ; No
                                ; yes
        clrf    units           ; Reset unit
        incf    tens,F          ; Increment tens
        movf    tens,W          ;
        xorlw   0X0A            ;
        btfss   STATUS,Z        ; Tens = 10d ?
        goto    $+3             ; No
                                ; Yes
        clrf    tens            ; Reset tens
        incf    hundreds,F      ; Increment hundreds
        decfsz  aux,F           ; End of convertion ?
        goto    $-.14           ; No - go back to continue the convertion
        return                  ; Yes

    ;/****************************************************************************
    ;* DESCRIPTION: Program Initialization
    ;*****************************************************************************/

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

        ; 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

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

    main_loop:
        movf    temper,W        ; Put temperature in W
        call    bin2bcd         ; Decode Temperature to bcd
        movf    units,W         ; copy units to W
        call    decdisp_a       ; convert
        bsf     LED_CMN         ; Leds off
        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    H_keeping       ; delay 2 ms
        movf    tens,W          ; copy tens to W
        call    decdisp_a       ; convert
        bsf     DISP1           ; display 1 off
        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    H_keeping       ; delay 2 ms
        movf    hundreds,W      ; copy hundeds to W
        call    decdisp_a       ; convert
        bsf     DISP2           ; display 2 off
        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    H_keeping       ; delay 2 ms
        bsf     DISP3           ; display 3 off

        ; Leds code:
        bsf     LEDS_ON         ; Flag leds on
        bcf     LED_CMN         ; Leds on
        call    H_keeping       ; delay 2 ms

        goto    main_loop       ; Back to main loop

        END
     
     
  13. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I have changed some of the names, re-arranged all the sub-routines and deleted some of the unnecessary code.

    Fix up the names and see my comments

    Let me know what happens


    Code (text):
    ;/****************************************************************************
    ;* System definitions.
    ;*****************************************************************************/

        ERRORLEVEL -302 ;remove message about using proper bank

        LIST  P=16F677
        INCLUDE <P16F677.INC>
        __CONFIG _BOR_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

    ;/****************************************************************************
    ;* Program variables and constant definitions.
    ;*****************************************************************************/

    temper        equ 0x20                        ; Store temperature
    units        equ 0x24                        ; units
    tens        equ    0x25                        ; tens
    hundreds    equ 0x26                        ; hundreds
    aux            equ    0x27                        ; GENERAL aux. REGISTER
    tempo0        equ    0x28
    tempo1        equ    0x29
    flags        equ    0x2B                        ; General use flags
    timer        equ    0x2D                        ; Timer register
    buz_file    equ 0x2E                        ; Buzzer file
    buz_length    equ 0x2F                        ; Buzzer length
    leds_s        equ    0x30                        ; Leds state
    k_pressed    equ    0x31                        ; Keys pressed state
    Key_deb        equ    0x32                        ; Keys debounce flag
    Key_off        equ    0x33                        ; Key off flag
    Led_blink    equ    0x34                        ; Led blink time - for debounce
    aux_file    equ    0x35                        ; extra delay in H-Keeping

    sw_flag        equ    0x35                        ; For keys
    fastcount    equ    0x36                        ; For keys

    #define        LEDS_ON                flags,0        ; Flag to see if the leds should be on

    ; Leds
    #define        LED_CMN                PORTC,2        ; Leds Anodes

    #define        LED_ON                PORTA,4        ; Led on
    #define        LED_timer            PORTB,6        ; Led timer
    #define        LED_TEMP            PORTB,5        ; Led TEMP
    #define        LED_OFF                PORTA,2        ; Led off
    #define        LED_LIGHT            PORTB,4        ; Led LIGHT
    #define        LED_TOASTER            PORTA,5        ; Led TOASTER
    #define        LED_ONOFF            PORTC,6        ; Led ONOFF
    #define        TRIS_LED_ONOFF        TRISC,6        ; Led ONOFF TRIS

    ; Displays
    #define        DISP1                PORTC,3        ; Anode display DIS0
    #define        DISP2                PORTC,4        ; Anode display DIS1
    #define        DISP3                PORTC,5        ; Anode display DIS2

    ; Keys
    #define        KEY_OFF                PORTB,7        ; KEY_UP
    #define        KEY_timer            PORTB,6        ; KEY_timer
    #define        KEY_ONOFF            PORTB,5        ; KEY_ONOFF
    #define        KEY_LIGHT            PORTB,4        ; KEY_LIGHT
    #define        KEY_TOASTER            PORTA,5        ; KEY_TOASTER
    #define        KEY_TEMP            PORTA,4        ; KEY_TEMP
    #define        KEY_ON                PORTA,2        ; KEY_DWN

    ; Piezo
    #define        piezo                    PORTC,0        ; piezo

    ;/****************************************************************************
    ;* Start of program.
    ;*****************************************************************************
        ORG        0x0000
        goto    start

    ;/****************************************************************************
    ;* Decode value in W register to display segments for PORTA.
    ;* return with  result in W
    ;*****************************************************************************/

    decdisp_a:
        addwf   PCL,F        ; compute the jump value
                            ;    |7|6|5|4|3|2|1|0| -    Bits PORTA
                            ;    |-|-|B|E|-|A|-|-|
        retlw    B'00000000'    ;    |-|-|B|E|-|A|-|-| -    0
        retlw    B'00010100'    ;    |-|-|B|X|-|X|-|-| -    1
        retlw    B'00000000'    ;    |-|-|B|E|-|A|-|-| -    2
        retlw    B'00010000'    ;    |-|-|B|X|-|A|-|-| -    3
        retlw    B'00010100'    ;    |-|-|B|X|-|X|-|-| -    4
        retlw    B'00110000'    ;    |-|-|X|X|-|A|-|-| -    5
        retlw    B'00100000'    ;    |-|-|X|E|-|A|-|-| -    6
        retlw    B'00010000'    ;    |-|-|B|X|-|A|-|-| -    7
        retlw    B'00000000'    ;    |-|-|B|E|-|A|-|-| -    8
        retlw    B'00010000'    ;    |-|-|B|X|-|A|-|-| -    9


    ;/****************************************************************************
    ;* DESCRIPTION: Decodes value in W register to display segments, for PORTB.
    ;* return:      result in W
    ;*****************************************************************************/

    decdisp_b:
        addwf   PCL,F        ; compute the jump value
                            ;    |7|6|5|4|3|2|1|0| -    Bits PORTB
                            ;    |C|F|D|G|-|-|-|-| -
        retlw    B'00010000'    ;    |C|F|D|X|-|-|-|-| -    0
        retlw    B'01110000'    ;    |C|X|X|X|-|-|-|-| -    1
        retlw    B'11000000'    ;    |X|X|D|G|-|-|-|-| -    2
        retlw    B'01000000'    ;    |C|X|D|G|-|-|-|-| -    3
        retlw    B'00100000'    ;    |C|F|X|G|-|-|-|-| -    4
        retlw    B'00000000'    ;    |C|F|D|G|-|-|-|-| -    5
        retlw    B'00000000'    ;    |C|F|D|G|-|-|-|-| -    6
        retlw    B'01110000'    ;    |C|X|X|X|-|-|-|-| -    7
        retlw    B'00000000'    ;    |C|F|D|G|-|-|-|-| -    8
        retlw    B'00000000'    ;    |C|F|D|G|-|-|-|-| -    9
       
       

    ;/****************************************************************************
    ;* Program Initialization
    ;*****************************************************************************/

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

        ; 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
        goto    main_loop
       
           

    ;/****************************************************************************
    ;* Sub-routines in Alphabetical Order
    ;*****************************************************************************/


            ; binary_to_bcd - 8-bits
            ; INPUT:        temper   - 8-bit binary number
            ; return:      hundreds - the hundreds digit of the BCD conversion
            ;                tens     - the tens digits of the BCD conversion
            ;                units    - the ones digits of the BCD conversion

    bin2bcd:

        movwf    aux                ; save the value to convert in aux
        clrf    units            ;
        clrf    tens            ;
        clrf    hundreds        ; RESET variables
        movf    aux,F            ;
        btfsc    STATUS,Z        ; Is the value to convert = 0?
        retlw    00                ; Yes - Return
                                ; No
        incf    units,F            ; Increment unit
        movf    units,W            ;
        xorlw    0X0A            ;
        btfss    STATUS,Z        ; unit = 10d ?
        goto    $+3                ; No
                                ; yes
        clrf    units            ; Reset unit
        incf    tens,F            ; Increment tens
        movf    tens,W            ;
        xorlw    0X0A            ;
        btfss    STATUS,Z        ; Tens = 10d ?
        goto    $+3                ; No
                                ; Yes
        clrf    tens            ; Reset tens
        incf    hundreds,F        ; Increment hundreds
        decfsz    aux,F            ; End of convertion ?
        goto    $-.14            ; No - go back to continue the convertion
        retlw    00                ; Yes




    H_keeping
        movlw    D'255'            ; Load W with 255 (0xFF)
        movwf    aux_file        ; Load aux_file counter with 255
        decfsz    aux_file,F        ; Decrement it untill it reaches 0
        goto    $-1                ; Keep doing till aux_file is 0

        ; 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            ; not enabled    ; No, get out!
        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:
        btfss    LEDS_ON            ; Are leds enabled? Without this, there were weird display's segments behaviour.
        goto    endleds            ; No, get out
        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
    endleds:
        bcf        LEDS_ON            ; Here, I turn on the leds anode (transistor Q6)

        ; 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
        bcf        OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag

        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
        bsf        OPTION_REG,7    ; Set RABPU flag
        bcf        STATUS,RP0        ; RP0 = 1 -> Bank 0    
       
        bsf        STATUS,RP1        ; RP1 = 0 -> "   "2
        movlw    B'11110000'        ; 1 = enable pull-up - 0 disable it.
        movwf    WPUB            ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors    
        bcf        STATUS,RP1        ; RP2 = 2 -> "   "0  

        btfss    KEY_UP            ; KEY_UP pressed?
        incf    temper,F        ; Yes
        btfsc    KEY_UP            ; Key Up pressed?
        goto    $+3                ; No
        bsf        k_pressed,6        ; Yes, set flag
        goto    $+2                ; Exit
        bcf        k_pressed,6        ; No, reset flag
        btfsc    KEY_timer        ;
        goto    $+3                ;
        bsf        k_pressed,5        ;
        goto    $+2                ;
        bcf        k_pressed,5        ;
        btfsc    KEY_ONOFF        ;
        goto    $+3                ;
        bsf        k_pressed,4        ;
        goto    $+2                ;
        bcf        k_pressed,4        ;
        btfsc    KEY_LIGHT        ;
        goto    $+3                ;
        bsf        k_pressed,3        ;
        goto    $+2                ;
        bcf        k_pressed,3        ;
        btfsc    KEY_TOASTER        ;
        goto    $+3                ;
        bsf        k_pressed,2        ;
        goto    $+2                ;
        bcf        k_pressed,2        ;
        btfsc    KEY_TEMP        ;
        goto    $+3                ;
        bsf        k_pressed,1        ;
        goto    $+2                ;
        bcf        k_pressed,1        ;
        btfsc    KEY_DWN            ;
        goto    $+3                ;
        bsf        k_pressed,0        ;
        goto    $+2                ;
        bcf        k_pressed,0        ;
        ;bsf        STATUS,RP0        ; RP0 = 1 -> Goto Bank 1 (RP1 already = 0)
       ; bcf        WPUA,7
        ;bcf        WPUB,7   ;the weak pull ups only work when INPUT
       
        bsf        STATUS,RP0        ;  0 -> 1
        bcf        OPTION_REG,7    ; Set RABPU flag  set or CLEAR?
        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        ;1 ->  Bank 0
        retlw    00


    ;/****************************************************************************
    ;* Main
    ;*****************************************************************************/

    main_loop
        movf    temper,W        ; Put temperature in W
        call    bin2bcd            ; Decode Temperature to bcd
        movf    units,W            ; copy units to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        LED_CMN            ; Leds off
        movwf    PORTA            ; put it in PORTA
        movf    units,W            ; copy units to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP1            ; display 1 on
        call    H_keeping        ; delay
       
        movf    tens,W            ; copy tens to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        DISP1            ; display 1 off
        movwf    PORTA            ; put it in PORTA
        movf    tens,W            ; copy tens to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP2            ; display 2 on
        call    H_keeping        ; delay
       
        movf    hundreds,W        ; copy hundeds to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        DISP2            ; display 2 off
        movwf    PORTA            ; put it in PORTA
        movf    hundreds,W        ; copy hundeds to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP3            ; display 3 on
        call    H_keeping        ; delay
        bsf        DISP3            ; display 3 off

        ; Leds code:
        bsf        LEDS_ON            ; Flag to turn leds on
        bcf        LED_CMN            ; clear bit 2 on PORTC to turn on LEDs    
        call    H_keeping        ; delay

        goto    main_loop        ; Back to main loop

        end
     
  14. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Exactly the same results.
    I will be back to you later because it's 01:00 AM and I have to go, at 07:00 AM to a job interview.
    When I return, I will see if I can discover something.
     
  15. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I have added the key detect sub-routines:

    Code (text):

    ;/****************************************************************************
    ;* Sub-routines in Alphabetical Order
    ;*****************************************************************************/


            ; binary_to_bcd - 8-bits
            ; INPUT:        temper   - 8-bit binary number
            ; return:      hundreds - the hundreds digit of the BCD conversion
            ;                tens     - the tens digits of the BCD conversion
            ;                units    - the ones digits of the BCD conversion

    bin2bcd:

        movwf    aux                ; save the value to convert in aux
        clrf    units            ;
        clrf    tens            ;
        clrf    hundreds        ; RESET variables
        movf    aux,F            ;
        btfsc    STATUS,Z        ; Is the value to convert = 0?
        retlw    00                ; Yes - Return
                                ; No
        incf    units,F            ; Increment unit
        movf    units,W            ;
        xorlw    0X0A            ;
        btfss    STATUS,Z        ; unit = 10d ?
        goto    $+3                ; No
                                ; yes
        clrf    units            ; Reset unit
        incf    tens,F            ; Increment tens
        movf    tens,W            ;
        xorlw    0X0A            ;
        btfss    STATUS,Z        ; Tens = 10d ?
        goto    $+3                ; No
                                ; Yes
        clrf    tens            ; Reset tens
        incf    hundreds,F        ; Increment hundreds
        decfsz    aux,F            ; End of convertion ?
        goto    $-.14            ; No - go back to continue the convertion
        retlw    00                ; Yes
       
       
       

    DelayAA

        movlw    D'255'            ; This delay increase the on-time for each segment
        movwf    aux_file        ; to improve the brightness
        decfsz    aux_file,F        ;
        goto    $-1    
        retlw    00

    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            ; not enabled    ; No, get out!
        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:
        ;btfss    LEDS_ON            ; Are leds enabled? Without this, there were weird display's segments behaviour.
        ;goto    endleds            ; No, get out
       ; btfsc    leds_s,5        ; Is led up on?
       ; goto    $+3
       ; bsf        LED_UP            ; turn LED_UP OFF
       ; goto    $+2
       ; bcf        LED_UP            ; turn LED_UP ON
       ; btfsc    leds_s,4        ; Is led down on?
       ; goto    $+3
       ; bsf        LED_DWN            ; turn LED_DWN OFF
       ; goto    $+2
       ; bcf        LED_DWN            ; turn LED_DWN ON
       ; 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
    endleds:
        bcf        LEDS_ON            ; turn on the leds anode (transistor Q6)

        ; Test_Keys (k_pressed):
        ;   7       6       5       4       3       2       1       0
        ;   X      up     timer   onoff    light   toast   temp    down
       
       
        ;Hasn't all the following been done in Set_UP?????????????

       ; bsf        STATUS,RP0        ;0 to Bank 1
       ; bcf        OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag

       ; 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
       ; bsf        OPTION_REG,7    ; Set RABPU flag
       ; bcf        STATUS,RP0        ;   1 -> Bank 0    
       
        ;bsf        STATUS,RP1        ;  0 -> "   "2
       ; movlw    B'11110000'        ; 1 = enable pull-up - 0 disable it.
       ; movwf    WPUB            ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors    
        ;bcf        STATUS,RP1        ; 2 -> "   "0
       
        ;movlw    D'255'            ; This delay increase the on-time for each segment
        ;movwf    aux_file        ; to improve the brightness
       ; decfsz    aux_file,F        ;
       ; goto    $-1  
       
       
        ;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    $+4
        btfss    k_not_pressed,6    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,6 is set, key has been released between detections)
        bcf        k_pressed,6        ; clear the KEY_UP flag
       
       
        btfsc    KEY_timer        ; When KEY_timer pressed, input=0
        goto    $+4
        btfss    k_not_pressed,5    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,5 is set, key has been released between detections)
        bcf        k_pressed,5        ; clear the KEY_timer flag
       
       
        btfsc    KEY_ONOFF        ; When KEY_ONOFF pressed, input=0
        goto    $+4
        btfss    k_not_pressed,4    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,4 is set, key has been released between detections)
        bcf        k_pressed,4        ; clear the KEY_ONOFF flag
                       
           
        btfsc    KEY_LIGHT        ; When KEY_LIGHT pressed, input=0
        goto    $+4
        btfss    k_not_pressed,3    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,3 is set, key has been released between detections)
        bcf        k_pressed,3        ; clear the KEY_LIGHT flag
                       
        btfsc    KEY_TOASTER        ; When KEY_TOASTER pressed, input=0
        goto    $+4
        btfss    k_not_pressed,2    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,2 is set, key has been released between detections)
        bcf        k_pressed,2        ; clear the KEY_TOASTER flag
       
                         
        btfsc    KEY_TEMP        ; When KEY_TEMP pressed, input=0
        goto    $+4
        btfss    k_not_pressed,1    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,1 is set, key has been released between detections)
        bcf        k_pressed,1        ; clear the KEY_TEMP flag
       
       
        btfsc    KEY_DWN            ; When KEY_DWN     pressed, input=0
        goto    $+4
        btfss    k_not_pressed,0    ;key pressed - look to see if second pressing
        goto    $+2             ;(if k_not_pressed,0 is set, key has been released between detections)
        bcf        k_pressed,0        ; clear the KEY_DWN     flag
       
       
       
       
       
        ;This routine detects if a key is released
         
        btfss    KEY_UP            ; When KEY_UP not pressed, input=1
        goto    $+2
        bsf        k_not_pressed,6        ; Yes, set flag
                       
       
        btfss    KEY_timer        ;
        goto    $+2                ;
        bsf        k_not_pressed,5        ;
       
        btfss    KEY_ONOFF        ;
        goto    $+2                ;
        bsf        k_not_pressed,4        ;
       
       
        btfss    KEY_LIGHT        ;
        goto    $+2                ;
        bsf        k_not_pressed,3        ;
       
       
        btfss    KEY_TOASTER        ;
        goto    $+2                ;
        bsf        k_not_pressed,2        ;
               
        btfss    KEY_TEMP        ;When KEY_TEMP not pressed, input=1
        goto    $+2                ;
        bsf        k_not_pressed,1        ;
               
       
       
        btfss    KEY_DWN            ;When KEY_DWN not pressed, input=1
        goto    $+2
        bsf        k_not_pressed,0    
       
       
       
        ;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            ; When KEY_UP pressed, input=0
        goto    $+3
        bsf        k_pressed,6        ; Yes, set flag
        bcf        k_not_pressed,6                    
       
        btfsc    KEY_timer        ;
        goto    $+3                ;
        bsf        k_pressed,5        ;
        bcf        k_not_pressed,5
        btfsc    KEY_ONOFF        ;
        goto    $+3                ;
        bsf        k_pressed,4        ;
        bcf        k_not_pressed,4
       
        btfsc    KEY_LIGHT        ;
        goto    $+3                ;
        bsf        k_pressed,3        ;
        bcf        k_not_pressed,3
       
        btfsc    KEY_TOASTER        ;
        goto    $+3                ;
        bsf        k_pressed,2        ;
        bcf        k_not_pressed,2        
        btfsc    KEY_TEMP        ;When KEY_TEMP pressed, input=0
        goto    $+3                ;
        bsf        k_pressed,1        ;
        bcf        k_not_pressed,1        
       
       
        btfsc    KEY_DWN            ;When KEY_DWN pressed, input=0
        goto    $+3
        bsf        k_pressed,0    
        bcf        k_not_pressed,0
       
       
        bsf        STATUS,RP0        ;  0 -> 1
        bcf        OPTION_REG,7    ; Set RABPU flag  set or CLEAR?
        movlw    B'00001000'        ;
        movwf    TRISA            ; Make A0,A1,A2,A4,A5,A6 and A7 outputs.
               
        clrf    TRISB            ; Make all PORTB output.
        bcf        STATUS,RP0        ;1 ->  Bank 0
        retlw    00


    ;/****************************************************************************
    ;* Main
    ;*****************************************************************************/

    main
        movf    temper,W        ; Put temperature in W
        call    bin2bcd            ; Decode Temperature to bcd
        movf    units,W            ; copy units to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        LED_CMN            ; Leds off
        movwf    PORTA            ; put it in PORTA
        movf    units,W            ; copy units to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP1            ; display 1 on
        call    DelayAA            ; delay
       
        movf    tens,W            ; copy tens to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        DISP1            ; display 1 off
        movwf    PORTA            ; put it in PORTA
        movf    tens,W            ; copy tens to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP2            ; display 2 on
        call    DelayAA            ; delay
       
        movf    hundreds,W        ; copy hundeds to W
        call    decdisp_a        ; turn on/off segments A,B,E
        bsf        DISP2            ; display 2 off
        movwf    PORTA            ; put it in PORTA
        movf    hundreds,W        ; copy hundeds to W
        call    decdisp_b        ; turn on/off segments C,D,F,G
        movwf    PORTB            ; put it in PORTB
        bcf        DISP3            ; display 3 on
        call    DelayAA            ; delay
        bsf        DISP3            ; display 3 off

        ; Leds code:
        bsf        LEDS_ON            ; Flag to turn leds on?????????????????
        bcf        LED_CMN            ; clear bit 2 on PORTC to turn on LEDs    
        call    H_keeping        ; detect keys and show LEDs

        goto    main            ; Back to main

        end
       
       
     
  16. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    When the pins are configured again as outputs, the pull-ups registers are cleared (page 60 of 16F677):
    "Each of the PORTA pins, except RA3, has an
    individually configurable internal weak pull-up. Control
    bits WPUAx enable or disable each pull-up. Refer to
    Register 4-4. Each weak pull-up is automatically turned
    off when the port pin is configured as an output."
     
  17. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Implemented the code you posted.
    Code (text):


    ;/****************************************************************************
    ;* DESCRIPTION: System definitions.
    ;*****************************************************************************/

        ERRORLEVEL -302 ;remove message about using proper bank

        LIST  P=16F677
        INCLUDE <P16F677.INC>
        __CONFIG _BOR_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO

    ;/****************************************************************************
    ;* DESCRIPTION: Program variables and constant definitions.
    ;*****************************************************************************/

    temper      equ 0x20                        ; Store temperature
    units       equ 0x24                        ; units
    tens        equ 0x25                        ; tens
    hundreds    equ 0x26                        ; hundreds
    aux         equ 0x27                        ; GENERAL aux. REGISTER
    tempo0      equ 0x28
    tempo1      equ 0x29
    flags       equ 0x2B                        ; General use flags
    timer       equ 0x2D                        ; Timer register
    buz_file    equ 0x2E                        ; Buzzer file
    buz_length  equ 0x2F                        ; Buzzer length
    leds_s      equ 0x30                        ; Leds state
    k_pressed   equ 0x31                        ; Keys pressed state
    Key_deb     equ 0x32                        ; Keys debounce flag
    k_not_pressed equ   0x33                    ; Key off flag
    Led_blink   equ 0x34                        ; Led blink time - for debounce
    aux_file    equ 0x35                        ; timing auxiliar file

    sw_flag     equ 0x35                        ; For keys routines
    fastcount   equ 0x36                        ; For keys routines

    #define     LEDS_ON             flags,0     ; Flag to see if the leds should be on

    ; Leds
    #define     LED_CMN             PORTC,2     ; Leds Anodes

    #define     LED_UP              PORTA,4     ; Led UP
    #define     LED_timer           PORTB,6     ; Led timer
    #define     LED_TEMP            PORTB,5     ; Led TEMP
    #define     LED_DWN             PORTA,2     ; Led DWN
    #define     LED_LIGHT           PORTB,4     ; Led LIGHT
    #define     LED_TOASTER         PORTA,5     ; Led TOASTER
    #define     LED_ONOFF           PORTC,6     ; Led ONOFF
    #define     TRIS_LED_ONOFF      TRISC,6     ; Led ONOFF TRIS

    ; Displays
    #define     DISP1               PORTC,3     ; Anode display DIS0
    #define     DISP2               PORTC,4     ; Anode display DIS1
    #define     DISP3               PORTC,5     ; Anode display DIS2

    ; Keys
    #define     KEY_UP              PORTB,7     ; KEY_UP
    #define     KEY_timer           PORTB,6     ; KEY_timer
    #define     KEY_ONOFF           PORTB,5     ; KEY_ONOFF
    #define     KEY_LIGHT           PORTB,4     ; KEY_LIGHT
    #define     KEY_TOASTER         PORTA,5     ; KEY_TOASTER
    #define     KEY_TEMP            PORTA,4     ; KEY_TEMP
    #define     KEY_DWN             PORTA,2     ; KEY_DWN

    ; Buzzer
    #define     buz                 PORTC,0     ; Buzzer

    ;/****************************************************************************
    ;* DESCRIPTION: Start of program.
    ;*****************************************************************************
        ORG     0x0000
        goto    start

    ;/****************************************************************************
    ;* DESCRIPTION: Decodes value in W register to display segments for PORTA.
    ;* return:      result in W
    ;*****************************************************************************/

    decdisp_a:
        addwf   PCL,F       ; compute the jump value
                            ;   |7|6|5|4|3|2|1|0| - Bits PORTA
                            ;   |-|-|B|E|-|A|-|-|
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 0
        retlw   B'00010100' ;   |-|-|B|X|-|X|-|-| - 1
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 2
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 3
        retlw   B'00010100' ;   |-|-|B|X|-|X|-|-| - 4
        retlw   B'00110000' ;   |-|-|X|X|-|A|-|-| - 5
        retlw   B'00100000' ;   |-|-|X|E|-|A|-|-| - 6
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 7
        retlw   B'00000000' ;   |-|-|B|E|-|A|-|-| - 8
        retlw   B'00010000' ;   |-|-|B|X|-|A|-|-| - 9


    ;/****************************************************************************
    ;* DESCRIPTION: Decodes value in W register to display segments, for PORTB.
    ;* return:      result in W
    ;*****************************************************************************/

    decdisp_b:
        addwf   PCL,F       ; compute the jump value
                            ;   |7|6|5|4|3|2|1|0| - Bits PORTB
                            ;   |C|F|D|G|-|-|-|-| -
        retlw   B'00010000' ;   |C|F|D|X|-|-|-|-| - 0
        retlw   B'01110000' ;   |C|X|X|X|-|-|-|-| - 1
        retlw   B'11000000' ;   |X|X|D|G|-|-|-|-| - 2
        retlw   B'01000000' ;   |C|X|D|G|-|-|-|-| - 3
        retlw   B'00100000' ;   |C|F|X|G|-|-|-|-| - 4
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 5
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 6
        retlw   B'01110000' ;   |C|X|X|X|-|-|-|-| - 7
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 8
        retlw   B'00000000' ;   |C|F|D|G|-|-|-|-| - 9

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

        ; 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    k_not_pressed   ; Zero Key off flag
        movlw   D'255'          ; Value to preload to
        movwf   Led_blink       ; Led blink time control
        goto    main_loop

    ;/****************************************************************************
    ;* DESCRIPTION: binary_to_bcd - 8-bits
    ;* INPUT:       temper   - 8-bit binary number
    ;* return:      hundreds - the hundreds digit of the BCD conversion
    ;*              tens     - the tens digits of the BCD conversion
    ;*              units    - the ones digits of the BCD conversion
    ;*****************************************************************************/
    bin2bcd:

        movwf   aux             ; save the value to convert in aux
        clrf    units           ;
        clrf    tens            ;
        clrf    hundreds        ; RESET variables
        movf    aux,F           ;
        btfsc   STATUS,Z        ; Is the value to convert = 0?
        return                  ; Yes - Return
                                ; No
        incf    units,F         ; Increment unit
        movf    units,W         ;
        xorlw   0X0A            ;
        btfss   STATUS,Z        ; unit = 10d ?
        goto    $+3             ; No
                                ; yes
        clrf    units           ; Reset unit
        incf    tens,F          ; Increment tens
        movf    tens,W          ;
        xorlw   0X0A            ;
        btfss   STATUS,Z        ; Tens = 10d ?
        goto    $+3             ; No
                                ; Yes
        clrf    tens            ; Reset tens
        incf    hundreds,F      ; Increment hundreds
        decfsz  aux,F           ; End of convertion ?
        goto    $-.14           ; No - go back to continue the convertion
        return                  ; Yes

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

        movlw   D'255'          ; This delay increase the on-time for each segment
        movwf   aux_file        ; to improve the brightness
        decfsz  aux_file,F      ;
        goto    $-1    
        retlw   00

    ;/****************************************************************************
    ;* 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:
        btfss   LEDS_ON         ; Are leds enabled? Without this, there were weird display's segments behaviour.
        goto    endleds         ; No, get out
        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
    endleds:
        bcf     LEDS_ON         ; Here, I turn on the leds anode (transistor Q6)

        ; 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
        bcf     OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag

        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    $+4
        btfss   k_not_pressed,6 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,6 is set, key has been released between detections)
        bcf     k_pressed,6     ; clear the KEY_UP flag

        btfsc   KEY_timer       ; When KEY_timer pressed, input=0
        goto    $+4
        btfss   k_not_pressed,5 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,5 is set, key has been released between detections)
        bcf     k_pressed,5     ; clear the KEY_timer flag

        btfsc   KEY_ONOFF       ; When KEY_ONOFF pressed, input=0
        goto    $+4
        btfss   k_not_pressed,4 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,4 is set, key has been released between detections)
        bcf     k_pressed,4     ; clear the KEY_ONOFF flag

        btfsc   KEY_LIGHT       ; When KEY_LIGHT pressed, input=0
        goto    $+4
        btfss   k_not_pressed,3 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,3 is set, key has been released between detections)
        bcf     k_pressed,3     ; clear the KEY_LIGHT flag

        btfsc   KEY_TOASTER     ; When KEY_TOASTER pressed, input=0
        goto    $+4
        btfss   k_not_pressed,2 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,2 is set, key has been released between detections)
        bcf     k_pressed,2     ; clear the KEY_TOASTER flag

        btfsc   KEY_TEMP        ; When KEY_TEMP pressed, input=0
        goto    $+4
        btfss   k_not_pressed,1 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,1 is set, key has been released between detections)
        bcf     k_pressed,1     ; clear the KEY_TEMP flag

        btfsc   KEY_DWN         ; When KEY_DWN     pressed, input=0
        goto    $+4
        btfss   k_not_pressed,0 ; key pressed - look to see if second pressing
        goto    $+2             ; (if k_not_pressed,0 is set, key has been released between detections)
        bcf     k_pressed,0     ; clear the KEY_DWN     flag

        ;This routine detects if a key is released

        btfss   KEY_UP          ; When KEY_UP not pressed, input=1
        goto    $+2
        bsf     k_not_pressed,6 ; Yes, set flag

        btfss   KEY_timer       ; When KEY_timer not pressed, input=1
        goto    $+2             ;
        bsf     k_not_pressed,5 ;

        btfss   KEY_ONOFF       ; When KEY_ONOFF not pressed, input=1
        goto    $+2             ;
        bsf     k_not_pressed,4 ;

        btfss   KEY_LIGHT       ; When KEY_LIGHT not pressed, input=1
        goto    $+2             ;
        bsf     k_not_pressed,3 ;

        btfss   KEY_TOASTER     ; When KEY_TOASTER not pressed, input=1
        goto    $+2             ;
        bsf     k_not_pressed,2 ;

        btfss   KEY_TEMP        ; When KEY_TEMP not pressed, input=1
        goto    $+2             ;
        bsf     k_not_pressed,1 ;

        btfss   KEY_DWN         ; When KEY_DWN not pressed, input=1
        goto    $+2
        bsf     k_not_pressed,0    

        ;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          ; When KEY_UP pressed, input=0
        goto    $+3
        bsf     k_pressed,6     ; Yes, set flag
        bcf     k_not_pressed,6                    

        btfsc   KEY_timer       ;
        goto    $+3             ;
        bsf     k_pressed,5     ;
        bcf     k_not_pressed,5

        btfsc   KEY_ONOFF       ;
        goto    $+3             ;
        bsf     k_pressed,4     ;
        bcf     k_not_pressed,4

        btfsc   KEY_LIGHT       ;
        goto    $+3             ;
        bsf     k_pressed,3     ;
        bcf     k_not_pressed,3

        btfsc   KEY_TOASTER     ;
        goto    $+3             ;
        bsf     k_pressed,2     ;
        bcf     k_not_pressed,2
       
        btfsc   KEY_TEMP        ;When KEY_TEMP pressed, input=0
        goto    $+3             ;
        bsf     k_pressed,1     ;
        bcf     k_not_pressed,1        

        btfsc   KEY_DWN         ;When KEY_DWN pressed, input=0
        goto    $+3
        bsf     k_pressed,0    
        bcf     k_not_pressed,0

        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_loop:
        movf    temper,W        ; Put temperature in W
        call    bin2bcd         ; Decode Temperature to bcd
        movf    units,W         ; copy units to W
        call    decdisp_a       ; convert
        bsf     LED_CMN         ; Leds off
        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
        movf    tens,W          ; copy tens to W
        call    decdisp_a       ; convert
        bsf     DISP1           ; display 1 off
        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
        movf    hundreds,W      ; copy hundeds to W
        call    decdisp_a       ; convert
        bsf     DISP2           ; display 2 off
        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:
        bsf     LEDS_ON         ; Flag leds on
        bcf     LED_CMN         ; Leds on
        call    H_keeping       ; delay 2 ms

        goto    main_loop       ; Back to main loop

        END
     
     
    Last edited: Jun 22, 2010
  18. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I understand your reasoning with this: Each weak pull-up is automatically turned
    off when the port pin is configured as an output."

    It is just the bad wording of the Microchip document.

    The pullups are available again when the pin is required as an input, if the setting has been set in Set_Up.

    You now have to create a sub-routine that detects if a flag has been set and turn on the appropriate LED.

    You were doing too many things in the one sub-routine. You were turning on a flag or turning it off in the same sub-routine.
    The flags are toggled and this toggles the LEDs.
    Also you have not changed the names of the sub-routines as per my last detailed program. The names I suggested are more suitable: Start becomes set_up and main_loop becomes Main
     
  19. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    Made the changes:
    Put the init of pull-ups in set_up:
    Code (text):

        bsf     STATUS,RP0      ; RP0 = 1 goto Bank 1
        bcf     OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag
        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

        bcf     STATUS,RP0      ; RP0 = 0
        bcf     STATUS,RP1      ; RP1 = 0 -> Back to Bank 0
     
    Renamed Start to set_up and main_loop to Main.
    Compiled and burned.
    Now, I need to test a key, to see if it works with these mods.
     
  20. colin55

    colin55 Well-Known Member

    Joined:
    Feb 14, 2009
    Messages:
    3,534
    Likes:
    82
    Location:
    Melbourne Australia
    I have also cut out a lot of coding for bsf status, RP0 RP1 etc. see my last program. It clears up all your mess.
     
  21. ssaguiar

    ssaguiar New Member

    Joined:
    Jun 7, 2010
    Messages:
    83
    Likes:
    0
    Location:
    Florianopolis, Brazil
    I had already cleaned up the House Keeping code for the bank election.
    I just forgot to clean the set_up (1 or 2 lines).
    Now, it's:
    Code (text):

    set_up:
        bcf     STATUS,RP0      ; RP0 = 0
        bsf     STATUS,RP1      ; RP1 = 1 -> Bank 2 (I need it to switch to bank2)
        clrf    ANSEL           ; digital I/O
        clrf    ANSELH          ;   "   "   "
        movlw   B'00000000'     ; To disable comparators
        movwf   CM1CON0         ; disable comparator
        movlw   B'00000000'     ; Not necessary?
        movwf   CM2CON0         ; disable 2nd comparator
        movlw   B'00000000'     ; Not necessary?
        movwf   CM2CON1         ; disable 3rd comparator
        bsf     STATUS,RP0      ; RP0 = 1
        bcf     STATUS,RP1      ; RP1 = 0 -> Bank 1 ( need it to came back from bank2)
        movlw   B'00001000'     ; RA0,RA1,RA2,RA4,RA5,RA6 and RA7 output - RA3 input
        movwf   TRISA           ; Set it
        movlw   B'00000000'     ; All PORTB output
        movwf   TRISB           ; Set it
        movlw   B'10000010'     ; RC0,RC2,RC3,RC4,RC5,RC6 output - RC1 and RC7 inputs
        movwf   TRISC           ; Set it
        bcf     STATUS,RP0      ; RP0 = 0 (removed the bcf STATUS,RP1)
        bcf     SSPCON,SSPEN    ; Disable Synchronous Serial Port
        bsf     STATUS,RP0      ; RP0 = 1 goto Bank 1
        bcf     OPTION_REG,NOT_RABPU ; Activate pull-up resistors - Clear RABPU flag
        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 -> "   " (Again, I need it to go to bank2)
        movlw   B'11110000'     ; 1 = enable pull-up - 0 disable it.
        movwf   WPUB            ; Enable RB4, RB5, RB6 and RB7 pull-up internal resistors
        bcf     STATUS,RP0      ; RP0 = 0
        bcf     STATUS,RP1      ; RP1 = 0 -> Back to Bank 0 (Again, I need it to came back from bank2)
     
    Is this good?
     

Share This Page