|
@@ -1,67 +1,67 @@
|
|
|
-Сам таймер 24 разрядный. И тикает вниз от предзагруженного значения до
|
|
|
-нуля, после чего перезагружается вновь и генерирует прерывание.
|
|
|
-Источником тактирования является системная тактовая частота SYSCLK, либо
|
|
|
-та же частота, но поделенная на 8 – SYSCLK/8.
|
|
|
+Сам таймер 24 разрядный. � тикает вниз от предзагруженного значения до
|
|
|
+нуля, после чего перезагружается вновь и генерирует прерывание.
|
|
|
+�сточником тактирования является системная тактовая частота SYSCLK, либо
|
|
|
+та же частота, но поделенная на 8 – SYSCLK/8.
|
|
|
|
|
|
-Управляется он четырьмя регистрами:
|
|
|
+Управляется он четырьмя регистрами:
|
|
|
0xE000E010 SYST_CSR RW SysTick control and status register
|
|
|
0xE000E014 SYSCT_RVR RW SysTick reload value register
|
|
|
0xE000E018 SYSCT_CVR RW SysTick current value register
|
|
|
0xE000E01C SYSCT_CALIB RO SysTick calibration value register
|
|
|
|
|
|
|
|
|
-*SYST_CSR* — SysTick Control and Status Register
|
|
|
-Регистр управления и статуса. Несмотря на то, что он 32 битный заняты там всего 4 бита :)
|
|
|
- * Бит 0 — ENABLE — бит разрешающий таймеру считать. 1 можно, 0 — нельзя. Когда
|
|
|
- мы ставим ENABLE в 1 то таймер автоматически загружает свои счетные регистры
|
|
|
- значением из регистра SYST_RVR и начинает тикать вниз.
|
|
|
- * Бит 1 — TICKINT — разрешение прерывания. Когда этот бит 1, то на
|
|
|
- обнулении будет прерывание таймера.
|
|
|
- * Бит 2 — CLKSOURCE — откуда брать тики. Варианта два 0 — внешнее
|
|
|
- тактирование эталонного генератора, 1 — с частоты процессора.
|
|
|
- * Бит 16 — COUNTFLAG — флаг отсчета. Первый раз ставится в 1 после
|
|
|
- первого обнуления. При чтении, как я понял, автоматом обнуляется.
|
|
|
- Возвращает 1 если с последнего его чтения таймер перешел через ноль.
|
|
|
- Позволяет отследить были ли переполнения. Удобно.
|
|
|
-
|
|
|
-
|
|
|
-*SYST_RVR* — SysTick Reload Value Register
|
|
|
-Регистр предзагрузки. Именно отсюда берет таймер свое значение для
|
|
|
-перезагрузки при обнулении. Фактически вот сюда и нужно грузить требуемое
|
|
|
-число задержки. Регистр 32 разрядный, но используются только первые 24
|
|
|
-бита.
|
|
|
-Класть туда можно любое число в диапазоне 0x00000001-0x00FFFFFF. Можно и
|
|
|
-0 положить, но ничего не будет. Т.к. у таймера весь экшн происходит с
|
|
|
-перехода из 0x00000001 в 0x00000000. А на ноль и получается ноль. Разве
|
|
|
-что COUNTFLAG вскочит. Только и всего. Поэтому значение SYST_RVR должно
|
|
|
-быть N-1 от желаемого количества тактов. Т.е. если надо получить
|
|
|
-прерывание на каждые 10000 тактов, то кладем 9999.
|
|
|
-
|
|
|
-
|
|
|
-*SYST_CVR* — SysTick Current Value Register
|
|
|
-Это, собственно, и есть счетный регистр. Тут оно тикает! В первых трех
|
|
|
-байтах. Есть у этого регистра особенность одна забавная. Из него можно
|
|
|
-только читать. А вот запись любого значения сразу его обнуляет. С
|
|
|
-обнулением флага COUNTFLAG.
|
|
|
-Т.е. если надо занулить таймер — пиши сюда :)
|
|
|
-
|
|
|
-
|
|
|
-*SYST_CALIB* — SysTick Calibration Value Register
|
|
|
-Это, как ясно из названия, регистр калибровки. Его можно только читать, и
|
|
|
-возвращает он следующее:
|
|
|
- * SKEW — Показывает что записано в TENMS 0 — там реальные калибровочные
|
|
|
- константы. 1 — какой то мусор который не имеет значения. Ну или ноль.
|
|
|
- * NOREF — показывает есть ли у девайса эталонная тактовая частота. 0 —
|
|
|
- есть, 1 — нет. Это зависит от производителя, позаботился ли он о такой
|
|
|
- штуке :) Если эталонных часов нет, то бит CLKSOURCE из регистра SYST_CSR
|
|
|
- читается как 1 и его нельзя изменить.
|
|
|
- * TENMS — калибровочная константа. Содержит значение для 10мс задержки.
|
|
|
- Как я понял, для эталонного генератора. Которого может и не быть.
|
|
|
-
|
|
|
-
|
|
|
- *** Адреса и имена ***
|
|
|
-Осталось залезть в CMSIS и поискать там описание и дефайны SysTick.
|
|
|
-Находятся быстро в core_cm3.h:
|
|
|
+*SYST_CSR* — SysTick Control and Status Register
|
|
|
+Регистр управления и статуса. Несмотря на то, что он 32 битный заняты там всего 4 бита :)
|
|
|
+ * Бит 0 — ENABLE — бит разрешающий таймеру считать. 1 можно, 0 — нельзя. Когда
|
|
|
+ мы ставим ENABLE в 1 то таймер автоматически загружает свои счетные регистры
|
|
|
+ значением из регистра SYST_RVR и начинает тикать вниз.
|
|
|
+ * Бит 1 — TICKINT — разрешение прерывания. Когда этот бит 1, то на
|
|
|
+ обнулении будет прерывание таймера.
|
|
|
+ * Бит 2 — CLKSOURCE — откуда брать тики. Варианта два 0 — внешнее
|
|
|
+ тактирование эталонного генератора, 1 — с частоты процессора.
|
|
|
+ * Бит 16 — COUNTFLAG — флаг отсчета. Первый раз ставится в 1 после
|
|
|
+ первого обнуления. При чтении, как я понял, автоматом обнуляется.
|
|
|
+ Возвращает 1 если с последнего его чтения таймер перешел через ноль.
|
|
|
+ Позволяет отследить были ли переполнения. Удобно.
|
|
|
+
|
|
|
+
|
|
|
+*SYST_RVR* — SysTick Reload Value Register
|
|
|
+Регистр предзагрузки. �менно отсюда берет таймер свое значение для
|
|
|
+перезагрузки при обнулении. Фактически вот сюда и нужно грузить требуемое
|
|
|
+число задержки. Регистр 32 разрядный, но используются только первые 24
|
|
|
+бита.
|
|
|
+Класть туда можно любое число в диапазоне 0x00000001-0x00FFFFFF. Можно и
|
|
|
+0 положить, но ничего не будет. Т.к. у таймера весь экшн происходит с
|
|
|
+перехода из 0x00000001 в 0x00000000. А на ноль и получается ноль. Разве
|
|
|
+что COUNTFLAG вскочит. Только и всего. Поэтому значение SYST_RVR должно
|
|
|
+быть N-1 от желаемого количества тактов. Т.е. если надо получить
|
|
|
+прерывание на каждые 10000 тактов, то кладем 9999.
|
|
|
+
|
|
|
+
|
|
|
+*SYST_CVR* — SysTick Current Value Register
|
|
|
+Рто, собственно, Рё есть счетный регистр. РўСѓС‚ РѕРЅРѕ тикает! Р’ первых трех
|
|
|
+байтах. Есть у этого регистра особенность одна забавная. �з него можно
|
|
|
+только читать. А вот запись любого значения сразу его обнуляет. С
|
|
|
+обнулением флага COUNTFLAG.
|
|
|
+Т.е. если надо занулить таймер — пиши сюда :)
|
|
|
+
|
|
|
+
|
|
|
+*SYST_CALIB* — SysTick Calibration Value Register
|
|
|
+Рто, как СЏСЃРЅРѕ РёР· названия, регистр калибровки. Его РјРѕР¶РЅРѕ только читать, Рё
|
|
|
+возвращает он следующее:
|
|
|
+ * SKEW — Показывает что записано в TENMS 0 — там реальные калибровочные
|
|
|
+ константы. 1 — какой то мусор который не имеет значения. Ну или ноль.
|
|
|
+ * NOREF — показывает есть ли у девайса эталонная тактовая частота. 0 —
|
|
|
+ есть, 1 — нет. Рто зависит РѕС‚ производителя, позаботился ли РѕРЅ Рѕ такой
|
|
|
+ штуке :) Если эталонных часов нет, то бит CLKSOURCE из регистра SYST_CSR
|
|
|
+ читается как 1 и его нельзя изменить.
|
|
|
+ * TENMS — калибровочная константа. Содержит значение для 10мс задержки.
|
|
|
+ Как я понял, для эталонного генератора. Которого может и не быть.
|
|
|
+
|
|
|
+
|
|
|
+ *** Адреса и имена ***
|
|
|
+Осталось залезть в CMSIS и поискать там описание и дефайны SysTick.
|
|
|
+Находятся быстро в core_cm3.h:
|
|
|
*------------------ File Begin -------------------*
|
|
|
typedef struct
|
|
|
{
|
|
@@ -105,18 +105,18 @@ typedef struct
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
|
|
|
-Нам там нужны имена битов. Вот они:
|
|
|
+Нам там нужны имена битов. Вот они:
|
|
|
SysTick_CTRL_CLKSOURCE_Msk, SysTick_CTRL_TICKINT_Msk, SysTick_CTRL_ENABLE_Msk.
|
|
|
|
|
|
|
|
|
-Конфигурация таймера на тик в 1ms, таким образом, будет выглядеть примерно
|
|
|
-так:
|
|
|
+Конфигурация таймера на тик в 1ms, таким образом, будет выглядеть примерно
|
|
|
+так:
|
|
|
*------------------ File Begin -------------------*
|
|
|
-#define F_CPU 72000000UL // Тактовая у нас 72МГЦ
|
|
|
-#define TimerTick F_CPU/1000-1 // Нам нужен килогерц
|
|
|
+#define F_CPU 72000000UL // Тактовая у нас 72МГЦ
|
|
|
+#define TimerTick F_CPU/1000-1 // Нам нужен килогерц
|
|
|
|
|
|
-SysTick->LOAD=TimerTick; // Загрузка значения
|
|
|
-SysTick->VAL=TimerTick; // Обнуляем таймеры и флаги. Записью, помните?
|
|
|
+SysTick->LOAD=TimerTick; // Загрузка значения
|
|
|
+SysTick->VAL=TimerTick; // Обнуляем таймеры и флаги. Записью, помните?
|
|
|
|
|
|
SysTick->CTRL= SysTick_CTRL_CLKSOURCE_Msk |
|
|
|
SysTick_CTRL_TICKINT_Msk |
|
|
@@ -124,11 +124,11 @@ SysTick->CTRL= SysTick_CTRL_CLKSOURCE_Msk |
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
|
|
|
- *** Обработчик прерывания SysTick ***
|
|
|
-Где взять имя обработчика? Да из таблицы прерываний. Поглядеть, если кто
|
|
|
-не помнит, можно в STM32F10x.s
|
|
|
+ *** Обработчик прерывания SysTick ***
|
|
|
+Где взять имя обработчика? Да из таблицы прерываний. Поглядеть, если кто
|
|
|
+РЅРµ РїРѕРјРЅРёС‚, РјРѕР¶РЅРѕ РІ STM32F10x.s
|
|
|
|
|
|
-Вот ее кусочек:
|
|
|
+Вот ее кусочек:
|
|
|
*------------------ File Begin -------------------*
|
|
|
; Vector Table Mapped to Address 0 at Reset
|
|
|
|
|
@@ -154,22 +154,22 @@ __Vectors DCD __initial_sp ; Top of Stack
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
|
|
|
-Имя есть. Осталось организовать прерывание:
|
|
|
+�мя есть. Осталось организовать прерывание:
|
|
|
*------------------ File Begin -------------------*
|
|
|
//SysTick Interrupt
|
|
|
void SysTick_Handler(void)
|
|
|
{
|
|
|
- // Тут будем делать нечто полезное. Например, ставить бит B.05
|
|
|
+ // Тут будем делать нечто полезное. Например, ставить бит B.05
|
|
|
GPIOB->BSRR = GPIO_BSRR_BS5; // Set bit
|
|
|
}
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
|
|
|
-А сбрасывать его будет в главном цикле. В результате мы получим иголки с
|
|
|
-частотой 1Кгц которые хорошо видно осциллографом :)
|
|
|
+А сбрасывать его будет в главном цикле. В результате мы получим иголки с
|
|
|
+частотой 1Кгц которые хорошо видно осциллографом :)
|
|
|
|
|
|
|
|
|
-Вот так выглядит полный код примера:
|
|
|
+Вот так выглядит полный код примера:
|
|
|
*------------------ File Begin -------------------*
|
|
|
#include "stm32f10x.h"
|
|
|
#define F_CPU 72000000UL
|
|
@@ -206,10 +206,10 @@ int main(void)
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
|
|
|
- *** Функции CMSIS ***
|
|
|
+ *** Функции CMSIS ***
|
|
|
|
|
|
-У Таймера, раз он часть ядра, есть функция конфигурации в CMSIS. Описана
|
|
|
-она в core_cm3.h и выглядит так:
|
|
|
+У Таймера, раз он часть ядра, есть функция конфигурации в CMSIS. Описана
|
|
|
+она в core_cm3.h и выглядит так:
|
|
|
*------------------ File Begin -------------------*
|
|
|
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
|
|
|
{
|
|
@@ -226,24 +226,24 @@ static __INLINE uint32_t SysTick_Config(uint32_t ticks)
|
|
|
}
|
|
|
*------------------ File End -------------------*
|
|
|
|
|
|
-То же самое, что и мы сделали вручную. Только есть проверка на
|
|
|
-корректность значения и обрезка лишних битов. Возвращает 1 если данные
|
|
|
-некорректные. Ну и еще там приоритет ставится если ядро М0 (это кстати хз
|
|
|
-зачем? У M0 же должна быть своя версия CMSIS?)
|
|
|
+То же самое, что и мы сделали вручную. Только есть проверка на
|
|
|
+корректность значения и обрезка лишних битов. Возвращает 1 если данные
|
|
|
+некорректные. Ну и еще там приоритет ставится если ядро М0 (это кстати хз
|
|
|
+зачем? У M0 же должна быть своя версия CMSIS?)
|
|
|
|
|
|
|
|
|
-Так что таймер можно загрузить и следующей фигней:
|
|
|
+Так что таймер можно загрузить и следующей фигней:
|
|
|
SysTick_Config(TimerTick);
|
|
|
|
|
|
-Для LPC все совершенно аналогично. До последней буковки можно сказать.
|
|
|
-Т.к. это фича не STM32, а ядра и описана в CMSIS. Т.е. едина для всех.
|
|
|
+Для LPC все совершенно аналогично. До последней буковки можно сказать.
|
|
|
+Т.к. это фича не STM32, а ядра и описана в CMSIS. Т.е. едина для всех.
|
|
|
|
|
|
===============================================================================
|
|
|
|
|
|
-Для конфигурации таймера в файле core_cm3.h есть функция
|
|
|
-SysTick_Config(uint32_t ticks), в качестве аргумента которой передается
|
|
|
-коэффициент деления тактовой частоты для получения необходимой временной
|
|
|
-задержки.
|
|
|
+Для конфигурации таймера в файле core_cm3.h есть функция
|
|
|
+SysTick_Config(uint32_t ticks), в качестве аргумента которой передается
|
|
|
+коэффициент деления тактовой частоты для получения необходимой временной
|
|
|
+задержки.
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
|
|
|
{
|
|
@@ -259,56 +259,56 @@ static __INLINE uint32_t SysTick_Config(uint32_t ticks)
|
|
|
}
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
-Это значение заносится в регистр перезагрузки. В самом начале выполняется
|
|
|
-проверка на то, что данная величина не выходит за максимальный предел,
|
|
|
-поскольку счетчик 24-разрядный, а передаваемый аргумент функции является
|
|
|
-32-разрядным числом и необходимо об этом помнить.
|
|
|
+Рто значение заносится РІ регистр перезагрузки. Р’ самом начале выполняется
|
|
|
+проверка на то, что данная величина не выходит за максимальный предел,
|
|
|
+поскольку счетчик 24-разрядный, а передаваемый аргумент функции является
|
|
|
+32-разрядным числом и необходимо об этом помнить.
|
|
|
|
|
|
-Далее в функции конфигурации SysTick_Config() задается уровень приоритета
|
|
|
-прерывания, обнуляется счетный регистр, разрешается генерация прерывания,
|
|
|
-задается источник тактирования и разрешается работа таймера – запускается
|
|
|
-счет.
|
|
|
+Далее в функции конфигурации SysTick_Config() задается уровень приоритета
|
|
|
+прерывания, обнуляется счетный регистр, разрешается генерация прерывания,
|
|
|
+задается источник тактирования и разрешается работа таймера – запускается
|
|
|
+счет.
|
|
|
|
|
|
-По умолчанию тактовая частота этого таймера будет равна системной тактовой
|
|
|
-частоте SYSCLK. Если же нужно задать частоту тактирования таймера как
|
|
|
-SYSCLK/8, то уже после этой функции инициализации можно вызвать функцию
|
|
|
+По умолчанию тактовая частота этого таймера будет равна системной тактовой
|
|
|
+частоте SYSCLK. Если же нужно задать частоту тактирования таймера как
|
|
|
+SYSCLK/8, то уже после этой функции инициализации можно вызвать функцию
|
|
|
|
|
|
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8),
|
|
|
|
|
|
-которая находится в файле misc.c. Для этого к проекту необходимо
|
|
|
-подключить файлы misc.c и misc.h.
|
|
|
+которая находится в файле misc.c. Для этого к проекту необходимо
|
|
|
+подключить файлы misc.c и misc.h.
|
|
|
|
|
|
|
|
|
-В данных примерах таймер настраивается на генерацию прерывания через
|
|
|
-“базовый” промежуток времени, равный 1 миллисекунде. Затем, уже с помощью
|
|
|
-программного цикла формируется задержка, равная 1 секунде. Через каждую
|
|
|
-секунду происходит попеременное зажигание/гашение светодиодов платы, здесь
|
|
|
-я не стал особо мудрить, поскольку основной задачей была настройка
|
|
|
-системного таймера для генерации прерываний через определенный интервал.
|
|
|
+В данных примерах таймер настраивается на генерацию прерывания через
|
|
|
+“базовый” промежуток времени, равный 1 миллисекунде. Затем, уже с помощью
|
|
|
+программного цикла формируется задержка, равная 1 секунде. Через каждую
|
|
|
+секунду происходит попеременное зажигание/гашение светодиодов платы, здесь
|
|
|
+я не стал особо мудрить, поскольку основной задачей была настройка
|
|
|
+системного таймера для генерации прерываний через определенный интервал.
|
|
|
|
|
|
-Для задания длительности между двумя последующими прерываниями от таймера,
|
|
|
-в регистр перезагрузки необходимо записать значение, которое
|
|
|
-рассчитывается по простой формуле:
|
|
|
+Для задания длительности между двумя последующими прерываниями от таймера,
|
|
|
+в регистр перезагрузки необходимо записать значение, которое
|
|
|
+рассчитывается по простой формуле:
|
|
|
|
|
|
- * Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s), где
|
|
|
- * Reload Value – величина перезагружаемого значения для таймера
|
|
|
- * SysTick Counter Clock (Hz) – тактовая частота таймера
|
|
|
- * Desired Time base (s) – желаемое время формируемой временной задержки между прерываниями
|
|
|
+ * Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s), РіРґРµ
|
|
|
+ * Reload Value – величина перезагружаемого значения для таймера
|
|
|
+ * SysTick Counter Clock (Hz) – тактовая частота таймера
|
|
|
+ * Desired Time base (s) – желаемое время формируемой временной задержки между прерываниями
|
|
|
|
|
|
-Системная тактовая частота задается при начальной инициализации микроконтроллера.
|
|
|
+Системная тактовая частота задается при начальной инициализации микроконтроллера.
|
|
|
|
|
|
-На плате STM32VL-DISCOVERY микроконтроллер конфигурируется на работу с
|
|
|
-внешним кварцем частотой 8 МГц, при этом его системная тактовая частота
|
|
|
-после начальной инициализации будет равна 24 МГц.
|
|
|
+На плате STM32VL-DISCOVERY микроконтроллер конфигурируется на работу с
|
|
|
+внешним кварцем частотой 8 МГц, при этом его системная тактовая частота
|
|
|
+после начальной инициализации будет равна 24 МГц.
|
|
|
|
|
|
-На плате STM32L-DISCOVERY внешнего кварца нет и после начальной
|
|
|
-инициализации системная тактовая частота формируется внутренним источником
|
|
|
-MSI и равна 2,097 МГц.
|
|
|
+На плате STM32L-DISCOVERY внешнего кварца нет и после начальной
|
|
|
+инициализации системная тактовая частота формируется внутренним источником
|
|
|
+MSI и равна 2,097 МГц.
|
|
|
|
|
|
-Расчет перезагружаемых значений приведен ниже, в комментариях примеров программ для этих плат.
|
|
|
+Расчет перезагружаемых значений приведен ниже, в комментариях примеров программ для этих плат.
|
|
|
|
|
|
|
|
|
-Код программы для платы STM32VL-DISCOVERY (контроллер STM32F100)
|
|
|
+Код программы для платы STM32VL-DISCOVERY (контроллер STM32F100)
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
#include "stm32f10x.h"
|
|
|
|
|
@@ -320,43 +320,43 @@ GPIO_InitTypeDef GPIO_InitStruct;
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
- /*Вызов функции конфигурации системного таймера SysTick.
|
|
|
- Эта функция находится в файле core_cm3.h и:
|
|
|
- --Задает источник тактирования системного таймера (по умолчанию это SYSCLK = 24 МГц,
|
|
|
- другой возможный вариант - SysTick тактируется от SYSCLK/8);
|
|
|
- --Задает уровень приоритета прерывания;
|
|
|
- --Сбрасывает флаг ожидания прерывания, если он выставлен;
|
|
|
- --Заносит в нужный регистр перезагружаемое значение для декрементирующего счетчика,
|
|
|
- которое вычисляется по формуле:
|
|
|
+ /*Вызов функции конфигурации системного таймера SysTick.
|
|
|
+ Рта функция находится РІ файле core_cm3.h Рё:
|
|
|
+ --Задает источник тактирования системного таймера (по умолчанию это SYSCLK = 24 МГц,
|
|
|
+ другой возможный вариант - SysTick тактируется от SYSCLK/8);
|
|
|
+ --Задает уровень приоритета прерывания;
|
|
|
+ --Сбрасывает флаг ожидания прерывания, если он выставлен;
|
|
|
+ --Заносит в нужный регистр перезагружаемое значение для декрементирующего счетчика,
|
|
|
+ которое вычисляется по формуле:
|
|
|
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s),
|
|
|
- для базовой задержки длительностью 1 мс получим величину
|
|
|
- Reload Value = 24 000 000 Гц х 0,001 с = 24 000
|
|
|
- (Необходимо самостоятельно посчитать эту величину и вставить в качестве
|
|
|
- параметра при вызове функции);
|
|
|
- --Обнуляет счетчик
|
|
|
- --Запускает счет системного таймера*/
|
|
|
+ для базовой задержки длительностью 1 мс получим величину
|
|
|
+ Reload Value = 24 000 000 Гц х 0,001 с = 24 000
|
|
|
+ (Необходимо самостоятельно посчитать эту величину и вставить в качестве
|
|
|
+ параметра при вызове функции);
|
|
|
+ --Обнуляет счетчик
|
|
|
+ --Запускает счет системного таймера*/
|
|
|
SysTick_Config(24000);
|
|
|
|
|
|
- //Включаем тактирование порта GPIOC
|
|
|
+ //Включаем тактирование порта GPIOC
|
|
|
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
|
|
- //Конфигурируем выводы, к которым подключены светодиоды платы
|
|
|
- GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //Выбираем выводы PC8, PC9
|
|
|
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //Максимальная скорость работы
|
|
|
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //Выход Push-Pull
|
|
|
- GPIO_Init(GPIOC, &GPIO_InitStruct); //Заносим заданные настройки в регистры порта
|
|
|
+ //Конфигурируем выводы, к которым подключены светодиоды платы
|
|
|
+ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; //Выбираем выводы PC8, PC9
|
|
|
+ GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //Максимальная скорость работы
|
|
|
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; //Выход Push-Pull
|
|
|
+ GPIO_Init(GPIOC, &GPIO_InitStruct); //Заносим заданные настройки в регистры порта
|
|
|
|
|
|
while(1)
|
|
|
{
|
|
|
- GPIO_ResetBits(GPIOC, GPIO_Pin_9); //Гасим зеленый LED
|
|
|
- GPIO_SetBits(GPIOC, GPIO_Pin_8); //Зажигаем синий LED
|
|
|
- Delay_ms(1000); //Временная задержка на 1 с
|
|
|
- GPIO_ResetBits(GPIOC, GPIO_Pin_8); //Гасим синий LED
|
|
|
- GPIO_SetBits(GPIOC, GPIO_Pin_9); //Зажигаем зеленый LED
|
|
|
- Delay_ms(1000); //Временная задержка на 1 с
|
|
|
+ GPIO_ResetBits(GPIOC, GPIO_Pin_9); //Гасим зеленый LED
|
|
|
+ GPIO_SetBits(GPIOC, GPIO_Pin_8); //Зажигаем синий LED
|
|
|
+ Delay_ms(1000); //Временная задержка на 1 с
|
|
|
+ GPIO_ResetBits(GPIOC, GPIO_Pin_8); //Гасим синий LED
|
|
|
+ GPIO_SetBits(GPIOC, GPIO_Pin_9); //Зажигаем зеленый LED
|
|
|
+ Delay_ms(1000); //Временная задержка на 1 с
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Функция временной задержки
|
|
|
+//Функция временной задержки
|
|
|
void Delay_ms(__IO uint32_t nTime)
|
|
|
{
|
|
|
TimingDelay = nTime;
|
|
@@ -371,7 +371,7 @@ void TimingDelay_Decrement(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Обработчик прерывания системного таймера
|
|
|
+//Обработчик прерывания системного таймера
|
|
|
void SysTick_Handler(void)
|
|
|
{
|
|
|
TimingDelay_Decrement();
|
|
@@ -379,7 +379,7 @@ void SysTick_Handler(void)
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
-Код программы для платы STM32L-DISCOVERY (контроллер STM32L152)
|
|
|
+Код программы для платы STM32L-DISCOVERY (контроллер STM32L152)
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
#include "stm32l1xx.h"
|
|
|
|
|
@@ -391,45 +391,45 @@ GPIO_InitTypeDef GPIO_InitStruct;
|
|
|
|
|
|
int main()
|
|
|
{
|
|
|
- /*Вызов функции конфигурации системного таймера SysTick.
|
|
|
- Эта функция находится в файле core_cm3.h и:
|
|
|
- --Задает источник тактирования системного таймера (по умолчанию это SYSCLK = 2.097 МГц,
|
|
|
- другой возможный вариант - SysTick тактируется от SYSCLK/8);
|
|
|
- --Задает уровень приоритета прерывания;
|
|
|
- --Сбрасывает флаг ожидания прерывания, если он выставлен;
|
|
|
- --Заносит в нужный регистр перезагружаемое значение для декрементирующего счетчика,
|
|
|
- которое вычисляется по формуле:
|
|
|
+ /*Вызов функции конфигурации системного таймера SysTick.
|
|
|
+ Рта функция находится РІ файле core_cm3.h Рё:
|
|
|
+ --Задает источник тактирования системного таймера (по умолчанию это SYSCLK = 2.097 МГц,
|
|
|
+ другой возможный вариант - SysTick тактируется от SYSCLK/8);
|
|
|
+ --Задает уровень приоритета прерывания;
|
|
|
+ --Сбрасывает флаг ожидания прерывания, если он выставлен;
|
|
|
+ --Заносит в нужный регистр перезагружаемое значение для декрементирующего счетчика,
|
|
|
+ которое вычисляется по формуле:
|
|
|
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s),
|
|
|
- для базовой задержки длительностью 1 мс получим величину
|
|
|
- Reload Value = 2 097 000 Гц х 0,001 с = 2097
|
|
|
- (Необходимо самостоятельно посчитать эту величину и вставить в качестве
|
|
|
- параметра при вызове функции);
|
|
|
- --Обнуляет счетчик
|
|
|
- --Запускает счет системного таймера*/
|
|
|
+ для базовой задержки длительностью 1 мс получим величину
|
|
|
+ Reload Value = 2 097 000 Гц х 0,001 с = 2097
|
|
|
+ (Необходимо самостоятельно посчитать эту величину и вставить в качестве
|
|
|
+ параметра при вызове функции);
|
|
|
+ --Обнуляет счетчик
|
|
|
+ --Запускает счет системного таймера*/
|
|
|
SysTick_Config(2097);
|
|
|
|
|
|
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //Включаем тактирование GPIOB
|
|
|
+ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //Включаем тактирование GPIOB
|
|
|
|
|
|
- //Конфигурируем выводы, к которым подключены светодиоды платы
|
|
|
- GPIO_InitStruct.GPIO_Pin = (GPIO_Pin_6 | GPIO_Pin_7); //Выбираем выводы PB6, PB7
|
|
|
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //Выводы порта в режиме выхода
|
|
|
- GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //Выход Push-Pull
|
|
|
- GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //Выход без подтягивающих резисторов
|
|
|
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz; //Скорость порта максимальная
|
|
|
- GPIO_Init(GPIOB, &GPIO_InitStruct); //Заданные настройки сохраняем в регистрах GPIOB
|
|
|
+ //Конфигурируем выводы, к которым подключены светодиоды платы
|
|
|
+ GPIO_InitStruct.GPIO_Pin = (GPIO_Pin_6 | GPIO_Pin_7); //Выбираем выводы PB6, PB7
|
|
|
+ GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //Выводы порта в режиме выхода
|
|
|
+ GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //Выход Push-Pull
|
|
|
+ GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //Выход без подтягивающих резисторов
|
|
|
+ GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz; //Скорость порта максимальная
|
|
|
+ GPIO_Init(GPIOB, &GPIO_InitStruct); //Заданные настройки сохраняем в регистрах GPIOB
|
|
|
|
|
|
while(1)
|
|
|
{
|
|
|
- GPIO_ResetBits(GPIOB, GPIO_Pin_7); //Гасим зеленый LED
|
|
|
- GPIO_SetBits(GPIOB, GPIO_Pin_6); //Зажигаем синий LED
|
|
|
- Delay_ms(1000); //Временная задержка на 1 с
|
|
|
- GPIO_ResetBits(GPIOB, GPIO_Pin_6); //Гасим синий LED
|
|
|
- GPIO_SetBits(GPIOB, GPIO_Pin_7); //Зажигаем зеленый LED
|
|
|
- Delay_ms(1000); //Временная задержка на 1 с
|
|
|
+ GPIO_ResetBits(GPIOB, GPIO_Pin_7); //Гасим зеленый LED
|
|
|
+ GPIO_SetBits(GPIOB, GPIO_Pin_6); //Зажигаем синий LED
|
|
|
+ Delay_ms(1000); //Временная задержка на 1 с
|
|
|
+ GPIO_ResetBits(GPIOB, GPIO_Pin_6); //Гасим синий LED
|
|
|
+ GPIO_SetBits(GPIOB, GPIO_Pin_7); //Зажигаем зеленый LED
|
|
|
+ Delay_ms(1000); //Временная задержка на 1 с
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Функция временной задержки
|
|
|
+//Функция временной задержки
|
|
|
void Delay_ms(__IO uint32_t nTime)
|
|
|
{
|
|
|
TimingDelay = nTime;
|
|
@@ -444,7 +444,7 @@ void TimingDelay_Decrement(void)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-//Обработчик прерывания системного таймера
|
|
|
+//Обработчик прерывания системного таймера
|
|
|
void SysTick_Handler(void)
|
|
|
{
|
|
|
TimingDelay_Decrement();
|
|
@@ -453,15 +453,15 @@ void SysTick_Handler(void)
|
|
|
|
|
|
===============================================================================
|
|
|
|
|
|
- *** Литература: ***
|
|
|
+ *** Литература: ***
|
|
|
|
|
|
Cortex-M3 Devices Generic User Guide
|
|
|
Cortex-M3 Peripherals > System timer, SysTick
|
|
|
4.4. System timer, SysTick
|
|
|
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Babieigh.html
|
|
|
|
|
|
-ARM. Учебный Курс. SysTick — Системный таймер
|
|
|
+ARM. Учебный Курс. SysTick — Системный таймер
|
|
|
http://easyelectronics.ru/arm-uchebnyj-kurs-systick-sistemnyj-tajmer.html
|
|
|
|
|
|
-STM32. Системный таймер SysTick.
|
|
|
+STM32. Системный таймер SysTick.
|
|
|
http://chipspace.ru/stm32-systick/
|