Например TDA7294

Форум РадиоКот • Просмотр темы - Пример программных таймеров для AVR
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Вт апр 16, 2024 18:54:18

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 2 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Пример программных таймеров для AVR
СообщениеДобавлено: Ср мар 06, 2024 08:27:33 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 141
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1384
Рейтинг сообщения: 0
Выкладываю пример программных таймеров для AVR. Использую эти таймеры уже несколько лет в своих проектах. Примечание. Подходят скорее для автоматного программирования.

soft_timer.h
Спойлер
Код:
//==================

#ifndef SOFT_TIMERS_H

#define SOFT_TIMERS_H

#include "soft_timers.h"

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

//==================
// Выбор: с прерыванием или с опросом флага OCFx.
#define __ST_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__
//==================

//==================
#ifdef __IOTINY13_H
#define ST_TCNT         TCNT0
#define ST_TIMSK        TIMSK0
#define ST_OCIE         OCIE0A
#define ST_OCR          OCR0A
#define ST_TCCR         TCCR0B
#define ST_CS0          CS00
#define ST_CS1          CS01
#define ST_CS2          CS02

#define ST_TIFR         TIFR0
#define ST_OCF          OCF0A
#endif

#ifdef __IOTINY13A_H
#define ST_TCNT         TCNT0
#define ST_TIMSK        TIMSK0
#define ST_OCIE         OCIE0A
#define ST_OCR          OCR0A
#define ST_TCCR         TCCR0B
#define ST_CS0          CS00
#define ST_CS1          CS01
#define ST_CS2          CS02

#define ST_TIFR         TIFR0
#define ST_OCF          OCF0A
#endif

#ifdef __IOM8A_H
#define ST_TCNT         TCNT2
#define ST_TIMSK        TIMSK
#define ST_TIFR         TIFR
#define ST_OCIE         OCIE2
#define ST_OCR          OCR2
#define ST_TCCR         TCCR2
#define ST_CS0          CS20
#define ST_CS1          CS21
#define ST_CS2          CS22

#define ST_TIFR         TIFR
#define ST_OCF          OCF2
#endif

#ifdef __IOM8535_H
#define ST_TCNT         TCNT2
#define ST_TIMSK        TIMSK
#define ST_TIFR         TIFR
#define ST_OCIE         OCIE2
#define ST_OCR          OCR2
#define ST_TCCR         TCCR2
#define ST_CS0          CS20
#define ST_CS1          CS21
#define ST_CS2          CS22

#define ST_TIFR         TIFR
#define ST_OCF          OCF2
#endif

#ifdef __IOM32_H
#define ST_TCNT         TCNT2
#define ST_TIMSK        TIMSK
#define ST_TIFR         TIFR
#define ST_OCIE         OCIE2
#define ST_OCR          OCR2
#define ST_TCCR         TCCR2
#define ST_CS0          CS20
#define ST_CS1          CS21
#define ST_CS2          CS22

#define ST_TIFR         TIFR
#define ST_OCF          OCF2
#endif

//==================

//==================
#define SYS_TICK        (F_CPU/64/1000)
//==================

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

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

//==================
void Init_Soft_Timers (void);

#define Handle_Soft_Timer(a) _Handle_Soft_Timer (&a)
bool _Handle_Soft_Timer (soft_timer_t *ptr_timer);

#ifdef __ST_PERIOD__
#define Set_Soft_Timer(a,b,c) _Set_Soft_Timer (&a, b, c)
void _Set_Soft_Timer (soft_timer_t *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_t *ptr_timer, u16 time);
#endif

#define Reset_Soft_Timer(a) _Reset_Soft_Timer (&a)
void _Reset_Soft_Timer (soft_timer_t *ptr_timer);

void Proc_Sys_Tick (void);
//==================

//==================
__monitor bool Main_Get_Tick (void);

void Set_S_Tick_Flg (bool t);
bool Get_S_Tick_Flg (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;
//==================

//==================
volatile static bool int_s_tick_flg; // Флаг обновления системного таймера
static bool s_tick_flg;       // Флаг начала нового системного интервала
//==================

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

   int_s_tick_flg = true; // Новый системный интервал
}
#endif
//==================

//==================
void Init_Soft_Timers (void)
{
   sys_tick = 0;
   ST_TCNT = 0;
   ST_OCR = SYS_TICK;

   int_s_tick_flg = true;  // Принудительное обновление

#ifdef __IOTINY13_H
   ST_TCCR |= ((1<<ST_CS1) | (1<<ST_CS0));
#endif

#ifdef __IOTINY13A_H
   ST_TCCR |= ((1<<ST_CS1) | (1<<ST_CS0));
#endif

#ifdef __IOM8A_H
   ST_TCCR |= (1<<ST_CS2);
#endif

#ifdef __IOM8535_H
   ST_TCCR |= (1<<ST_CS2);
#endif

#ifdef __IOM32_H
   ST_TCCR |= (1<<ST_CS2);
#endif

#ifdef __ST_INTERRUPT__
   set_bit (ST_TIMSK, ST_OCIE);
#endif
}
//----------
#ifdef __ST_PERIOD__
void _Set_Soft_Timer (soft_timer_t *ptr_timer, u16 time, u16 period)
#else
void _Set_Soft_Timer (soft_timer_t *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_t *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_t *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 (ST_TIFR & (1<<ST_OCF))
         {
            ST_TIFR = (1<<ST_OCF);
            ST_OCR += SYS_TICK;
            sys_tick++;

            int_s_tick_flg = true; // Новый системный интервал
         }
         break;
   }
}
#endif
//==================

//==================
__monitor bool Main_Get_Tick (void)
{
   if(!int_s_tick_flg)
      return false;            // Проверка нового системного интервала
   else
   {
      int_s_tick_flg = false;  // Очистка флага
      return true;             // Новый системный интервал
   }
}
//==================

//==================
void Set_S_Tick_Flg (bool t)
{
   s_tick_flg = t;
}

bool Get_S_Tick_Flg (void)
{
   return s_tick_flg;
}
//==================


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Пример программных таймеров для AVR
СообщениеДобавлено: Пн мар 11, 2024 23:39:51 
Вымогатель припоя
Аватар пользователя

Карма: 5
Рейтинг сообщений: 10
Зарегистрирован: Ср дек 08, 2010 19:03:17
Сообщений: 513
Рейтинг сообщения: 0
день добрый!
сам юзаю подобные велосипеды и ... представляю, как тяжело понять "суть" реализации без примеров... :о)
было бы не плохо накидать примеры.
спасибо

_________________
Енот - это кот, только инкогнито!
p.s. держитесь обоими руками, а то прорвет...


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 2 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y