2

16 ビット デバイスの組み込みアプリケーションに関するヘルプを探しています。関数ポインターを介していくつかの単純な「タスク/関数」を実行する必要があります。これらのタスクは、あらかじめ決められた間隔で実行されます。

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++;
}

経過時間を計算する方法はありますか?時間がオーバーフローした場合に % (モジュロ) が定義されたレートで機能することを確認する方法。とにかく、時間のオーバーフローを回避し、% (モジュロ) を介して正しいタイミングを得るにはどうすればよいですか?

4

2 に答える 2

2

これは、小さな MCU アプリケーションに適した、MISRA-C 準拠の、私の非常によく似たアプリのコードです。これは、呼び出し元アプリでの静的な「ソフトウェア タイマー」の割り当てに基づいています。プロジェクト内の複数のモジュールが同じタイマー モジュールを使用できます。これは、リンクされたリストを内部で使用してすべてのタイマーを追跡しているためです。

1ms 割り込みから tim_traverse_timers() を呼び出します。非常に高い精度が要求される場合は、関数を呼び出す前に割り込みソースをクリアして、関数自体からの「コード ジッター」オーバーヘッドがタイマーに影響を与えないようにする必要があります。

65535 ミリ秒よりも長い遅延が必要な場合は、カウンターと間隔を 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);
  ...


}
于 2011-02-16T13:49:49.400 に答える
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;
     }
  }
}

これは、a) ロールオーバー時間の半分 (0x8000 ミリ秒) を超える期間がなく、b) 最短期間内にすべての機能を実行できることを保証できる限り機能するはずです。

于 2011-02-16T18:33:16.690 に答える