1
\$\begingroup\$

So, I'm very new to assembly language programming for microcontrollers.

I'm using an AVR XMega A3BU X-plained board, and I've got a program where I need to interface with 7 buttons. 3 of them are on the board, and 4 are connected to a cheap 4 button membrane keypad.

I need to debounce the switches (hardware solutions are not an option), and I've constructed the following routine to do it; I feel like it's horribly inefficient and has several design flaws, but I can't tell.

(The CPU clock is running at 32 MHz and the timer interrupt occurs every 100ms.)

C programming is not an option, I must use assembly.

Is there a better way to do this?

;------------------------------------------------------------------------------
; Timer interrupt service routine - tcf0_isr
;------------------------------------------------------------------------------
; TODO - document this routine
;------------------------------------------------------------------------------
.equ        DEBOUNCE_VALUE   =0xFF                   ;

tcf0_isr:                                       ;
            push        r16                     ;
check_ib1:                                      ;
            lds         r16,PORTE_IN            ;
            sbrs        r16,5                   ; if(ib1 is down)
            rjmp        ib1_is_down             ;   debounce ib1
            clr         r16                     ; else reset debounce counter
            sts         ib1downcnt,r16          ;       *
            jmp         check_ib2               ;       *
ib1_is_down:                                    ;
            lds         r16,ib1downcnt          ; Debounce ib1
            inc         r16                     ;       *
            sts         ib1downcnt,r16          ;       *
            cpi         r16,DEBOUNCE_VALUE      ;       *
            breq        ib1_debounced           ;       *
ib1_debounced:                                  ;       *
            call        sel_wng_pressed         ; Call ib1 handling routine
check_ib2:                                      ; Check 2nd button on board
            ; todo
check_ib3:                                      ; Check 3rd button on board
            ; and so on
check_eb1:                                      ; Check 1st external button
            ; and so on
check_eb2:                                      ; Check 2nd external button

check_eb3:                                      ; Check 3rd external button

check_eb4:                                      ; Check 4th external button
            pop         r16                     ;
            reti                                ;
;------------------------------------------------------------------------------
\$\endgroup\$
  • \$\begingroup\$ So do you read the button states just once per 100ms? Do you even need debounce then, 100ms sounds like it may be enough for the HW to sort it out on its own. Anyway for the theory you may check my answer on SO: stackoverflow.com/a/47440366/4271923 And don't write code for each button separately, I mean the debounce logic. Each button needs only the state extraction separate, and action-handler separate, everything between can be general code reused for every button, just operating on different instance of button data. \$\endgroup\$ – Ped7g Jan 28 '18 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.