2011-02-16 2 views
2

나는 16bit 장치에 묻힌 신청에 도움을 찾고있다. 함수 포인터를 통해 몇 가지 간단한 "작업/함수"를 실행해야합니다. 이러한 작업은 미리 정해진 간격으로 실행됩니다.시간을 잰 업무 명부

typedef struct 
{ 
    int timeToRun; 
    void (*fcn)(void); 

} task_t; 

task_t tasks[] = 
{ 
    { 13_MSEC, fcn1 }, 
    { 50_MSEC, fcn2 }, 
    { 0, NULL } 
}; 

volatile unsigned int time; 

main() 
{ 

    for (ptr = tasks; ptr->timeToRun !=0; ptr++) 
    { 
    if (!(time % ptr->timeToRun)) 
     (ptr->fcn)(); 
    } 
} 

1ms에서 타이머 인터럽트를 실행할 수 있습니다.

interrupt void TimerTick(void) 
{ 
time++; 
} 

경과 시간을 계산하는 방법에 대해 알고 싶습니다. 시간이 초과되면 확률로 % (모듈러)가 작동하는지 확인하는 방법. 어쨌든 시간 오버플로를 방지하고 % (모듈로)를 통해 정확한 타이밍을 유지하는 방법은 무엇입니까?

답변

0

나는 이런 식으로 뭔가 할 것 :

typedef struct 
{ 
    unsigned int nextRunTime 
    int period; 
    unsigned int rollover; 
    void (*fcn)(void); 
} task_t; 


main() 
{ 
    //setup goes here 
    /*...*/ 
    //loop 
    while (1) 
    { 
    for (ptr = tasks; ptr->period!=0; ptr++) 
    { 
     if ((time > ptr->nextRunTime) && (time <= ptr->rollover)) 
     { 
      ptr->nextRunTime+=ptr->period; 
      ptr->rollover = (ptr->nextRunTime < ptr->period)? 2*ptr->period : 0xFFFF; 
      (ptr->fcn)(); 
     } 
     ptr->nextRunTime = timeToRun; 
    } 
    } 
} 

이만큼 당신이) 어떤 기간이 절반 롤오버 시간 이상 없음을 보장 할 수있는 작업을해야을 (0x8000을 ms), b) 최단 기간 내에 모든 기능을 실행할 수 있습니다.

2

다음은 작은 MCU 애플리케이션에 적합한 내 유사한 애플리케이션의 일부 코드이며 MISRA-C 규격입니다. 이것은 호출하는 응용 프로그램에서 정적으로 "소프트웨어 타이머"할당을 기반으로합니다. 프로젝트의 여러 모듈은 모든 타이머를 추적하기 위해 내부적으로 연결된 목록을 사용하므로 동일한 타이머 모듈을 사용할 수 있습니다.

1ms 인터럽트에서 tim_traverse_timers()를 호출하십시오. 매우 높은 정확도의 요구 사항이있는 경우 함수를 호출하기 전에 인터럽트 소스를 지워야하므로 함수 자체의 "코드 지터"오버 헤드가 타이머에 영향을주지 않습니다.

지연 시간이 65535ms 이상인 경우 카운터와 간격을 uint32로 변경하면됩니다.

typedef struct timer 
    { 
     struct timer* next;       /* Next timer in the linked list */ 

     uint16 counter;        /* 16-bit timer counter   */ 
     uint16 interval;        /* The interval between triggers */ 
     BOOL is_enabled;        /* Timer enabled/disabled   */ 

     void (*callback_func)(void);     /* Callback timer function   */ 

    } Timer; 



    static Timer* timer_list; 


    void tim_init (void) 
    { 
     timer_list = NULL; 
    } 

    void tim_add (Timer* timer, 
        void (* callback_func)(void), 
        uint16 interval_ms, 
        BOOL  enabled) 
    { 
     tim_enable_interrupt (FALSE);     /* hardware function disabling timer interrupt */ 

     timer->callback_func = callback_func; 
     timer->counter  = 0U; 
     timer->interval  = interval_ms; 
     timer->is_enabled  = enabled; 

     timer->next   = timer_list; 
     timer_list   = timer; 

     tim_enable_interrupt (TRUE); 
    } 



    void tim_enable (Timer* timer, BOOL enable) 
    { 
     if(enable) 
     { 
     timer->counter = 0U;      /* Reset counter each time function is called */ 
     } 

     timer->is_enabled = enable; 
    } 

    void tim_traverse_timers (void) 
    { 
     Timer* timer; 

     for(timer=timer_list; timer!=NULL; timer=timer->next) 
     { 
     if(timer->is_enabled == TRUE) 
     { 
      timer->counter++; 

      if(timer->counter == timer->interval) 
      { 
      timer->counter = 0U; 
      timer->callback_func(); 
      } 

     } 
     } 
    } 

#include "timer.h" 

void my_func (void); /* lights some LED etc... */ 
void my_other_func (void); 

void main (void) 
{ 
    Timer some_task; 
    Timer some_other_task; 
    ... 

    tim_init(); 
    ... 

    tim_add(&some_task, &my_func, SOME_DELAY_IN_MS, TRUE); 
    tim_add(&some_other_task, &my_other_func, SOME_OTHER_DELAY_IN_MS, TRUE); 
    ... 


} 
+0

+1 타이머 구조체 내용입니다. – Sparky

관련 문제