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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
/* Описание модуля 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]++;
}
}
|