В ядро процессора STM32 встроен 24-битный системный таймер, так называемый SysTick (STK), который считает в обратном направлении от загруженной в таймер величины до нуля. В момент достижения значения 0 счетчик автоматически на следующем тактовом перепаде перезагружает сам себя значением из регистра STK_LOAD, и далее продолжает счет вниз, считая каждый приходящий импульс тактирования. Когда процессор остановлен (halted) для отладки, то счетчик не декрементируется.
Таймер SysTick (Cortex System Timer) специально предназначен для операционных систем реального времени (real-time operating system, RTOS), но может использоваться просто как стандартный счетчик вниз. Его возможности:
• 24-битный счетчик с обратным отсчетом.
• Возможность автозагрузки.
• Маскируемая генерация системного прерывания, когда счетчик достигает 0.
• Программируемый источник тактирования.
Базовый адрес для блока регистров SysTick равен 0xE000E010.
Таблица 54. Обзор регистров таймера SysTick.
Адрес |
Имя |
Тип |
Режим доступа |
Значение после сброса |
Описание |
0xE000E010 |
STK_CTRL |
RW |
Привилегированный |
0x00000000 |
Регистр статуса и управления SysTick. |
0xE000E014 |
STK_LOAD |
RW |
Привилегированный |
не определено |
Значение для перезагрузки счетчика SysTick. |
0xE000E018 |
STK_VAL |
RW |
Привилегированный |
не определено |
Текущее значение счетчика SysTick. |
0xE000E01C |
STK_CALIB |
RO |
Привилегированный |
0xC0000000 |
Регистр калибровки SysTick. |
[Описание регистров SysTick]
STK_CTRL, SysTick control and status register (регистр статуса и управления).
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
Reserved |
COUNT FLAG |
rw |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Reserved |
CLK SOURCE |
TICK INT |
ENABLE |
rw |
rw |
rw |
Смещение адреса 0x00, значение после сброса 0x00000000. Требуемый режим доступа: привилегированный. Через регистр статуса и управления разрешаются фичи SysTick.
Биты 31..17, 15..3 зарезервированы, их состояние должно сохраняться в нулевом значении.
COUNTFLAG: этот бит читается как 1, если таймер досчитал до нуля после последнего чтения этого бита.
CLKSOURCE: выбор тактовой частоты для счетчика SysTick. 0: частота AHB/8, 1: частота процессора (AHB).
TICKINT: разрешение на запрос прерывания (exception request enable) SysTick. 0: счет продолжается вниз до нуля, но при этом не выставляется запрос на SysTick exception, 1: то же самое, но по достижении нуля выставляется запрос на SysTick exception. Примечание: программное обеспечение может использовать флаг COUNTFLAG, чтобы определить, что сосчитал ли когда-либо счетчик SysTick до нуля.
ENABLE: разрешение работы счетчика, 0: счетчик запрещен, 1: разрешен. Когда в 1, то счетчик загружает в себя значение RELOAD из регистра STK_LOAD, когда счет достигает 0. В этот момент также устанавливается в 1 флаг COUNTFLAG, и может быть выставлен запрос от прерывания, в зависимости от значения флага TICKINT. После перезагрузки счетчика значением RELOAD счет продолжается, и цикл повторяется.
STK_LOAD, SysTick reload value register (регистр для значения перезагрузки).
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
Reserved |
RELOAD[23:16] |
rw |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
RELOAD[15:0] |
rw |
Смещение адреса 0x04, значение после сброса не определено. Требуемый режим доступа: привилегированный. Биты 31..24 зарезервированы, их состояние должно сохраняться в нулевом значении.
RELOAD: в этих битах содержится значение для перезагрузки счетчика SysTick. Это начальное значение, которое автоматически загружается в регистр STK_VAL, когда счетчик разрешен, и когда счет достигает 0.
Значение для RELOAD вычисляется в соответствии с целями программы:
• Для генерации multi-shot таймера (т. е. у которого срабатывания повторяются снова и снова) с периодом N циклов процессора, используйте значение для RELOAD, равное N-1. Например, когда нужно, чтобы прерывание SysTick было каждые 100 тактовых импульсов, то установите значение RELOAD на величину 99.
• Для генерации одиночного прерывания SysTick после задержки в N циклов процессора, используйте для RELOAD значение N. Например, когда нужно, чтобы прерывание SysTick было каждые 100 тактовых импульсов, то установите значение RELOAD на величину 100.
STK_VAL, SysTick current value register (регистр текущего значения счетчика).
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
Reserved |
CURRENT[23:16] |
rw |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
CURRENT[15:0] |
rw |
Смещение адреса 0x08, значение после сброса не определено. Требуемый режим доступа: привилегированный. Биты 31..24 зарезервированы, их состояние должно сохраняться в нулевом значении.
CURRENT: текущее значение счетчика SysTick. Чтение возвратит это значение. Запись любого значения очистит это поле в 0, и также очистит в 0 бит COUNTFLAG регистра STK_CTRL.
STK_CALIB, SysTick calibration value register (регистр значения калибровки). Содержимое регистра показывает свойства калибровки SysTick.
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
NOREF |
SKEW |
Reserved |
TENMS[23:16] |
r |
r |
r |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
TENMS[15:0] |
r |
Смещение адреса 0x0C, значение после сброса 0xC0000000. Требуемый режим доступа: привилегированный. Биты 29..24 зарезервированы, их состояние должно сохраняться в нулевом значении.
NOREF: флаг NOREF, читается как 0. Показывает, что предоставляется отдельная опорная частота тактов. Частота этих тактов HCLK/8.
SKEW: флаг SKEW (уход), показывает, точно ли установлено значение TENMS. Читается как 1. Значение калибровки для 1 мс не определено, потому что значение TENMS не известно. Это может повлиять на пригодность SysTick в качестве программных часов реального времени.
TENMS: значение калибровки. Показывает значение калибровки, когда счетчик SysTick работает от тактов HCLK max/8. Реальное значение зависит от конкретного чипа и определяется в процессе производства, за подробностями обращайтесь к Product Reference Manual, секция SysTick Calibration Value. Когда HCLK запрограммирован на максимальную частоту, период таймера SysTick равен 1 мс. Если информация калибровки не известна, вычислите значение калибровки по частоте тактов процессора или внешней частоте тактов.
Регистры SysTick в среде IAR, в режиме отладки можно посмотреть в группе регистров STK. Кто бы мог подумать?..
[Общие указания по использованию таймера SysTick]
Счетчик SysTick работает от тактов процессора. Если тактовый сигнал остановлен в режиме пониженного энергопотребления, то счетчик SysTick прекращает счет.
Убедитесь, что программа использует адрес, выровненный по слову для доступа к регистрам SysTick.
После сброса текущее состояние счетчика и значение его перезагрузки не определены, и корректная последовательность инициализация для счетчика SysTick следующая:
1. Нужно запрограммировать значение для перезагрузки счетчика.
2. Затем очистить текущее значение счетчика.
3. Program Control and Status register.
Вектор прерывания таймера SysTick находится по адресу 0x000003C. RCC подает тактовую частоту на System Timer (SysTick) от частоты шины AHB (HCLK), поделенной на 8. SysTick может работать либо от этой частоты, либо от частоты тактов Cortex (HCLK), что конфигурируется через регистр статуса и управления SysTick.
Более подробно о таймере SysTick можно прочитать в руководстве PM0214 компании ST (STM32F3 and STM32F4 Series Cortex®-M4 programming manual).
Комментарии
while (1)
{
if (delaystamp - millis >= delay)
{
delaystamp += delay;
HAL_GPIO_Toggle Pin(GPIOC , LED_Pin);
}
}
uint32_t start_stamp = timestamp;
while(1)
{
if (timestamp - start_stamp >= 500) //полупериод мигания 0.5 сек.
{
start_stamp += 500;
....
}
}
microsin: Вы все правильно понимаете. Глобальный, постоянно считающий счетчик timestamp конечно когда-нибудь переполнится, и перевалит через границу в 0xFFFFFFFF, и начнет считать с нуля. Но еще раньше него произойдет прибавление к delaystamp константы, которая сразу же приведет к перескакиванию delaystamp через границу 0xFFFFFFFF. В этом случае просто условие сработает раньше, и задержка получится меньше, чем обычно.
Страшного ничего не случится, если Вы используете эту задержку для опроса клавиатуры, для мигания, сбора статистики (обычно так эта задержка и используется). Если же Вам нужна стабильная, постоянно точная задержка (например, для ШИМ), то её следует задавать по-другому, с помощью аппаратных таймеров, и алгоритм отсчета должен быть другим, учитывающим переполнение счетчиков.
RSS лента комментариев этой записи