Soft timers

demiurg1978's picture
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Type: 

Compiler/Assembler: 

      soft_timers.h:

 

//========================================================================
#ifndef SOFT_TIMERS_H

#define SOFT_TIMERS_H

#include "soft_timers.h"

#include "main_def_func.h"
//========================================================================

//========================================================================
// Выбор: с прерыванием или с опросом флага OCFx.
#define __ST_NO_INTERRUPT__ // __ST_NO_INTERRUPT__ // __ST_INTERRUPT__

// Состав структуры: bool status, u08 sys_tick_prev, u16 cnt, u16 period.
// Итого 6 байтов на один программный таймер. Если убрать элемент period,
// то теперь будет 4 байта на таймер.
#define __ST_PERIOD__ // __ST_PERIOD__ // __ST_NO_PERIOD__
//========================================================================

//========================================================================
#define ST_TCNT         TCNT2
#define ST_TIMSK        TIMSK
#define ST_OCIE         OCIE2
#define ST_OCR          OCR2
#define ST_TCCR         TCCR2
#define CS0             CS20
#define CS1             CS21
#define CS2             CS22
//========================================================================

//========================================================================
typedef struct soft_timer
{
   bool status;
   u08 sys_tick_prev;
   u16 cnt;       // Counter.

#ifdef __ST_PERIOD__
   u16 period;    // Period.
#endif
} soft_timer;
//========================================================================

//========================================================================
void init_soft_timers (void);

#define handle_soft_timer(a) _handle_soft_timer (&a)
bool _handle_soft_timer (soft_timer *ptr_timer);

#ifdef __ST_PERIOD__
#define set_soft_timer(a,b,c) _set_soft_timer (&a, b, c)
void _set_soft_timer (soft_timer *ptr_timer, u16 time, u16 period);
#endif

#ifdef __ST_NO_PERIOD__
#define set_soft_timer(a,b) _set_soft_timer (&a, b)
void _set_soft_timer (soft_timer *ptr_timer, u16 time);
#endif

#define reset_soft_timer(a) _reset_soft_timer (&a)
void _reset_soft_timer (soft_timer *ptr_timer);

void proc_sys_tick (void);
//========================================================================

#endif

 

soft_timer.c:

 

//========================================================================
// Реализация программных таймеров.
// Примечание. Важно!!!!!!!!!!!!!!!
// При смене состояния конечного автомата нужно сбросить
// все таймеры, которые используются в этом состоянии. Иначе может быть
// следующая ситуация: если таймер уже использовался в
// текущем состоянии и флаг EN установлен, то по окончании времени
// выполнится соответствующий код.
//--------------------- Пример использования -----------------------------
// set_soft_timer (ST_LED_2_BLINK, 50, 50); // Установка таймера.
// if (handle_soft_timer (ST_LED_2_BLINK))  // Проверка таймера.
//========================================================================

//========================================================================
#include "soft_timers.h"
//========================================================================

//========================================================================
static u08 sys_tick;
//========================================================================

//========================================================================
#ifdef __ST_INTERRUPT__
#pragma vector = TIMER2_COMP_vect
__interrupt void SysTimerComp (void)
{
   ST_OCR += 250;
   sys_tick++;
}
#endif
//========================================================================

//========================================================================
void init_soft_timers (void)
{
   sys_tick = 0;
   ST_TCNT = 0;
   ST_OCR = 250;
   ST_TCCR |= (1<<CS2);

#ifdef __ST_INTERRUPT__
   set_bit (ST_TIMSK, ST_OCIE);
#endif
}
//------------------------------------------------------------------------
#ifdef __ST_PERIOD__
void _set_soft_timer (soft_timer *ptr_timer, u16 time, u16 period)
#else
void _set_soft_timer (soft_timer *ptr_timer, u16 time)
#endif
{
   ptr_timer -> status = true;

   if (time == 0)
      ptr_timer -> sys_tick_prev = ~sys_tick;
   else
      ptr_timer -> sys_tick_prev = sys_tick;

   ptr_timer -> cnt = time;

#ifdef __ST_PERIOD__
   ptr_timer -> period = period;
#endif
}
//------------------------------------------------------------------------
bool _handle_soft_timer (soft_timer *ptr_timer)
{
   if (ptr_timer -> status)
   {
      if (ptr_timer -> sys_tick_prev != sys_tick)
      {
         ptr_timer -> sys_tick_prev = sys_tick;

         if (ptr_timer -> cnt == 0)
         {
            #ifdef __ST_PERIOD__
            if (ptr_timer -> period != 0)
               ptr_timer -> cnt = ptr_timer -> period;
            #endif

            return true;
         }
         else
         {
            ptr_timer -> cnt--;

            if (ptr_timer -> cnt == 0)
            {
               #ifdef __ST_PERIOD__
               if (ptr_timer -> period == 0)
                  ptr_timer -> status = false;
               else
                  ptr_timer -> cnt = ptr_timer -> period;
               #else
               ptr_timer -> status = false;
               #endif

               return true;
            }
         }
      }
   }

   return false;
}
//------------------------------------------------------------------------
void _reset_soft_timer (soft_timer *ptr_timer)
{
   ptr_timer -> status = false;
   ptr_timer -> sys_tick_prev = 0;
   ptr_timer -> cnt = 0;

#ifdef __ST_PERIOD__
   ptr_timer -> period = 0;
#endif
}
//------------------------------------------------------------------------
#ifdef __ST_NO_INTERRUPT__
void proc_sys_tick (void)
{
   static u08 _proc_sys_tick;

   switch (_proc_sys_tick)
   {
      case 0:
         init_soft_timers ();
         _proc_sys_tick = 1;
         break;

      case 1:
         if (TIFR & (1<<OCF2))
         {
            TIFR = (1<<OCF2);
            ST_OCR += 250;
            sys_tick++;
         }
         break;
   }
}
#endif
//========================================================================

 

//************************************************************************
// Example of the using
//************************************************************************


static u08 _proc_led_2;

soft_timer ST_LED_2_BLINK;

// Immediate execution
case 0:
   set_soft_timer (ST_LED_2_BLINK, 0, 50);
   _proc_led_2 = 1;
   break;

case 1:
   if (handle_soft_timer (ST_LED_2_BLINK))
   {

   }
   break;

// Execution after the specified time
case 0:
   set_soft_timer (ST_LED_2_BLINK, 50, 50);
  _proc_led_2 = 1;
   break;

case 1:
   if (handle_soft_timer (ST_LED_2_BLINK))
   {

   }
   break;

// Other
case 0:
   set_soft_timer (ST_LED_2_BLINK, 1000, 50);
  _proc_led_2 = 1;
   break;

case 1:
   if (handle_soft_timer (ST_LED_2_BLINK))
   {

   }
   break;

 

//========================================================================
#include "proc_device.h"
//========================================================================

//========================================================================
void proc_device (void)
{
   static u08 _proc_device;

   switch (_proc_device)
   {
      case 0: // Блок инициализации.
         #ifdef __ST_PERIOD__
         set_proc_led_1_run ();
         set_proc_led_2_run ();
         set_proc_led_3_run ();
         set_proc_led_4_run ();
         set_proc_led_5_run ();
         set_proc_led_6_run ();
         set_proc_led_7_run ();
         set_proc_led_8_run ();
         #endif

         _proc_device = 1;
         break;

      case 1:
         #ifdef __ST_PERIOD__
         proc_led_1 ();
         proc_led_2 ();
         proc_led_3 ();
         proc_led_4 ();
         proc_led_5 ();
         proc_led_6 ();
         proc_led_7 ();
         proc_led_8 ();
         #else
         led_1_blink ();
         led_2_blink ();
         led_3_blink ();
         led_4_blink ();
         led_5_blink ();
         led_6_blink ();
         led_7_blink ();
         led_8_blink ();
         #endif
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_1;

static soft_timer ST_PROC_LED_1;
static soft_timer ST_PROC_LED_2;
static soft_timer ST_PROC_LED_3;
static soft_timer ST_PROC_LED_4;
static soft_timer ST_PROC_LED_5;
static soft_timer ST_PROC_LED_6;
static soft_timer ST_PROC_LED_7;
static soft_timer ST_PROC_LED_8;

void set_proc_led_1_run (void)
{
   led_1_off ();
   _proc_led_1 = 1;
}

void set_proc_led_1_off (void)
{
   led_1_off ();
   _proc_led_1 = 0;
}

void proc_led_1 (void)
{
   switch (_proc_led_1)
   {
      case 0:
         break; // Idle.

      case 1:
         #ifdef __ST_PERIOD__
         set_soft_timer (ST_PROC_LED_1, 0, 10);
         #else
         set_soft_timer (ST_PROC_LED_1, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         #endif
         _proc_led_1 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_1))
         {
            if (!(LED_1_DDR & (1<<LED_1)))
               led_1_on ();
            else
               led_1_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_2;

void set_proc_led_2_run (void)
{
   led_2_off ();
   _proc_led_2 = 1;
}

void set_proc_led_2_off (void)
{
   led_2_off ();
   _proc_led_2 = 0;
}

void proc_led_2 (void)
{
   switch (_proc_led_2)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_2, 0, 10);
         set_soft_timer (ST_PROC_LED_2, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_2 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_2))
         {
            if (!(LED_2_DDR & (1<<LED_2)))
               led_2_on ();
            else
               led_2_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_3;

void set_proc_led_3_run (void)
{
   led_3_off ();
   _proc_led_3 = 1;
}

void set_proc_led_3_off (void)
{
   led_3_off ();
   _proc_led_3 = 0;
}

void proc_led_3 (void)
{
   switch (_proc_led_3)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_3, 0, 10);
         set_soft_timer (ST_PROC_LED_3, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_3 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_3))
         {
            if (!(LED_3_DDR & (1<<LED_3)))
               led_3_on ();
            else
               led_3_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_4;

void set_proc_led_4_run (void)
{
   led_4_off ();
   _proc_led_4 = 1;
}

void set_proc_led_4_off (void)
{
   led_4_off ();
   _proc_led_4 = 0;
}

void proc_led_4 (void)
{
   switch (_proc_led_4)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_4, 0, 10);
         set_soft_timer (ST_PROC_LED_4, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_4 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_4))
         {
            if (!(LED_4_DDR & (1<<LED_4)))
               led_4_on ();
            else
               led_4_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_5;

void set_proc_led_5_run (void)
{
   led_5_off ();
   _proc_led_5 = 1;
}

void set_proc_led_5_off (void)
{
   led_5_off ();
   _proc_led_5 = 0;
}

void proc_led_5 (void)
{
   switch (_proc_led_5)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_5, 0, 10);
         set_soft_timer (ST_PROC_LED_5, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_5 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_5))
         {
            if (!(LED_5_DDR & (1<<LED_5)))
               led_5_on ();
            else
               led_5_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_6;

void set_proc_led_6_run (void)
{
   led_6_off ();
   _proc_led_6 = 1;
}

void set_proc_led_6_off (void)
{
   led_6_off ();
   _proc_led_6 = 0;
}

void proc_led_6 (void)
{
   switch (_proc_led_6)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_6, 0, 10);
         set_soft_timer (ST_PROC_LED_6, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_6 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_6))
         {
            if (!(LED_6_DDR & (1<<LED_6)))
               led_6_on ();
            else
               led_6_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_7;

void set_proc_led_7_run (void)
{
   led_7_off ();
   _proc_led_7 = 1;
}

void set_proc_led_7_off (void)
{
   led_7_off ();
   _proc_led_7 = 0;
}

void proc_led_7 (void)
{
   switch (_proc_led_7)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_7, 0, 10);
         set_soft_timer (ST_PROC_LED_7, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_7 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_7))
         {
            if (!(LED_7_DDR & (1<<LED_7)))
               led_7_on ();
            else
               led_7_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
static u08 _proc_led_8;

void set_proc_led_8_run (void)
{
   led_8_off ();
   _proc_led_8 = 1;
}

void set_proc_led_8_off (void)
{
   led_8_off ();
   _proc_led_8 = 0;
}

void proc_led_8 (void)
{
   switch (_proc_led_8)
   {
      case 0:
         break; // Idle.

      case 1:
//         set_soft_timer (ST_PROC_LED_8, 0, 10);
         set_soft_timer (ST_PROC_LED_8, 0); // !!!!!!!!!!!!!!!!!!!!!!!!!!!
         _proc_led_8 = 2;
         break;

      case 2:
         if (handle_soft_timer (ST_PROC_LED_8))
         {
            if (!(LED_8_DDR & (1<<LED_8)))
               led_8_on ();
            else
               led_8_off ();
         }
         break;
   }
}
//========================================================================

//========================================================================
void led_1_blink (void)
{
   if (!(LED_1_DDR & (1<<LED_1)))
   {
      set_bit (LED_1_DDR, LED_1);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_1, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_1, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_1))
   {
      if (!(LED_1_PORT & (1<<LED_1)))
         led_1_on ();
      else
         led_1_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_1, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_2_blink (void)
{
   if (!(LED_2_DDR & (1<<LED_2)))
   {
      set_bit (LED_2_DDR, LED_2);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_2, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_2, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_2))
   {
      if (!(LED_2_PORT & (1<<LED_2)))
         led_2_on ();
      else
         led_2_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_2, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_3_blink (void)
{
   if (!(LED_3_DDR & (1<<LED_3)))
   {
      set_bit (LED_3_DDR, LED_3);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_3, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_3, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_3))
   {
      if (!(LED_3_PORT & (1<<LED_3)))
         led_3_on ();
      else
         led_3_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_3, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_4_blink (void)
{
   if (!(LED_4_DDR & (1<<LED_4)))
   {
      set_bit (LED_4_DDR, LED_4);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_4, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_4, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_4))
   {
      if (!(LED_4_PORT & (1<<LED_4)))
         led_4_on ();
      else
         led_4_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_4, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_5_blink (void)
{
   if (!(LED_5_DDR & (1<<LED_5)))
   {
      set_bit (LED_5_DDR, LED_5);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_5, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_5, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_5))
   {
      if (!(LED_5_PORT & (1<<LED_5)))
         led_5_on ();
      else
         led_5_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_5, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_6_blink (void)
{
   if (!(LED_6_DDR & (1<<LED_6)))
   {
      set_bit (LED_6_DDR, LED_6);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_6, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_6, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_6))
   {
      if (!(LED_6_PORT & (1<<LED_6)))
         led_6_on ();
      else
         led_6_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_6, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_7_blink (void)
{
   if (!(LED_7_DDR & (1<<LED_7)))
   {
      set_bit (LED_7_DDR, LED_7);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_7, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_7, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_7))
   {
      if (!(LED_7_PORT & (1<<LED_7)))
         led_7_on ();
      else
         led_7_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_7, 10);
      #endif
   }
}
//------------------------------------------------------------------------
void led_8_blink (void)
{
   if (!(LED_8_DDR & (1<<LED_8)))
   {
      set_bit (LED_8_DDR, LED_8);

      #ifdef __ST_PERIOD__
      set_soft_timer (ST_PROC_LED_8, 0, 10);
      #else
      set_soft_timer (ST_PROC_LED_8, 0);
      #endif
   }

   if (handle_soft_timer (ST_PROC_LED_8))
   {
      if (!(LED_8_PORT & (1<<LED_8)))
         led_8_on ();
      else
         led_8_off ();

      #ifdef __ST_NO_PERIOD__
      set_soft_timer (ST_PROC_LED_8, 10);
      #endif
   }
}
//========================================================================