Pull to refresh

Comments 17

Строго говоря, SysTick — это часть ядра Cortex M3, поэтому работа с ним в разных контроллерах на этом ядре практически идентична.
По-хорошему, вам даже не обязательно было трогать регистры; в файле core_cm3.h уже есть готовая функция для его настройки — SysTick_Config.

Полезнее было бы рассмотреть работу с родной периферией миландра в каком-нибудь более-менее реалистичном сценарии. Чтение ADC через DMA, например.
Строго говоря, SysTick — это часть ядра Cortex M3, поэтому работа с ним в разных контроллерах на этом ядре практически идентична.
Полезнее было бы рассмотреть работу с родной периферией миландра в каком-нибудь более-менее реалистичном сценарии. Чтение ADC через DMA, например.

Я знаю. Он нужен для следующего урока, посвященного системам тактирования МК. Для наглядности.
По-хорошему, вам даже не обязательно было трогать регистры; в файле core_cm3.h уже есть готовая функция для его настройки — SysTick_Config.

Про функцию тоже знаю. Но куда приятнее настроить вручную. Чтобы знать наверняка, что все правильно.
Но куда приятнее настроить вручную. Чтобы знать наверняка, что все правильно.

Я бы сказал, чтобы было проще ошибиться.
Дальше без SPL будет сложно; хотя в ней полно ошибок, код с регистрами пишется и читается значительно тяжелее.
Как раз в образовательных целях написание своей функции работы с таймером полезней, чем использование библиотечной… Использование библиотечной функции ничего кроме знания названия этой функции новичку не даст…
Я очень сомневаюсь, что знание о стандартизированных регистрах ценнее, чем знание о стандартизированной библиотечной функции.
Зря сомневаетесь. Это в обычном каком-нибудь веб-программировании можно не знать ассемблер и принципов работы железа. А для работы с микроконтроллерами — это основа основ. При отладке и поиске багов без знания устройства кода на низшем уровне никак не обойдешься.
Нисколько не умаляю важности знания библиотек для дальнейшей работы. Но всему своё время…
Я не спорю, что знание ассемблера и принципов работы железа — основа (хотя современные тенденции от этого уводят изо всех сил).
Но каждый бит в каждом регистре все равно не запомнишь.
И не надо биты запоминать. На то документация и дана. Важно понимать принцип. Этого документацией не заменишь…
SysTick->LOAD |= ...;
выглядит странно, не находите?

И используйте, пожалуйста, png, а не jpg для скриншотов, то глаза вытекают от такого мыла и шума.
SysTick->LOAD |= ...;
выглядит странно, не находите?

Ошибка. Спасибо, исправил.
И используйте, пожалуйста, png, а не jpg для скриншотов, то глаза вытекают от такого мыла и шума.

Заменил код. Спасибо. В будущем буду выкладывать в png.
В Keil есть встроенная небольшая операционная система — RTX. Позволяет создать многозадачную систему с плюшками (события, мьютексы, приоритеты..). Таймер SysTick однозначно занимается под эту операционку, это основной таймер такой системы. Задача мигания светодиодом при использовании RTX могла бы вылядеть так:
__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 конечными автоматами — примерно так

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, но после недели безуспешных попыток передать двоичный симафор — сдался. Написал свою мини ОС в десяток другой строк и этого хватило.
Only those users with full accounts are able to leave comments. Log in, please.