summaryrefslogtreecommitdiff
path: root/Libraries/LTimers/ltimers.c
blob: 61c9e6f91cb12abe6961ddd13a8e2a8136a573d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* Описание модуля ltimers.c

   Этот модуль используется для создания неограниченного количества
программных таймеров для программы. Модуль использует аппаратный таймер,
который генерирует прерывание каждую 1мс (можно использовать любой другой
промежуток времени, просто 1 мс это очень удобно и хватает для многих
программных пауз, задержек, таймеров и тд. в программе).
В прерывании вызывается ф-я ProcessLTimers(), которая инкрементирует значения
всех таймеров. Таймеры создаются в файле ltimers.h.
   Модуль универсален, прост и может использоваться на любой платформе,
компиляторе, любом МК.
   Для подключения модуля настройте аппаратный таймер на прерывание в 1мс (или
любой другой нужный промежуток времени) и добавьте в обработчик прерывания
этого таймера ф-ю ProcessLTimers();. Затем добавьте #include "ltimers.h" в тот
файл программы, где будут использоваться ф-ии модуля. Собственно,
в всего нужны две функции для работы с таймерами:

StartLTimer ( LTIMER_LED_BLINK ); // запустить таймер
GetLTimer   ( LTIMER_LED_BLINK ); // получить текущее значение таймера

   Пример использования:
...
// Предварительно ltimers.h создаем перечисление, в котором создаем имена для
// программных таймеров, а также в конце перечисления всегда MAX_LTIMERS
#include "ltimers.h"
...

int main ()
{
   ...
   // Настройка аппаратного таймера на прерывание раз в 1 мс
   InitLTimersHardWare();

   // Стартовая инициализация (просто обнуление) всех программных таймеров
   InitLTimers ();

   // Запускаем таймер
   StartLTimer ( LTIMER_LED_BLINK );

   // Основной цикл программы
   while (1)
  {
     // Проверяем значение таймера
     if ( GetLTimer ( LTIMER_LED_BLINK ) >= 500 )
     {
        LED_ON;
     }
  }
}

***Примечание

 1. Необходимо учитывать разрядность МК и атомарность при проверке значений
таймера. То есть, если произойдет прерывание в момент проверки полубайтов на
8-ми разрядном МК, то, возможно, могут быть трудноуловимые глюки.

 2. Обратите внимание, что в ф-ии ProcessLTimers() значения таймеров
инкрементируются постоянно и не перестают изменяться. Ф-я StartLTimer только
сбрасывает значение таймера в ноль, а потом программа уже ловит тот момент,
когда это значение превысило или сравнялось с нужным. И когда мы провели
сравнение, то таймер все равно продолжает маслать. Но это не важно. Пусть себе
маслает.

 3. Псевдоним для типа uint32_t можно заменить на необходимый в зависимости
от среды разработки и компилятора.
*/

#include "ltimers.h"
#include "ltimers_config.h"

uint32_t LTimers [MAX_LTIMERS] = { 0 };


// ----------------------------------------------------------------------------
// Стартовая инициализация всех программных таймеров программиста.
// Ф-я вызывается при старте МК и просто устанавливает все значения таймеров
// в ноль.
// ----------------------------------------------------------------------------
void InitLTimers (void)
{
    LTimersConfig ();
}


// ----------------------------------------------------------------------------
// Ф-я получения значения программного счетчика
// Используется программистом для проверки значения запущенного таймера
// Ф-я принимает имя таймера из перечисления LTimerNum_t в файле ltimers.h
// Ф-я возвращает значение таймера, которое увеличивается каждую 1мс
// ----------------------------------------------------------------------------
uint32_t GetLTimer ( LTimersNames_t LTimer )
{
    return LTimers[ LTimer ];
}


// ----------------------------------------------------------------------------
// Ф-я запуска программного таймера для использования программистом для
// любых программных задержек разрешением 1мс
// Ф-я принимает имя таймера из перечисления LTimerNum_t в файле ltimers.h
// ----------------------------------------------------------------------------
void StartLTimer ( LTimersNames_t LTimer )
{
    LTimers[ LTimer ] = 0;
}


// ----------------------------------------------------------------------------
// Ф-я, инкрементирующая значения программных таймеров. Количество этих
// программных таймеров нее ограничено и задается программистом в ltimers.h
// в тайпдефе LTimerNum_t. Просто дописываем в перечислении перед MAX_LTIMERS
// имя нового таймера.
// Вызывается эта ф-я в обреботчике TIM6_IRQHandler каждую 1 мс.
// 1 мс это удобный квант времени для разных программных задержек
// ----------------------------------------------------------------------------
void ProcessLTimers (void)
{
    for ( uint32_t i = 0; i < MAX_LTIMERS; i++ )
    {
        LTimers[i]++;
    }
}