Встраиваемые системы. Проектирование приложений на микроконтроллерах семейства 68HC12/HCS12 с применением языка С
Шрифт:
Следующая рассматриваемая нами директива — это директива #include. Ранее мы установили, что эта директива используется для присоединения к разрабатываемому программному модулю другого файла. При этом у программиста появляется возможность использовать в тексте программы ранее объявленные переменные или вызывать функции, которые были определены в другом файле. Присоединяемые файлы называют заголовочными файлами. Например, следующая запись необходима для присоединения к разрабатываемой программе файла стандартных функций ввода/вывода:
Символы <> указывают на определенное место расположение файла stdio.h в папках директории компилятора.
Назначение директивы #error —
Если в процессе выполнения программа достигнет приведенной строки, то на экран будет выведено приведенное сообщение.
Также для целей отладки используется директива #line. Эта директива отмечает номерами те инструкции программы, которые следуют за директивой. В результате, в процессе отладки можно идентифицировать тот фрагмент программы, который исполняется в текущий момент отладки.
Функции директивы #pragma определяются конкретным типом используемого компилятора. Для компилятора ICC12 эта директива определения сегментов данных и программы в исходном тексте программы на Си, для объявления подпрограмм прерывания, а также для присвоения желаемых значений ячейкам памяти с фиксированными адресами. Последнее позволяет инициализировать таблицу векторов прерываний в микроконтроллерах. Приведенный ниже пример демонстрирует использование директивы #pragma для объявления подпрограммы с именем TOISR в качестве подпрограммы прерывания:
Объявление подпрограммы TOISR как подпрограммы прерывания информирует компилятор о том, что в конце этой подпрограммы он должен расположить ассемблерную инструкцию возврата из прерывания rti. В конце обычной функции компилятор подставляет инструкцию возврата из подпрограммы rts.
Директива #pragma также используется для задания начального адреса расположения в памяти сегментов программного кода или кодов данных. Запишем вектор прерывания для подпрограммы TOISR в таблицу векторов прерывания МК. Мы знаем, что в соответствие с картой памяти МК, вектор прерывания по переполнению таймера должен располагаться по адресу 0x0B1E. Следующая запись помещает адрес начала подпрограммы TOISR в две ячейки памяти, начиная с адреса 0x0B1E:
Более подробно оформление подпрограмм прерывания мы обсудим в главе 4.
3.7. Конструкции программирования
В теории программирования доказано, что любая программа может быть закодирована с помощью комбинаций трёх конструкций: последовательность операторов, выбор и итерация. В этом разделе мы рассмотрим набор операторов языка Си и типовые примеры их использования для реализации конструкций цикла (итерации) и принятия решения (выбора).
3.8. Операторы для организации программных циклов
В языке Си существует несколько операторов, которые позволяют реализовать циклические вычисления (итерации). В этом параграфе мы рассмотрим программные конструкции циклов с операторами for, while, do while.
3.8.1. Оператор FOR
Оператор for предназначен для реализации циклов со счетчиком. В операторе for могут автоматически реализоваться сразу три операции: инициализация счётчика цикла, проверка его значения и модификация. Синтаксис оператора for:
Рассмотрим типичный пример реализации цикла с оператором for:
В строке 1 записывается сам оператор for, за которым обязательно следуют три выражения, заключенные в круглые скобки. Выражение 1 вычисляется один и только один раз перед проверкой условия цикла. В нашем примере выражение 1 присваивает начальное значение переменной i. Выражения два и три могут иметь произвольный характер, но обычно их используют для проверки и модификации условия продолжения цикла. Выражение 2 задаёт условие продолжения цикла. Если его значение отлично от нуля (истина), будут выполнены операторы 3…7, составляющие тело цикла. После этого вычисляется выражение 3, указанное в скобках первой строки. В нашем примере выражение i = i++ = i + 1 осуществляет увеличение на 1 внутреннего счетчика циклов оператора for. Поэтому операторы тела цикла 3…7 будут выполняться 10 раз при значениях переменной цикла i от 0 до 9. В конце первого цикла значение i будет равно 1, в конце второго — i=2, и т.д. В конце десятого цикла переменная i примет значение 10. Далее начнется исполнение 11-ого цикла оператора for, но, проанализировав условие выражения 2 оператора for, программа выйдет из цикла, не исполняя операторов тела цикла.
Достаточно часто переменная счетчика циклов оператора for используется также в теле цикла этого оператора. Например, следующий программный фрагмент вычисляет таблицу соответствия значений температуры, записанных по шкале Цельсия и по шкале Фаренгейта, и последовательно выводит эти значения на экран монитора. Диапазон исходных значений температуры составляет от –10°C до +40°C.
Как видите, значение переменной k используется как параметр для вычисления новых значений температуры в теле цикла.
3.8.2. Оператор WHILE
Второй способ организации циклов использует оператор while. Применение оператора while иллюстрирует следующий программный фрагмент:
В отличие от оператора for, переменная k, используемая в качестве счетчика циклов, должна быть инициализирована перед оператором while, например, в строке 1. Обратите внимание, что в строке 2 в скобках оператора while записано всего лишь одно выражение, которое называется условием цикла. Выполнение оператора while начинается с вычисления этого выражения. Если значение выражения отлично от нуля («истина»), то выполняются операторы 4…6 тела цикла. После выполнения операторов тела цикла снова вычисляется выражение условия и процесс повторяется. Таким образом, выполнение тела цикла происходит пока значение выражения условия цикла отлично от нуля («истина»).