Кафедра света и электричества

Начинаем осваивать ассемблер
Ab asm !

Концептуальным аналогом великой программы "Hello, world!" для встроенных систем является мигание светодиодом. Решим эту задачу, используя плату Discovery в качестве программатора, и плату собственной разработки на контроллере STM8S105K4. Для простоты и иллюстративности напишем программу на ассемблере. Первым делом придется слегка вандализировать Discovery, а именно либо удалить перемычки на плате, либо просто сломать плату пополам. Вот как выглядит плата после удаления перемычек:

Далее нужно запустить среду разработки ST Visual Develop. Создаем новый Workspace и Project (первая картинка из 5 одинаковых в диалоге "New Workspace"). Лучше всего создать отдельный каталог для проекта. В качестве ToolChain выбираем ST Assembler Linker.

Следующим шагом выбираем тип процессора. Среда автоматически создает прототип, который состоит из трех файлов. Первые два - mapping.inc и mapping.asm задают распределение памяти. Третий - main.asm - содержит процедуры очистки памяти и стека, после чего идет зацикливание программы. Проверим, что проект компилируется (F7). Если все прошло нормально, то можно заняться светодиодами.

По каким-то странным причинам, известным только инженерам ST Microelectronics, в проект автоматически не включаются описания портов и регистров контроллера. Это надо сделать самостоятельно, добавив в начало файла main.asm строку

#include "STM8S105K4.inc"

Кроме того, нужно добавить к проекту файл c именем stm8s105k4.asm (он находится в каталоге asm/include). Теперь все готово для программирования.

Ассемблер, разработанный в недрах ST Microelectronics отличается странным синтаксисом. Например, метки следует начинать с первой позиции. Длина метки ограничена 30 символами. Явно кто-то из разработчиков в детстве учил Fortran или Cobol. После метки надо ставить точку и букву l,w или b, означающую разрядность адреса - 32, 16 или 8 бит.

Аппаратная часть

Здесь все достаточно просто: светодиоды подключаются к любым ногам контроллера, обозначенным как (HS) - High Sink. Для простоты поставим диод между плюсом питания и выводом PD0 контроллера. Для подобных экспериментов полезно купить десяток-другой красных пятивольтовых светодиодов со встроенными резисторами. Как показывает практика, они почти универсальны и работают начиная от напряжения в 1.8 Вольта.

Посмотрим внимательно на программу, которую нам сгенерировала среда STVD. Она производит очистку памяти и стека, а потом зацикливается:

infinite_loop.l
   jra infinite_loop

Вот перед этой конструкцией мы и вставим код для включения светодиода. Как и в случае ATMEL, он будет состоять из одной инструкции, конфигурирующей вывод микроконтроллера как выход. Предполагается, что состояние вывода равно 0 по умолчанию.

   mov PD_DDR,#1

Сразу же заметим, что редактор STVD был сделан явно впопыхах, команды, имеющиеся только у STM8, он не подсвечивает. Контекстная подсказка по командам ассемблера отсутствует, указатель в PDF достаточно бестолковый. Описание директив ассемблера содержится в старательно спрятанном файле с названием asm_lnk_user_manual.pdf.
Присоединим нашу плату к разъему SWIM, скомпилируем программу и загрузим ее в контроллер командой Debug-Start Debugging. Дальше можно поставить курсор на строку с командой включения светодиода и нажать Ctrl+F10 - выполнить до курсора. Нажимаем F10 - одиночный шаг отладки - и убеждаемся, что диод включился.

Теперь нужно заставить диод мигать. Сделаем простецкий пустой цикл с использованием регистра X. В результате наша программа будет выглядеть так:

   mov PD_DDR,#1
blink.l
   clrw X
loop.l
   incw X
   cpw X, #60000
   jrult loop
   bcpl PD_DDR,#0
   jra blink

Компилируем и запускаем программу. Диод мигает, хотя и достаточно часто. Как видно, цикл выполняется 60000 раз, но этого недостаточно. Видимо, придется придумывать какой-то другой способ формирования задержек. Заметим, что в библиотеке GNU C для AVR были неплохие функции _delay_ms и _delay_us. В библиотеке от Raisonance такие удобства, увы, не предусмотрены. Что можно сделать по этому поводу - см. в следующей части.