понедельник, 27 февраля 2012 г.

I & STM32-discovery part9 - timers

После добавления прерывания на кнопку почти ничего не изменилось, т.к. программа как нагружала ядро мк работой по подсчету тактов так и нагружает. Сейчас мы попробуем разгрузить ядро используя такой замечательный блок мк как таймер.



Таймер в своем первоначальном представлении это счетчик, но в современном мк это не просто счетчик - количество альтернативных функций у самого продвинутого из таймеров того же stm32f100rb больше десятка. Особенностью серии stm32 является большое количество (5 в самой младшей серии) различных таймеров. Каждый из них может выполнять определенное количество действий в зависимости от типа. Существует три группы таймеров - базовые, основные и расширенного функционала. Основные разработчики мк поделили еще на 3 подгруппы(на этом мы подробно остановимся в одной из следующих статей).

Базовые таймера (TIM6 & TIM7).
Два 16битных таймера, автоматически перезагружаемых с программируемым предделителем. Изначально объедены в связку с ЦАП и по прерываниям и по дма и по конструктиву - т.е. по сути являются частью схемы преобразователя, но могут использоваться отдельно. Эти два таймера не имеют внешних выводов и поэтому могут использоваться только программно либо в качестве таймера семплов для ЦАП.
Таймера включают:
  • 16битный автоперезагружаемый инкрементный счетчик
  • 16битный программируемый предделитель(функция "смена на лету")
  • Схема синхронизации с ЦАП
  • Прерывания/НДП по переполнению.
Вот собственно и весь функционал этих таймеров. Но для нас он более чем достаточен.
Опишем в кратце алгоритм нашей программы:
В основном коде мы производим начальную инициализацию портов и подключаем необходимую периферию, затем включаем прерывания по таймеру и внешнее на пине 0.
В прерывании что таймера что внешнего источника мы просто инвертируем состояние пинов на которых висят светодиоды.
Вот и все. Теперь посмотрим как это будет выглядеть в коде.

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

nis@jane ~/stm32/examples $ cp -a 03-exti-int/ 04-tim6
nis@jane ~/stm32/examples $ cd 04-tim6/

Для начала упорядочим код и создадим main.h куда собственно скидаем все константы.
main.h


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


И наконец основной код. Мы упразднили бесконечный цикл и в основном коде оставили только инициализацию периферии.
main.c


Как видно из кода мы настроили предделитель на значение 8000 - 1(т.к. значение фактически будет значение регистра + 1 такт) и регистра обновления. Т.е. мигать у нас будет с частотой 1 сек.

После этих манипуляций с кодом, соберём проект и зальем прошивку в мк

nis@jane ~/stm32/examples/04-tim6 $ make all write
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld   -c -o startup.o startup.c
arm-softfloat-linux-gnueabi-gcc -g -O2 -mlittle-endian -mthumb -ffreestanding -nostdlib -nostdinc -mcpu=cortex-m3 -DSTM32F10X_MD_VL -I. -I../../stlink/example/libs_stm/inc/base -I../../stlink/example/libs_stm/inc/core_support -I../../stlink/example/libs_stm/inc/device_support -Wl,-T,stm32f100xb_flash.ld -o firmware.elf main.o sys_init.o startup.o -L.
arm-softfloat-linux-gnueabi-objcopy -O binary firmware.elf firmware.bin
st-flash write v1 firmware.bin 0x8000000
2012-02-27T15:08:25 INFO src/stlink-common.c: Loading device parameters....
2012-02-27T15:08:25 INFO src/stlink-common.c: Device connected is: F1 Medium-density Value Line device
2012-02-27T15:08:25 INFO src/stlink-common.c: SRAM size: 0x2000 bytes (8 KiB), Flash: 0x20000 bytes (128 KiB) in pages of 1024 bytes
2012-02-27T15:08:25 INFO src/stlink-sg.c: Successfully opened a stlink v1 debugger
2012-02-27T15:08:25 INFO src/stlink-common.c: Attempting to write 608 (0x260) bytes to stm32 address: 134217728 (0x8000000)
2012-02-27T15:08:25 INFO src/stlink-common.c: Erasing flash page at addr: 0x8000000
2012-02-27T15:08:25 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-27T15:08:26 INFO src/stlink-common.c: Finished erasing 1 pages of 1024 (0x400) bytes
2012-02-27T15:08:26 INFO src/stlink-common.c: Starting Flash write for VL core id
2012-02-27T15:08:26 INFO src/stlink-common.c: Successfully loaded flash loader in sram
2012-02-27T15:08:26 INFO src/stlink-common.c: Writing flash block 0 of size 64 (0x40)
...
2012-02-27T15:08:26 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-27T15:08:26 INFO src/stlink-common.c: Writing flash block 9 of size 64 (0x40)
2012-02-27T15:08:26 INFO src/stlink-common.c: Successfully unlocked flash
2012-02-27T15:08:26 INFO src/stlink-common.c: Starting verification of write complete
2012-02-27T15:08:26 INFO src/stlink-common.c: Flash written and verified! jolly good!

И как обычно видео:
Добавление прерываний не только сократило код(пусть не намного), но и разгрузило ядро мк - т.к теперь основную часть времени он крутится в бесконечном цикле и лишь меньше одного 1% общего времени обрабатывает прерывания. Кстати один грамотно настроенный таймер может сократить объем кода в несколько раз.
На этом все.

Комментариев нет:

Отправить комментарий