自己按照自己的习惯修改的,原有工程使用看门狗定时器作为tick,
自己改为Timer0——B0,留出看门狗用。
定时器定时采用ACLK,外部32Khz晶振,约5ms中断定时,采用比较定时实现。这样B1就可以留出来共其他模块使用,但是时钟源还是XT1.
这样也利于低功耗应用。
工程文件为:
tick操作
;********************************************************************************************************
; TICK ISR
;
; Description: This ISR handles tick interrupts. This ISR uses the Watchdog timer as the tick source.
;
; Notes : 1) The following C pseudo-code describes the operations being performed in the code below.
;
; Save all the CPU registers
; if (OSIntNesting == 0) {
; OSTCBCur->OSTCBStkPtr = SP;
; SP = OSISRStkPtr; /* Use the ISR stack from now on */
; }
; OSIntNesting++;
; Enable interrupt nesting; /* Allow nesting of interrupts (if needed) */
; Clear the interrupt source;
; OSTimeTick(); /* Call uC/OS-II's tick handler */
; DISABLE general interrupts; /* Must DI before calling OSIntExit() */
; OSIntExit();
; if (OSIntNesting == 0) {
; SP = OSTCBHighRdy->OSTCBStkPtr; /* Restore the current task's stack */
; }
; Restore the CPU registers
; Return from interrupt.
;
; 2) ALL ISRs should be written like this!
;
; 3) You MUST disable general interrupts BEFORE you call OSIntExit() because an interrupt
; COULD occur just as OSIntExit() returns and thus, the new ISR would save the SP of
; the ISR stack and NOT the SP of the task stack. This of course will most likely cause
; the code to crash. By disabling interrupts BEFORE OSIntExit(), interrupts would be
; disabled when OSIntExit() would return. This assumes that you are using OS_CRITICAL_METHOD
; #3 (which is the prefered method).
;
; 4) If you DON'T use a separate ISR stack then you don't need to disable general interrupts
; just before calling OSIntExit(). The pseudo-code for an ISR would thus look like this:
;
; Save all the CPU registers
; if (OSIntNesting == 0) {
; OSTCBCur->OSTCBStkPtr = SP;
; }
; OSIntNesting++;
; Enable interrupt nesting; /* Allow nesting of interrupts (if needed) */
; Clear the interrupt source;
; OSTimeTick(); /* Call uC/OS-II's tick handler */
; OSIntExit();
; Restore the CPU registers
; Return from interrupt.
;********************************************************************************************************
TIMER0_B0_ISR;WDT_ISR ; wd timer ISR
PUSHM.A #12, R15
add.w #164,&TBCCR0 ; Add offset to CCR0
BIC.W #CCIE, TBCCTL0 ; disable wd timer interrupt
CMP.B #0, &OSIntNesting ; if (OSIntNesting == 0)
JNE TIMER0_B0_ISR_1
MOVX.A &OSTCBCur, R13 ; save task stack
MOVX.A SP, 0(R13)
MOVX.A &OSISRStkPtr, SP ; load interrupt stack
TIMER0_B0_ISR_1
INC.B &OSIntNesting ; increase OSIntNesting
BIS.W #CCIE, TBCCTL0 ; enable wd timer interrupt
EINT ; enable general interrupt to allow for interrupt nesting
CALLA #OSTimeTick ; call ticks routine
DINT ; IMPORTANT: disable general interrupt BEFORE calling OSIntExit()
CALLA #OSIntExit
CMP.B #0, &OSIntNesting ; if (OSIntNesting == 0)
JNE TIMER0_B0_ISR_2
MOVX.A &OSTCBHighRdy, R13 ; restore task stack SP
MOVX.A @R13, SP
TIMER0_B0_ISR_2
POPM.A #12, R15
RETI ; return from interrupt
;********************************************************************************************************
; WD TIMER INTERRUPT VECTOR ENTRY
;
; Interrupt vectors
;********************************************************************************************************
COMMON INTVEC
; ORG WDT_VECTOR
;WDT_VEC DW WDT_ISR ; interrupt vector. Watchdog/Timer, Timer mode
ORG TIMER0_B0_VECTOR
DW TIMER0_B0_ISR ; interrupt vector. Watchdog/Timer, Timer mode
END
|