Keil Logo

RTX51 TINY: Hardware Timer Interrupt fails


Information in this article applies to:

  • C51 Version 7
  • RTX51 Tiny Version 2

QUESTION

I'm using the RTX Tiny kernel on an Analog Devices ADuC834 MicroConverter. I have added the following hardware timer interrupt code to the CONF_TNY.A51 configuration file:

;------------------------------------------------------------------------------
;
;  USER CODE FOR 8051 HARDWARE TIMER INTERRUPT
;  ===========================================
;
;  The following macro defines the code executed on a hardware timer interrupt.
;
;  Define instructions executed on a hardware timer interrupt.
EXTRN           XDATA (us_value)
HW_TIMER_CODE   MACRO
                USING   0       ; Registerbank 0 for following code

                PUSH    AR6
                PUSH    ACC
                        ; test if null
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                MOV     R6,A
                INC     DPTR
                MOVX    A,@DPTR
                ORL     A,R6
                JZ      HW_TIMER_CODE_END
                        ; us_value --;
                MOVX    A,@DPTR
                ADD     A,#0FFH
                MOVX    @DPTR,A
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                ADDC    A,#0FFH
                MOVX    @DPTR,A
HW_TIMER_CODE_END:
                                ; End of Macro by default
                POP     ACC
                POP     AR6
                RETI
                ENDM

I am using the simulator to verify my code behavior. Everything seems to work correctly (several timer interruption calls with the correct behavior) however, from time to time, the value of us_value is changed when the program exits for RTX_TNY call.

What can be the reason for this problem?

ANSWER

The hardware interrupt code needs to save all modified registers. You need to PUSH and POP the following registers that are altered in your code: DPL, DPH (=DPTR), PSW (required for Carry flag that is modified by ADDC). When you change your code as follows, everything should work fine:

HW_TIMER_CODE   MACRO
                USING   0       ; Registerbank 0 for following code

                PUSH    DPL
                PUSH    DPH
                PUSH    PSW
                PUSH    AR6
                PUSH    ACC
                        ; test if null
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                MOV     R6,A
                INC     DPTR
                MOVX    A,@DPTR
                ORL     A,R6
                JZ      HW_TIMER_CODE_END
                        ; us_value --;
                MOVX    A,@DPTR
                ADD     A,#0FFH
                MOVX    @DPTR,A
                MOV     DPTR,#us_value
                MOVX    A,@DPTR
                ADDC    A,#0FFH
                MOVX    @DPTR,A
HW_TIMER_CODE_END:
                                ; End of Macro by default
                POP     ACC
                POP     AR6
                POP     PSW
                POP     DPH
                POP     DPL
                RETI
                ENDM

If you are in doubt, you should write the interrupt service routine with the C51 Compiler and copy the generated assembler instructions (i.e. generated with the SRC directive) to the CONF_TNY.A51 file.

MORE INFORMATION

SEE ALSO


Last Reviewed: Thursday, February 25, 2021


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.