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