PIC и mikroPascal
Паскаль для микроконтроллеров PIC. Часть 1.
Язык высокого уровня Паскаль сегодня активно используется в основном в целях первоначального обучения программированию. Этому способствует хорошая структурированность синтаксиса, а также высокая читаемость исходного текста. К сожалению, несмотря на множество достоинств, Паскаль постепенно теряет свои позиции, уступая место языкам новой волны. Тем не менее, он до сих пор остается очень привлекательным в деле создания не сложных программ и в любительских целях. Именно эти направления делают компилятор mikroPascal и одноименную IDE востребованными для разработки кода под микроконтроллеры.
Структура и особенности программ для микроконтроллеров
Общие моменты программирования на языке Pascal для микроконтроллеров, практически полностью совпадают с классическими стандартами языка. Операторы циклов, условий, формат функций и процедур полностью соответствуют любому другому варианту языка. Отличия проявляются в методах ввода и вывода информации, а также некоторых других особенностях. В данной части статьи рассмотрены общие моменты реализации Pascal для микроконтроллеров PIC.
Структура программы
Как было сказано выше, структура программы в среде mikroPascal не отличается от типовой для используемого языка. Заголовок, описание переменных и констант, процедуры, функции и тело программы задаются с помощью стандартных зарезервированных слов. Единственным исключением становится процедура interrupt, содержащая обработчики прерываний. В общем случае для произвольного алгоритма будет использоваться следующая структура:
program MyProject; //заголовок программы
{ Секция объявления глобальных переменных и констант }
procedure interrupt; //Прерывание
begin
{Тело прерывания}
end;
begin
{ Основная программа }
end.
Типы данных
Согласно стандартам Pascal, все переменные должны быть предварительно объявлены в специальных секциях. Рассматриваемая среда программирования поддерживает множество типов переменных, но в отличие от больших ПК, 8-ми разрядные микроконтроллеры требуют тщательного подхода к выбору типа. Связано это в первую очередь с ограничением размера регистров, и с объемом результирующего машинного кода. Наилучшим вариантом становится использование стандартного типа данных – byte. Его использование предполагает выделение переменным одного регистра в памяти МК. При необходимости пользователь может использовать и другие варианты. Компилятор сам создаст требуемые процедуры обработки больших чисел, но при этом существенно увеличится объем кода.
Тип |
Размер |
Диапазон значений |
bit |
1–bit |
0 или 1 |
sbit |
1–bit |
0 или 1 |
byte, char |
8–bit |
0 .. 255 |
short |
8–bit |
-128 .. 127 |
word |
16–bit |
0 .. 65535 |
integer |
16–bit |
-32768 .. 32767 |
dword |
32–bit |
0 .. 4294967295 |
longint |
32–bit |
-2147483648 .. 2147483647 |
real |
32–bit |
±1.17549435082 * 10-38 .. ±6.80564774407 * 1038 |
Кроме выше приведенных, mikroPascal поддерживает и другие стандартные типы данных языка, такие как массивы (arrays), строки (string), указатели (pointers), записи (records). Их использование ничем не отличается от стандартных правил.
Преобразование типов
Еще одним серьезным вопросом может оказаться преобразование одного типа данных в другой. Без дополнительных функций такое преобразование выполняется, если исходный тип более прост (т.е. имеет меньший размер), по сравнению с конечным. В таком случае достаточно запрограммировать операцию присваивания. В остальных случаях следует ожидать потерю части данных. Успешно могут быть выполнены следующие преобразования:
- bit → byte/char
- byte/char → word
- short → integer
- short → longint
- integer → longint
- integer → real
Для преобразования вещественных типов в строковые и обратно, в компиляторе используется встроенная библиотека Conversions. Процедуры этой библиотеки отлично походят при необходимости преобразования чисел в символы, для отображения на индикаторах различных типов. В частности библиотека содержит и такие элементы, как преобразование чисел в двоично-десятичный код (BCD).
Циклы
Организация циклов в mikroPascal стандартна. Поддерживаются все три основных типа циклов – for, repeat, until. В процессе компиляции каждый из них дает разный код. В общем случае циклы repeat, until позволят получить несколько меньший код. Но с учетом необходимости организации переменной счетчика циклов и ее инкремента/декремента, результирующий объем кода, для всех типов будет одинаков. Поэтому ни один из циклов не имеет особых преимуществ с точки зрения микроконтроллера. Выбор требуемого цикла должен больше зависеть от особенностей программы и предпочтений программиста.
Условия
Также как и циклы, условия в программе реализуются стандартным оператором if then. При его использовании выгодным становится применение полной конструкции типа ЕСЛИ-ТО-ИНАЧЕ (if then else), так как результирующий объем кода меньше чем при использовании двух отдельных условий.
Например, строка if i>10 then porta:=2 else porta:=3; дает результат в 9 команд машинного кода при байтовом типе переменной, а строки if i>10 then porta:=2; if i<=10 then porta:=3; занимают уже 12 команд.
Встроенные и библиотечные функции.
Перенос программ с языка высокого уровня на уровень машинного кода имеет множество особенностей. Одной из них является возможность использовать готовые функции. Такие функции призваны решать какую-либо небольшую задачу, что освобождает программиста от написания части кода. Mikroelektronika в своих программных продуктах предусматривает широкий выбор библиотек, реализующих часто встречающиеся задачи или работу со некоторыми стандартными устройствами, такими как интерфейсы, индикаторы, датчики и т.п.
Весь набор функций делится на встроенные и библиотечные. Встроенные функции иногда называются built-in routine. Результирующий код этих функций или процедур вставляется компилятором в месте вызова. Такой подход упрощает структуру программы и не требует контроля за использованием стека, так как не происходит фактического вызова подпрограмм. При этом объем итоговой программы сильно зависит от количества используемых функций. Например, частый вызов задержки приведет к тому, что ее программный код будет вставлен столько раз, сколько вызовов напишет программист.
В отличие от встроенных, библиотечные функции выделяются в отдельный файл. При компоновке этот файл подключается к основной программе, а вызов процедур выполняется в виде вызова подпрограмм. При частом использовании одних и тех же процедур, библиотечные функции могут дать существенную выгоду по объему кода. Но обязательно следует иметь в виду, что каждый вызов занимает одну позицию стека. Компилятор не отслеживает правильность работы стека, поэтому задача контроля на переполнение целиком ложится на программиста.
Примеры использрвания mikroPascal можной найти в разделе Проекты.
Паскаль для микроконтроллеров PIC. Часть 2.