Comments 17
Спасибо. Вставьте ссылки на предыдущие статьи…
Строго говоря, SysTick — это часть ядра Cortex M3, поэтому работа с ним в разных контроллерах на этом ядре практически идентична.
По-хорошему, вам даже не обязательно было трогать регистры; в файле core_cm3.h уже есть готовая функция для его настройки — SysTick_Config.
Полезнее было бы рассмотреть работу с родной периферией миландра в каком-нибудь более-менее реалистичном сценарии. Чтение ADC через DMA, например.
По-хорошему, вам даже не обязательно было трогать регистры; в файле core_cm3.h уже есть готовая функция для его настройки — SysTick_Config.
Полезнее было бы рассмотреть работу с родной периферией миландра в каком-нибудь более-менее реалистичном сценарии. Чтение ADC через DMA, например.
Строго говоря, SysTick — это часть ядра Cortex M3, поэтому работа с ним в разных контроллерах на этом ядре практически идентична.
Полезнее было бы рассмотреть работу с родной периферией миландра в каком-нибудь более-менее реалистичном сценарии. Чтение ADC через DMA, например.
Я знаю. Он нужен для следующего урока, посвященного системам тактирования МК. Для наглядности.
По-хорошему, вам даже не обязательно было трогать регистры; в файле core_cm3.h уже есть готовая функция для его настройки — SysTick_Config.
Про функцию тоже знаю. Но куда приятнее настроить вручную. Чтобы знать наверняка, что все правильно.
Как раз в образовательных целях написание своей функции работы с таймером полезней, чем использование библиотечной… Использование библиотечной функции ничего кроме знания названия этой функции новичку не даст…
Я очень сомневаюсь, что знание о стандартизированных регистрах ценнее, чем знание о стандартизированной библиотечной функции.
Зря сомневаетесь. Это в обычном каком-нибудь веб-программировании можно не знать ассемблер и принципов работы железа. А для работы с микроконтроллерами — это основа основ. При отладке и поиске багов без знания устройства кода на низшем уровне никак не обойдешься.
Нисколько не умаляю важности знания библиотек для дальнейшей работы. Но всему своё время…
Нисколько не умаляю важности знания библиотек для дальнейшей работы. Но всему своё время…
SysTick->LOAD |= ...;
выглядит странно, не находите?И используйте, пожалуйста, png, а не jpg для скриншотов, то глаза вытекают от такого мыла и шума.
В Keil есть встроенная небольшая операционная система — RTX. Позволяет создать многозадачную систему с плюшками (события, мьютексы, приоритеты..). Таймер SysTick однозначно занимается под эту операционку, это основной таймер такой системы. Задача мигания светодиодом при использовании RTX могла бы вылядеть так:
В периоды ожидания os_dly_wait МК выполняет другие задачи.
Для прикладных задач логичнее использовать таймеры общего назначения, внешние по отношению к ядру ARM. Они в этом микроконтроллере достаточно наворочанные, число регистров конфигурации гораздо больше 4-х.
Мигание можно реализовать через таймер несколькими способами
— с использованием аппаратного прерывания таймера. Состояние светодиода изменяется непосредственно в теле прерывания
— с использованием аппаратного прерывания таймера. В основное тело программы передается метка наступления события (вариант автора статьи).
— настройками таймера в режиме ШИМ. При этом не используются ни прерывания, ни код в основном теле программы.
__task void f_LED (void) {
while(1)
{ PORTС-RXTX!=1;
os_dly_wait (1000);
PORTС-RXTX&=~(1);
os_dly_wait (1000);
}
В периоды ожидания os_dly_wait МК выполняет другие задачи.
Для прикладных задач логичнее использовать таймеры общего назначения, внешние по отношению к ядру ARM. Они в этом микроконтроллере достаточно наворочанные, число регистров конфигурации гораздо больше 4-х.
Мигание можно реализовать через таймер несколькими способами
— с использованием аппаратного прерывания таймера. Состояние светодиода изменяется непосредственно в теле прерывания
— с использованием аппаратного прерывания таймера. В основное тело программы передается метка наступления события (вариант автора статьи).
— настройками таймера в режиме ШИМ. При этом не используются ни прерывания, ни код в основном теле программы.
Они в этом микроконтроллере достаточно навороченные, число регистров конфигурации гораздо больше 4-х.
В данном МК их всего 3 и, в случае когда не требуется использование ОСРВ, лучше задействовать SysTick как один дополнительный таймер для вещей некритичных к точности (например моргание светодиодом, подсчёт периодов) с кратным всем периодам (у меня чаще всего SysTick считает миллисекунды), а внутри уже последовательно считать периоды для каждого таска:
void SysTick_Handler(void)
{
LED_Blink();
static unsigned task1 = SECONDS(1);
if(!(task1--))
{
LED_Blink();
task1 = SECONDS(1);
}
static unsigned task2 = MILLISECONDS(254);
if(!(task2--))
{
UART_Handler();
task2 = SECONDS(1);
}
}
По количеству таймеров согласен — на них сэкономили.
Про RTX и таймеры общего назначения упомянул для полноты картины, в рамках раздела — «Электроника для начинающих».
Когда не использую ОСРВ, тоже применяю SysTick. Но немного по другому — глобальная переменная счетчика миллисекунд наращивается в прерывании SysTick. В основном теле программы использую case c конечными автоматами — примерно так
Код упрощенный, например нет запрета прерываний (надо предотвратить попытку одновременного изменения GlobalTimer). Также есть проблема в ограничении длины GlobalTimer.
Ничто не мешает сделать несколько конечных автоматов и переключаться между ними — получается подобие ОСРВ.
Про RTX и таймеры общего назначения упомянул для полноты картины, в рамках раздела — «Электроника для начинающих».
Когда не использую ОСРВ, тоже применяю SysTick. Но немного по другому — глобальная переменная счетчика миллисекунд наращивается в прерывании SysTick. В основном теле программы использую case c конечными автоматами — примерно так
int delay=500;
int State=BEGIN;
while (1) {
switch (State) {
case BEGIN:
LocalTimer=GlobalTimer+delay;
LedOn();
State=LED_ON;
break;
case LED_ON:
if (LocalTimer>=GlobalTimer) {
LocalTimer=GlobalTimer+delay;
LedOff();
State=LED_OFF;
}
break;
case LED_OFF:
if (LocalTimer>=GlobalTimer) {
LocalTimer=GlobalTimer+delay;
LedOn();
State=LED_ON;
}
break;
}
}
Код упрощенный, например нет запрета прерываний (надо предотвратить попытку одновременного изменения GlobalTimer). Также есть проблема в ограничении длины GlobalTimer.
Ничто не мешает сделать несколько конечных автоматов и переключаться между ними — получается подобие ОСРВ.
Про RTX спасибо. Буду изучать. Но сначала разберу всю периферию без ОС. Раньше пытался подружиться с FreeRTOS, но после недели безуспешных попыток передать двоичный симафор — сдался. Написал свою мини ОС в десяток другой строк и этого хватило.
Sign up to leave a comment.
Переходим с STM32 на российский микроконтроллер К1986ВЕ92QI. Системный таймер (SysTick)