Ноя 10 2010

Таймер SysTick

В микроконтроллерах LPC17xx (ядро Cortex M3), наряду с обычными универсальными таймерами-счётчиками в количестве 4-х штук есть два дополнительных таймера: SysTick и Repetitive Interrupt Timer, использование которых позволяет освободить универсальные таймеры-счётчики для других целей.

Примечание

Если быть точным, то SysTick есть, по крайней мере, у всех микроконтроллеров с ядром Cortex M3, однако код, приведённый ниже, был написан именно для LPC1768 в среде разработки IAR.

Ниже речь пойдёт о таймере SysTick. Он предназначен для генерации прерываний с фиксированной частотой и может быть использован как основной системный таймер. Частота генерации прерываний по умолчанию составляет 100 Гц, однако может быть настроена программно в очень широких пределах. Таймер имеет 24-битный счётный регистр, и тактируется системной тактовой частотой.

Частота генерации прерываний равна:

где Reload — загружаемое в таймер значение, cclk — тактовая частота.

По умолчанию значение регистра STRELOAD (значение Reload) равно 0, для получения частоты генерации 100 Гц можно воспользоваться для его инициализации значением, хранящимся в специальном регистре STCALIB = F423F16 = 99999910, хотя можно, конечно, просто записать в STRELOAD нужное значение. При этом здесь и далее подразумевается, что тактовая частота микроконтроллера равна 100 МГц.

Для использования таймера нам понадобится следующее:
1. написать код инициализации таймера
2. написать обработчик прерывания таймера

Код инициализации таймера:

STRELOAD  =  999999;  //Устанавливаем значение Reload
//источник тактирования - системный тактовый генератор
//(при CLKSOURCE = 0 источником тактовых импульсов служит вывод STCLK)
SYSTICKCSR_bit.CLKSOURCE = 1;
SYSTICKCSR_bit.ENABLE = 1;  //cчёт разрешён
SYSTICKCSR_bit.TICKINT = 1;  // генерировать прерывание

Код обработчика прерывания:

void SysTick_Handler(void)
{
 ... do something useful
// извещаем контроллер прерываний об окончании обработки прерывания
 ICSR_bit.PENDSTCLR = 1; 
}

Разумеется, обработчик SysTick_Handler должен быть прописан в таблице векторов прерываний (для проектов IAR она, как правило, содержится в файле cstartup_M.s, там не нужно ничего менять, достаточно скопировать имя нужного обработчка.)

Следует отметить, что прерывание системного таймера снимается с обработки не так, как большая часть «обычных» прерываний, для снятия которых используются регистры ICPR0-ICPR3. Почему это так? Это не обычное прерывание. SysTick —  это системное исключение. Их в архитектуре контроллера немного, всего пять. Помимо рассмотренного, системными исключениями являются: Bus fault, Usage fault, SVCall и PendSV.

Так как SysTick не является обычным прерыванием, для работы с ним не могут быть использованы обычные функции разрешения/запрета прерывания и установки приоритета прерывания.

Разрешение прерывания производится так, как показано в коде инициализации таймера: SYSTICKCSR_bit.TICKINT = 1.

Приоритеты прерываний для указанных выше особых системных источников прерываний указываются в специальных регистрах: SHPR1-SHPR3. Приоритет может быть в диапазоне от 0 до 31, следовательно, задаётся 5-битным полем. Приоритет SysTick задаётся в регистре SHPR3 битами 24-31 (т.е., фактически, 27-31, биты 24-26 не используются). Как обычно, наивысшему приоритету соответствует значение 0, самому низкому — значение 31. При назначении приоритетов не следует забывать о существующей в Cortex M3 возможности группировки прерываний.

Полное описание таймера SysTick приведено в [1], в разделах

«Chapter 23: LPC17xx System Tick Timer»

«Chapter 34: Appendix: Cortex-M3 User Guide/4.4 System timer, SysTick»

«Chapter 34: Appendix: Cortex-M3 User Guide/4.3.4 Interrupt Control and State Register

Литература:

1. UM10360. LPC17xx User Manual. Rev 01 — 4 January 2010.