Какие файлы входят в состав проекта на языке с и каково их назначение

Обновлено: 07.07.2024

По мере того, как программы становятся больше (и используют больше файлов), становится всё более утомительным давать предварительные объявления каждой функции, которую вы хотите использовать, и которая определена в другом файле. Было бы неплохо, если бы вы могли поместить все свои предварительные объявления в одно место, а затем импортировать их, когда они вам понадобятся?

Исходные файлы кода C++ (с расширением .cpp ) – это не единственные файлы, которые обычно встречаются в программах на C++. Другой тип файлов – это заголовочный файл (иногда просто заголовок). Заголовочные файлы обычно имеют расширение .h , но иногда вы можете встретить их с расширением .hpp или вообще без расширения. Основная цель заголовочного файла – распространять объявления в исходные файлы кода.

Ключевой момент

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

Использование заголовочных файлов стандартной библиотеки

Рассмотрим следующую программу:

Эта программа печатает « Hello, world! » в консоль с помощью std::cout . Однако эта программа никогда не предоставляла определение или объявление для std::cout , поэтому как компилятор узнает, что такое std::cout ?

Ключевой момент

Когда дело доходит до функций и переменных, стоит помнить, что заголовочные файлы обычно содержат только объявления функций и переменных, а не их определения (в противном случае может произойти нарушение правила одного определения). std::cout объявлен в заголовке iostream, но определен как часть стандартной библиотеки C++, которая автоматически подключается к вашей программе на этапе линкера.

Рисунок 1 Диаграмма процесса сборки

Рисунок 1 – Диаграмма процесса сборки

Лучшая практика

Заголовочные файлы обычно не должны содержать определений функций и переменных, чтобы не нарушать правило одного определения. Исключение сделано для символьных констант (которые мы рассмотрим в уроке «4.14 – const, constexpr и символьные константы»).

Написание собственных заголовочных файлов

А теперь вернемся к примеру, который мы обсуждали в предыдущем уроке. Когда мы закончили, у нас было два файла, add.cpp и main.cpp , которые выглядели так:

(Если вы воссоздаете этот пример с нуля, не забудьте добавить add.cpp в свой проект, чтобы он компилировался).

В этом примере мы использовали предварительное объявление, чтобы при компиляции main.cpp компилятор знал, что такое идентификатор add . Как упоминалось ранее, добавление предварительных объявлений для каждой функции, которую вы хотите использовать, и которая находится в другом файле, вручную может быстро стать утомительным.

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

  1. защита заголовка, о которой мы поговорим более подробно в следующем уроке («2.11 – Защита заголовков»);
  2. фактическое содержимое файла заголовка, которое должно быть предварительными объявлениями для всех идентификаторов, которые мы хотим, чтобы другие файлы могли видеть.

Добавление заголовочного файла в проект работает аналогично добавлению исходного файла (рассматривается в уроке «2.7 – Программы с несколькими файлами исходного кода»). Если вы используете IDE, выполните такие же действия и при появлении запроса выберите Файл заголовка (или C/C++ header) вместо Файла С++ (или C/C++ source). Если вы используете командную строку, просто создайте новый файл в своем любимом редакторе.

Лучшая практика

При именовании файлов заголовков используйте расширение .h .

Заголовочные файлы часто идут в паре с файлами исходного кода, при этом заголовочный файл предоставляет предварительные объявления для соответствующего исходного файла. Поскольку наш заголовочный файл будет содержать предварительное объявление для функций, определенных в add.cpp , мы назовем наш новый заголовочный файл add.h .

Лучшая практика

Если заголовочный файл идет в паре с файлом исходного кода (например, add.h с add.cpp ), они оба должны иметь одинаковое базовое имя ( add ).

Вот наш завершенный заголовочный файл:

Следовательно, наша программа будет правильно компилироваться и компоноваться.

Рисунок 2 Диаграмма процесса сборки

Рисунок 2 – Диаграмма процесса сборки

Включение заголовочного файла в соответствующий исходный файл

Позже вы увидите, что большинство исходных файлов включают свой соответствующий заголовочный файл, даже если он им не нужен. Зачем?

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

Когда мы углубимся в изучение стандартной библиотеки, вы будете включать множество заголовочных файлов библиотек. Если вам потребовалось включение в заголовочном файле, оно, вероятно, понадобилось вам для объявления функции. Это означает, что вам также потребуется такое же включение в исходный файл. Это приведет к тому, что в исходном файле у вас будет копия включений заголовочного файла. Включив заголовочный файл в исходный файл, исходный файл получит доступ ко всему, к чему имел доступ заголовочный файл.

При разработке библиотеки включение заголовочного файла в исходный файл может даже помочь в раннем обнаружении ошибок.

Лучшая практика

При написании исходного файла включите в него соответствующий заголовочный файл (если он существует), даже если он вам пока не нужен.

Поиск и устранение проблем

Если вы получаете ошибку компилятора, указывающую, что add.h не найден, убедитесь, что файл действительно называется add.h . В зависимости от того, как вы его создали и назвали, возможно, файл может иметь имя вроде add (без расширения), add.h.txt или add.hpp . Также убедитесь, что он находится в том же каталоге, что и остальные исходные файлы.

Угловые скобки и двойные кавычки

Вам, наверное, интересно, почему мы используем угловые скобки для iostream и двойные кавычки для add.h . Возможно, что заголовочные файлы с таким же именем могут существовать в нескольких каталогах. Использование угловых скобок и двойных кавычек помогает компилятору понять, где ему следует искать заголовочные файлы.

Когда мы используем угловые скобки, мы сообщаем препроцессору, что это заголовочный файл, который мы не писали сами. Компилятор будет искать заголовок только в каталогах, указанных в каталогах включаемых файлов (include directories). Каталоги включаемых файлов настраиваются как часть вашего проекта / настроек IDE / настроек компилятора и обычно по умолчанию используются для каталогов, содержащих заголовочные файлы, которые поставляются с вашим компилятором и/или ОС. Компилятор не будет искать заголовочный файл в каталоге исходного кода вашего проекта.

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

Правило

Используйте двойные кавычки, чтобы включать заголовочные файлы, которые написали вы или которые, как ожидается, будут найдены в текущем каталоге. Угловые скобки используйте, чтобы включать заголовочные файлы, которые поставляются с вашим компилятором, ОС или сторонними библиотеками, которые вы установили в другом месте своей системы.

Почему у iostream нет расширения .h ?

Другой часто задаваемый вопрос: «Почему iostream (или любой другой заголовочный файл стандартной библиотеки) не имеет расширения .h ?». Ответ заключается в том, что iostream.h – это другой заголовочный файл, отличающийся от iostream ! Для объяснения требуется небольшой урок истории.

Когда C++ был только создан, все файлы в стандартной библиотеке оканчивались расширением .h . Жизнь была последовательной, и это было хорошо. Исходные версии cout и cin были объявлены в iostream.h . Когда комитет ANSI стандартизировал язык, они решили переместить все функции стандартной библиотеки в пространство имен std , чтобы избежать конфликтов имен с пользовательскими идентификаторами. Однако это представляло проблему: если бы они переместили всю функциональность в пространство имен std , ни одна из старых программ (включая iostream.h ) больше не работала бы!

Кроме того, многие библиотеки, унаследованные от C, которые всё еще используются в C++, получили префикс c (например, stdlib.h стал cstdlib ). Функциональные возможности этих библиотек также были перенесены в пространство имен std , чтобы избежать конфликтов имен.

Лучшая практика

При включении заголовочного файла из стандартной библиотеки используйте версию без расширения (без .h ), если она существует. Пользовательские заголовочные файлы по-прежнему должны использовать расширение .h .

Включение заголовочных файлов из других каталогов

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

Хотя это будет компилироваться (при условии, что файлы существуют в этих относительных каталогах), обратная сторона этого подхода состоит в том, что он требует от вас отражения структуры каталогов в вашем коде. Если вы когда-нибудь обновите структуру каталогов, ваш код больше не будет работать.

Лучший способ – сообщить вашему компилятору или IDE, что у вас есть куча заголовочных файлов в каком-то другом месте, чтобы он смотрел туда, когда не может найти их в текущем каталоге. Обычно это можно сделать, установив путь включения (include path) или каталог поиска (search directory) в настройках проекта в IDE.

Для пользователей Visual Studio

Кликните правой кнопкой мыши на своем проекте в обозревателе решений и выберите Свойства (Properties), затем вкладку Каталоги VC++.(VC++ Directories). Здесь вы увидите строку с названием «Включаемые каталоги» (Include Directories). Добавьте каталоги, в которых компилятор должен искать дополнительные заголовочные файлы.

Для пользователей Code::Blocks

В Code:: Blocks перейдите в меню Project (Проект) и выберите Build Options (Параметры сборки), затем вкладку Search directories (Каталоги поиска). Добавьте каталоги, в которых компилятор должен искать дополнительные заголовочные файлы.

Для пользователей GCC/G++

Используя g++, вы можете использовать параметр -I , чтобы указать альтернативный каталог для включения.

Хороший момент в этом подходе заключается в том, что если вы когда-нибудь измените структуру каталогов, вам нужно будет изменить только одну настройку компилятора или IDE, а не каждый файл кода.

Заголовочные файлы могут включать другие заголовочные файлы

Содержимое этих транзитивных включений доступно для использования в вашем файле исходного кода. Однако не следует полагаться на содержимое заголовков, которые включены транзитивно. Реализация заголовочных файлов может со временем меняться или отличаться в разных системах. Если это произойдет, ваш код может компилироваться только на определенных системах или может компилироваться сейчас, но перестать в будущем. Этого легко избежать, явно включив все заголовочные файлы, необходимые для содержимого вашего файла исходного кода.

Лучшая практика

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

Вопрос: Я не включил <someheader.h> , и моя программа всё равно работала! Почему?

Это один из наиболее часто задаваемых вопросов. Ответ: скорее всего, он работает, потому что вы включили какой-то другой заголовок (например, <iostream> ), который сам включает <someheader.h> . Несмотря на то, что ваша программа будет компилироваться, в соответствии с приведенными выше рекомендациями вам не следует полагаться на это. То, что компилируется у вас, может не компилироваться на машине друга.

Лучшая практика

Рекомендации по использованию заголовочных файлов

Вот еще несколько рекомендаций по созданию и использованию заголовочных файлов.

Вопрос правильной организации проекта на языках С и C++ является одним из важнейших при разработке ПО.

Выделяется несколько уровней организации: процедурный уровень (или уровень классов), файловый уровень, уровень библиотек.

Рассматривая программу на уровне процедур или классов, необходимо определить, какую задачу решает та или иная функция (класс), какие входные данные нужны для этого.

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

Файловый уровень проекта определяет, как организованы файлы с исходным текстом, данными и скриптами сборки.

Рассмотрим назначение различных файлов (табл. 1), участвующих в проекте на языках С и C++, собираемых с помощью утилит make и cmake 4.

Назначение файлов с различными расширениями

Исходный текст на языке С

Исходный текст на языке C++

Сборочный скрипт, обрабатываемый утилитой make

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

Файл, обработанный препроцессором

Файл на языке ассемблера

Несвязанный объектный код

Исполняемый файл. В UNIX-системах не имеет специального расширения.

В виндовс - *.сот или *.ехе

Образ памяти, например для программирования встроенного ПЗУ специальной утилитой

Образ памяти, например для программирования встроенного ПЗУ специальной утилитой

Отметим, что в табл. 1 показаны общепринятые расширения файлов, но проектировщик может использовать и другие, более удобные ему расширения, например для отделения файлов по каким-либо признакам.

Настоятельно рекомендуем придерживаться общепринятых расширений файлов, поскольку большинство текстовых редакторов и иных программ ориентированы именно на эти расширения.

На основе обширной практики работы с программами на С и C++ дадим несколько рекомендаций по организации программ, полезных начинающим программистам, на языках С и C++.

1. Один файл - один класс для языка C++ (один файл - сходные по назначению функции для языка С).

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

2. Больше библиотек - проще проект. Сходные взаимосвязанные функции или классы необходимо выделять в функционально законченные библиотеки.

Такой подход особенно эффективен, когда в проекте есть несколько исполняемых файлов, использующих одни и те же функции (классы).

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

Библиотека, как правило, выделяется в отдельный подкаталог в дереве файлов проекта.

  • 3. В заголовочных файлах должны быть только объявления. Часто встречающаяся ошибка у начинающих - попытка описать тело функции или объявить глобальную переменную в заголовочном файле. Этого делать ни в коем случае нельзя, поскольку такой заголовочный файл можно будет включить только один раз в один из файлов с исходными текстами. Включение такого заголовочного файла в разные файлы с исходным текстом приведет к ошибке линкера.
  • 4. Всегда делайте защиту заголовочного файла от повторного включения. Если мы более одного раза включим заголовочный файл в файл с исходным текстом, то чаще всего это вызовет ошибку компилятора, который, обнаружив двойные объявления типов и констант, сгенерирует ошибку. Чтобы этого избежать, необходимо использовать условную компиляцию и в каждом заголовочном файле использовать следующую схему. Предположим, у нас есть заголовочный файл LCD_driver.h. Тогда в начале файла необходимо проверить - определен ли уже некий уникальный символ. Назовем этот символ LCDDRIVERJH. Если данный символ не определен, значит, что файл еще не включался. Если символ определен - то файл уже использовался и его содержимое компилировать не надо.

/** @file tscr.h Функции экранною вывода.

Определяем символ tscr h и компилируем тело заголовочного файла*/

/* Тело заголовочного файла */

Для более глубокого изучения организации проектов рекомендуем изучить [3, 4]. Рассмотрим подробнее, как происходит трансляция программы на языках С и C++.

Теперь давайте рассмотрим из чего состоит проект Qt . В общем, проект Qt имеет такую структуру:

  • файл проекта — описывает файлы, которые входят в проект и содержит необходимые настройки;
  • файлы, входящие в проект (или другие подпроекты, если проект разбит на несколько частей).

Ключевую роль имеет файл проекта с расширением .pro . Он содержит списки файлов: исходных кодов, файлов ресурсов, файлов локализации, форм, других файлов, которые входят в проект, а также файлов подпроектов, если проект состоит из нескольких частей. Этот файл также содержит некоторые настройки программы.

Теперь рассмотрим создание своего проектного файла. Создадим новую папку, где будет размещаться проект (например: custom_project ). Создайте файл (это будет файл проекта) введите его имя с расширением .pro (например: custom_project.pro ). Наш файл пока что пустой, но его уже можно открыть в Qt Creator (воспользуйтесь главным меню : File->Open File or Project.. .).

Создать пустой проект можно с помощью мастера построения проектов. Для этого надо воспользоваться главным меню File->New File or Project.. . либо комбинацией клавиш Ctrl+Shift+N . В окне мастера нужно выбрать раздел Other Project (Другой проект) и тип проекта — Empty Qt Project .

После того, как мы открыли проект, Qt Creator предлагает выбрать комплект для его компиляции. В разделе Projects (Проекты) выберем комплект по умолчанию и нажмём Configure Project . В дереве проекта выберем и откроем файл проекта. Теперь настало время исследовать синтаксис проектных файлов Qt .

Проектный файл обычно содержит несколько настроек в виде специальных переменных, каждая из которых играет свою особую роль. Среди большого количества настроек, которые задают в .pro -файле:

  • тип проекта (приложение, динамическая или статическая библиотека, проект, который состоит из подпроектов);
  • общие настройки проекта;
  • настройки компиляции;
  • путь, где будет размещён исполняемый файл, библиотека или бинарный файл во время процесса компиляции;
  • пути к файлам, библиотекам и другим частям проекта необходимым для компиляции;
  • файлы, входящие в проект;
  • дополнительные действия, которые будут выполняться в процессе компиляции проекта.

Теперь нам осталось добавить в проект файл с текстом программы. Для этого мы снова можем воспользоваться мастером. В категории Files and Classes (Файлы и классы) выберем раздел C++ и выберем тип файла " C++ Source File " ( Файл исходных текстов C++ ). Поскольку это будет главный файл программы, то дадим ему привычное для этого случая название: main.cpp . Текст программы является обычным:

После создания main.cpp , вновь откроем файл проекта и обратим внимание на несколько дополнительных строк:

Переменная SOURCES хранит список .cpp файлов. В табл. 12.1 мы предоставляем список переменных, которые часто участвуют в описании проекта:

Лабораторные работы по курсу «Проектирование встроенных компьютерных систем» (ВКС) призваны закрепить теоретические знания студентов и развить их в навыки осуществления различных этапов проектирования ВКС на основе микроконтроллеров (МК) семейства х51 и программируемых логических интегральных схем (ПЛИС) типа FPGA.

Первая часть пособия описывает пять лабораторных работ, посвященных разработке систем на основе МК семейства х51 (архитектуры MCS-51). МК семейства х51 на протяжении многих лет (начиная с первого представителя — микросхемы Intel 8051) являются весьма популярными среди разработчиков встраиваемых систем самого разного уровня и степени сложности. Об этом говорит как количество устройств, разрабатываемых на их основе, так и многообразие программных средств, предназначенных для их программирования, отладки и тестирования. Одним из таких средств является интегрированная среда разработки MCStudio, разработанная украинским программистом Д. Джулгаковым. Она объединяет в себе текстовый редактор программ на ассемблере, саму программу-ассемблер для трансляции этих программ, программный эмулятор МК, а также редактор аппаратного окружения МК.

Альтернативное направление в области разработки встроенных систем предполагает использование в качестве их основы ПЛИС. Одним из мировых лидеров в изготовлении ПЛИС типа FPGA является фирма Altera. Лабораторные работы по разработке прототипов ВКС на основе FPGA ориентированы на использование учебно-отладочных плат Altera DE2, которыми оснащен один из вычислительных центров лаборатории ОГАХ. В качестве схемной основы для конфигурирования FPGA использован софт-процессор Nios II.

Описание каждой лабораторной работы включает задание, рекомендации к его выполнению, а также пример выполнения.

Общие шаги выполнения лабораторной работы следующие:

Ознакомление с общим заданием на лабораторную работу.

Изучение и/или повторение соответствующего теоретического материала.

Изучение требований к разрабатываемой системе (модулю) и общих рекомендаций к выполнению задания.

Закрепление полученных знаний проработкой контрольных вопросов (приводятся в конце каждой лабораторной работы).

Получение (выбор) индивидуального задания.

Продумывание способов и особенностей решения. Подготовка предварительного проекта (чернового варианта) решения.

Запуск среды MCStudio и подготовка проекта.

Реализация модели системы в соответствии с заданием и требованиями к проекту.

Компиляция программы. Исправление ошибок при необходимости.

Проверка работы, отладка скомпилированной программы.

Отчет по лабораторной работе должен включать в себя титульный лист с указанием номера, темы лабораторной работы, фамилии выполнившего ее студента. Далее — задание на лабораторную работу и решение в виде исходного текста модулей созданного проекта и, если есть, изображения рабочей панели. В конце отчета должны быть сформулированы выводы к лабораторной работе в целом. Пример оформленного отчета приведен в приложении.

Лабораторная работа №1.
Ознакомление с интегрированной средой разработки MCStudio

Научиться применять знания системы команд и директив для написания программ на ассемблере ASM-51. Приобрести базовые навыки разработки программ в среде MCStudio (научиться вводить, компилировать, исправлять программу, а также выполнять ее в различных режимах).

Задание

Научиться разрабатывать и отлаживать программы для МК архитектуры МCS-51 в интегрированной среде разработки MCStudio. Написать и отладить программу, формирующую задержку при помощи циклов. Величина формируемой задержки составляет N секунд, где N — порядковый номер студента в академическом журнале. Оценить отклонение фактически сформированной задержки от заданной величины (не должно превышать 50 мс).

Краткие теоретические сведения

Особенности разработки программ на языке ассемблера ASM-51

Исходные тексты программ на языке ассемблера ASM-51 составляются из инструкций — команд и директив. Каждая строка исходного кода, в общем случае, включает в себя идентификатор, инструкцию, ее операнды и, возможно, поясняющий однострочный комментарий, отделенные знаками табуляции:

идентификатор: инструкция операнд(ы) ; комментарий

Строка может также содержать только комментарий к последующим строкам кода (комментарием считается текст после точки с запятой (;) до конца строки).

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

start: ; адрес первой команды программы

Команды ассемблера ASM-51 соответствуют машинным инструкциям МК. Использование такого низкого уровня программирования позволяет детально оптимизировать скорость и размер программы. Команды размещаются в ячейках памяти программ и составляют программный код. Команды группируются по следующим категориям выполняемых действий:

команды пересылки (MOV, PUSH, POP, CLR, SETB и др.);

арифметические команды (ADD, ADDC, INC, SUBB, DEC, MUL, DIV и др.);

логические и сдвиговые команды (байтовые ANL, ORL, XRL, CPL, RL, RLC, RR, RRC, SWAP);

команды операций с битами (битовые ANL С, ORL С, CLR С, CPL C, MOV C и др.);

команды передачи управления (JZ/JNZ, JC/JNC, JB/JNB, JBC, CJNE, DJNZ, SJMP, AJMP, LJMP, JMP, ACALL, LCALL, RET, RETI, NOP).

Краткие описания команд приведены в учебном пособии [7 – Лекции]. Справочную информацию о командах — их операндах, кодах машинных операций, временах исполнения, влиянии на содержимое флагов — можно почерпнуть из официальной документации на MSC-51-совместимые МК. Подробное описание команд с примерами их использования можно найти в руководствах по программированию МК архитектуры MCS-51 (см., например, [6 – Микушин], с. 147).

Директивы ассемблера являются инструкциями транслятора и позволяют управлять процессом трансляции программы. Вообще говоря, существует несколько различных программ-ассемблеров для МК семейства x51. В каждом из них состав и правила записи (синтаксис) директив могут различаться.

Среда разработки MCStudio поддерживает стандартный набор директив ассемблера ASM-51: BIT, BSEG, CODE, CSEG, DATA, DB, DBIT, DS, DSEG, DW, END, EQU, EXTRN, IDATA, ISEG, NAME, ORG, PUBLIC, RSEG, SEGMENT, SET, USING, XDATA, XSEG. Краткое описание этих директив также приведено в учебном пособии. Более подробную информацию о данных директивах можно найти в руководствах по языку ASM-51 (см., например. [6 – Микушин], с. 277).

1) следует размещать главную программу по нулевому адресу (адресу точки первоначального входа);

2) разрабатываемая программа должна иметь общий циклический характер выполнения с целью недопущения случайного выхода указателя команд (точки выполнения) за пределы используемой памяти.

Основы работы в среде MCStudio

Система MCStudio представляет собой интегрированную среду разработки программного обеспечения однокристальных МК семейства x51. Она объединяет в себе специализированный текстовый редактор программ на ассемблере ASM-51, транслятор с этого языка для компиляции разрабатываемых программ, программный симулятор МК, позволяющий тестировать разработанные программы, а также редактор окружения, позволяющий формировать модели внешнего аппаратного окружения МК.

Обобщенный процесс разработки программы для МК имеет много общего с традиционным процессом разработки компьютерных программ и, в общем случае, включает в себя следующие этапы:

ввод и/или модификация исходного текста программы с помощью текстового редактора (встроенного в среду программирования или альтернативного);

ассемблирование текста программы;

обнаружение и исправление ошибок программы, повторное ассемблирование;

проверка и отладка работы программы, возможно, в пошаговом режиме, с помощью симулятора (при необходимости — с использованием окон наблюдения состояния регистров, флагов, памяти данных и программ, портов и пр.).

Вариант внешнего вида среды MCStudio показан на рис. 1.1.


Рисунок 1.1 – Внешний вид среды MCStudio

Пользовательский интерфейс системы MCStudio интуитивно понятен. Основные команды могут отдаваться через основное меню системы, по нажатии кнопок панелей инструментов или по нажатии «горячих» клавиш.

Работа над новой программой в MCStudio начинается с создания проекта по команде меню «Файл – Создать – Проект». При создании проекта необходимо указать его имя, местоположение папки с файлами проекта и эмулируемую модель МК (см. рис. 1.2).


Рисунок 1.2 – Параметры нового проекта MCStudio

После создания проекта необходимо ввести исходный текст программы в область редактора кода. При сохранении проекта этот текст сохраняется в файле проекта с расширением asm. Хороший стиль программирования на языке ассемблера предполагает структурирование текста программы по колонкам, отделяемым табуляцией (клавиша Tab): идентификаторы, инструкции, аргументы инструкций, комментарии (см. область кода на рис. 1.1). По мере набора текста стоит периодически сохранять его в файл по команде «Файл – Сохранить» (или нажимая комбинацию клавиш Ctrl-S).

По окончании редактирования исходного текста программы необходимо проверить ее работоспособность. Для этого следует, прежде всего, активизировать симулятор МК по команде «Выполнение – Запустить симуляцию» (или по нажатии клавиши F9).

Если синтаксических ошибок в программе нет, будет выполнена трансляция программы, а затем запустится симулятор контроллера. При этом слева от исходного текста появляется колонка адресов и машинных кодов, полученных в результате трансляции. Далее можно выполнять программу в одном из режимов:

в пошаговом режиме — по нажатии клавиши F7 или F8,

до текущего положения курсора — клавиша F4,

до точки прерывания, установленной щелчком по серой вертикальной полосе слева от строк кода,

в обычном (быстром) режиме — клавиша F9.

Полный список доступных режимов выполнения перечислен в меню «Выполнение».

В процессе симуляции можно наблюдать за состоянием основных блоков МК в оконной области «Ресурсы», а также, при необходимости, в оконных областях просмотра памяти (см., например, область «РПД - просмотр» на рис. 1.1).

Как уже указывалось, в связи с недопустимостью выхода точки выполнения (указателя команд) за пределы используемой памяти программа для МК должна иметь циклическую организацию. При необходимости быстрого (не пошагового) выполнения такой программы при отладке имеет смысл выполнить ее однократно, без зацикливания. Для этого следует воспользоваться командой «Выполнение – Выполнять до курсора» (F4), предварительно установив курсор на команду программы, организующую общее зацикливание.

Более подробное описание системы MCStudio и приемов работы в ней можно найти в руководстве пользователя.

Организация программной задержки

mov r0, 255 ; подготовка счетчика цикла

cycle: ; метка начала цикла

; пустое тело цикла

djnz r0, cycle ; команда организации цикла

Однако, один пустой цикл выполнится очень быстро даже при максимальном значении счетчика цикла. Добиться ощутимой человеком задержки порядка нескольких секунд можно, запрограммировав вложенные циклы с пустым циклом в основе. При выполнении и отладке программы с пустым циклом в среде MCStudio следует учесть, что в данной среде по умолчанию включена опция оптимизации выполнения пустого цикла, так что он выполняется за один шаг. Такое поведение системы при необходимости можно отключить в меню «Настройка – Опции системы», пункт «Отладка», опция «Выполнять циклы "djnz $" за один шаг».

Типовой порядок выполнения и рекомендации

Написать код программы в соответствии с заданием.

Подготовить папку для нового проекта.

Запустить среду MCStudio и создать новый проект. Сохранить его под определенным именем в подготовленной папке.

Ввести код программы в окно редактора, сохраняя проект время от времени по мере добавления новых порций кода.

Оттранслировать программу и запустить симуляцию по команде «Выполнение – Запустить симуляцию» (F9).

При наличии синтаксических ошибок внимательно проанализировать отчет о трансляции; внести исправления в исходный код.

Проверить правильность работы программы в эмуляторе. Для этого осуществить пошаговое выполнение программы последовательными командами «Шаг внутрь» (F7) или «Шаг в обход» (F8).

При необходимости модифицировать программу в соответствии с индивидуальным заданием.

Подготовить отчет. Защитить его.

Указанный порядок является общим для всех лабораторных работ, предусматривающих использование среды MCStudio.

В ходе работы может понадобиться обратиться к дополнительным источникам: [4 – Руководство пользователя MCStudio], [6 – Микушин].

Пример

Ниже приведен пример законченной программы, организующей задержку малой величины при помощи одного цикла (DJNZ) с командой NOP в качестве тела цикла.


В данной работе, посвященной формированию задержки, необходимо отслеживать время выполнения программы с целью контроля величины задержки. Для этого следует после запуска эмуляции установить курсор на последнюю команду холостого цикла (jmp $) и дать команду «Выполнить до курсора» (F4). В правом нижнем углу, в строке статуса среды MCStudio, будет отображено время, затраченное на выполнение программы до точки останова (см. рис. 1.3).


Рисунок 1.3 – Наблюдение времени выполнения программы

Задания для самостоятельной проработки

Описать состав файлов проекта среды MCStudio и назначение каждого файла в проекте.

Определить число выполнений внутреннего цикла и общее время выполнения программы в тактах.

Уменьшить отклонение сформированной задержки от заданной величины до 2 мкс.

Написать подпрограмму формирования задержки в 1 секунду и вызвать ее из главной программы нужное число раз. (Cведения о разработке подпрограмм приведены в лабораторной работе №2).

Написать последовательность команд, выполняющих действия, эквивалентные действию команды DJNZ.

Контрольные вопросы

Какие файлы входят в состав проекта среды MCStudio и каково их назначение?

Какова базовая структура программы на ассемблере ASM-51?

Какие существуют режимы выполнения программы в эмуляторе контроллера в среде MCStudio?

В чем заключается существенное отличие между командами и директивами языка ассемблера?

Каков простейший способ организации программной задержки? В чем его преимущества и недостатки?

Читайте также: