Сам таймер 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:
*------------------ File Begin -------------------*
typedef struct
{
  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */
  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */
  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */
  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;
 
/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */
 
#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */
 
#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */
 
#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */
 
/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */
 
/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */
 
/* SysTick Calibration Register Definitions */
#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */
 
#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */
 
#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */
/*@}*/ /* end of group CMSIS_CM3_SysTick */
*------------------ File End -------------------*


Нам там нужны имена битов. Вот они:
SysTick_CTRL_CLKSOURCE_Msk, SysTick_CTRL_TICKINT_Msk, SysTick_CTRL_ENABLE_Msk.


Конфигурация таймера на тик в 1ms, таким образом, будет выглядеть примерно 
так:
*------------------ File Begin -------------------*
#define F_CPU		72000000UL	// Тактовая у нас 72МГЦ
#define TimerTick	F_CPU/1000-1	// Нам нужен килогерц
 
SysTick->LOAD=TimerTick;	// Загрузка значения
SysTick->VAL=TimerTick;		// Обнуляем таймеры и флаги. Записью, помните? 
 
SysTick->CTRL=	SysTick_CTRL_CLKSOURCE_Msk |
                SysTick_CTRL_TICKINT_Msk   |
                SysTick_CTRL_ENABLE_Msk;
*------------------ File End -------------------*


 *** Обработчик прерывания SysTick ***
Где взять имя обработчика? Да из таблицы прерываний. Поглядеть, если кто 
не помнит, можно в STM32F10x.s

Вот ее кусочек:
*------------------ File Begin -------------------*
; Vector Table Mapped to Address 0 at Reset
 
                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
 
__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     DebugMon_Handler          ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     PendSV_Handler            ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler
*------------------ File End -------------------*
 

Имя есть. Осталось организовать прерывание:
*------------------ File Begin -------------------*
//SysTick Interrupt
void SysTick_Handler(void)
{
	// Тут будем делать нечто полезное. Например, ставить бит B.05
	GPIOB->BSRR = GPIO_BSRR_BS5;	// Set bit
}
*------------------ File End -------------------*
 

А сбрасывать его будет в главном цикле. В результате мы получим иголки с 
частотой 1Кгц которые хорошо видно осциллографом :)


Вот так выглядит полный код примера:
*------------------ File Begin -------------------*
#include "stm32f10x.h"
#define F_CPU 		72000000UL
#define TimerTick	F_CPU/1000-1
 
void Delay(uint32_t Val);
 
//SysTick Interrupt
void SysTick_Handler(void)
{
	GPIOB->BSRR = GPIO_BSRR_BS5;		// Set bit
}
 
int main(void)
{
	SystemInit();
 
	RCC->APB2ENR 	|= RCC_APB2ENR_IOPBEN;
	// Config CRL
	GPIOB->CRL	&= ~GPIO_CRL_CNF5;	// Clear CNF bit 5. Mode 00 - Push-Pull 
	GPIOB->CRL 	|= GPIO_CRL_MODE5_0;	// Set bit MODE0 for pin 5. Mode 01 = Max Speed 10MHz
 
 
	SysTick->LOAD=TimerTick;
	SysTick->VAL=TimerTick;
	SysTick->CTRL=	SysTick_CTRL_CLKSOURCE_Msk |
	                SysTick_CTRL_TICKINT_Msk   |
	                SysTick_CTRL_ENABLE_Msk;;
	while(1)
	{
		GPIOB->BSRR = GPIO_BSRR_BR5;		// Clear bit
	}
}
*------------------ File End -------------------*


 *** Функции CMSIS ***

У Таймера, раз он часть ядра, есть функция конфигурации в CMSIS. Описана 
она в core_cm3.h и выглядит так:
*------------------ File Begin -------------------*
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            	/* Reload value impossible */
 
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      	/* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  	/* set Priority for Cortex-M0 System Interrupts */
 
  SysTick->VAL   = 0;                                          	/* Load the SysTick Counter Value */
  SysTick->CTRL  = 	SysTick_CTRL_CLKSOURCE_Msk | 
                   	SysTick_CTRL_TICKINT_Msk   | 
                   	SysTick_CTRL_ENABLE_Msk; 		/* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                   /* Function successful */
}
*------------------ File End -------------------*

То же самое, что и мы сделали вручную. Только есть проверка на 
корректность значения и обрезка лишних битов. Возвращает 1 если данные 
некорректные. Ну и еще там приоритет ставится если ядро М0 (это кстати хз 
зачем? У M0 же должна быть своя версия CMSIS?)


Так что таймер можно загрузить и следующей фигней:
	SysTick_Config(TimerTick);

Для LPC все совершенно аналогично. До последней буковки можно сказать. 
Т.к. это фича не STM32, а ядра и описана в CMSIS. Т.е. едина для всех.

===============================================================================

Для конфигурации таймера в файле core_cm3.h есть функция 
SysTick_Config(uint32_t ticks), в качестве аргумента которой передается 
коэффициент деления тактовой частоты для получения необходимой временной 
задержки.
~~~~~~~~~~~~~~~~~~~~
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */

  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}
~~~~~~~~~~~~~~~~~~~~

Это значение заносится в регистр перезагрузки. В самом начале выполняется 
проверка на то, что данная величина не выходит за максимальный предел, 
поскольку счетчик 24-разрядный, а передаваемый аргумент функции является 
32-разрядным числом и необходимо об этом помнить.

Далее в функции конфигурации SysTick_Config() задается уровень приоритета 
прерывания, обнуляется счетный регистр, разрешается генерация прерывания, 
задается источник тактирования и разрешается работа таймера – запускается 
счет.

По умолчанию тактовая частота этого таймера будет равна системной тактовой 
частоте SYSCLK. Если же нужно задать частоту тактирования таймера как 
SYSCLK/8, то уже после этой функции инициализации можно вызвать функцию

	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8),

которая находится в файле misc.c. Для этого к проекту необходимо 
подключить файлы misc.c и misc.h.


В данных примерах таймер настраивается на генерацию прерывания через 
“базовый” промежуток времени, равный 1 миллисекунде. Затем, уже с помощью 
программного цикла формируется задержка, равная 1 секунде. Через каждую 
секунду происходит попеременное зажигание/гашение светодиодов платы, здесь 
я не стал особо мудрить, поскольку основной задачей была настройка 
системного таймера для генерации прерываний через определенный интервал.

Для задания длительности между двумя последующими прерываниями от таймера, 
в регистр перезагрузки необходимо записать значение, которое 
рассчитывается по простой формуле:

 * 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 МГц.

На плате STM32L-DISCOVERY внешнего кварца нет и после начальной 
инициализации системная тактовая частота формируется внутренним источником 
MSI и равна 2,097 МГц.

Расчет перезагружаемых значений приведен ниже, в комментариях примеров программ для этих плат.


Код программы для платы STM32VL-DISCOVERY (контроллер STM32F100)
~~~~~~~~~~~~~~~~~~~~
#include "stm32f10x.h"

static __IO uint32_t TimingDelay;

void Delay_ms(__IO uint32_t nTime);

GPIO_InitTypeDef    GPIO_InitStruct;

int main()
{
  /*Вызов функции конфигурации системного таймера 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
    (Необходимо самостоятельно посчитать эту величину и вставить в качестве
    параметра при вызове функции);
  --Обнуляет счетчик
  --Запускает счет системного таймера*/
  SysTick_Config(24000);

  //Включаем тактирование порта 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); //Заносим заданные настройки в регистры порта

  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 с
  }
}

//Функция временной задержки
void Delay_ms(__IO uint32_t nTime)
{
  TimingDelay = nTime;
  while(TimingDelay != 0);
}

void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}

//Обработчик прерывания системного таймера
void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}
~~~~~~~~~~~~~~~~~~~~


Код программы для платы STM32L-DISCOVERY (контроллер STM32L152)
~~~~~~~~~~~~~~~~~~~~
#include "stm32l1xx.h"

static __IO uint32_t TimingDelay;

void Delay_ms(__IO uint32_t nTime);

GPIO_InitTypeDef    GPIO_InitStruct;

int main()
{
    /*Вызов функции конфигурации системного таймера 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
    (Необходимо самостоятельно посчитать эту величину и вставить в качестве
    параметра при вызове функции);
  --Обнуляет счетчик
  --Запускает счет системного таймера*/
  SysTick_Config(2097);

  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

  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 с
  }
}

//Функция временной задержки
void Delay_ms(__IO uint32_t nTime)
{
  TimingDelay = nTime;
  while(TimingDelay != 0);
}

void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}

//Обработчик прерывания системного таймера
void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}
~~~~~~~~~~~~~~~~~~~~

===============================================================================

 *** Литература: ***

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 — Системный таймер
http://easyelectronics.ru/arm-uchebnyj-kurs-systick-sistemnyj-tajmer.html

STM32. Системный таймер SysTick.
http://chipspace.ru/stm32-systick/
