Итак, подведем итоги
В главе было рассмотрено внутреннее устройство и система команд наиболее распространенного семейства микроконтроллеров. При описании внутренних узлов этого семейства были приведены типовые фрагменты программ, иллюстрирующие работу с этими узлами. Там, где это необходимо, были приведены фрагменты принципиальных схем устройств с использованием рассматриваемого микроконтроллера.
Естественно, что в одной книге невозможно охватить все особенности применения микроконтроллеров. Тем более, что у каждого вида микросхем, принадлежащего к этому семейству, имеются свои особенности. Тем не менее, были рассмотрены узлы, присутствующие во всех микросхемах данного семейства. При необходимости полученные знания можно применить для того, чтобы разобраться и научиться управлять узлами микроконтроллеров, которые не были рассмотрены в данной книге. Даже для микросхем, которые только появятся на рынке через несколько лет.
Однако уметь управлять отдельными узлами микроконтроллера еще не значит уметь писать программы. Точно так же как недостаточно иметь в наличии кирпичи, доски, окна и двери для того, чтобы построить дом.
При написании программ используются специфические приемы, позволяющие реализовывать законченные блоки аппаратуры и организовывать взаимодействие между ними. Там не менее, теперь можно перейти к изучению принципов написания программ для микроконтроллеров, реализующих различные цифровые устройства. Именно этим мы и займемся в следующей главе.
Глава 7
Принципы создания программ для микроконтроллеров
В предыдущих главах были рассмотрены основы построения микропроцессорных систем, подробно описано внутреннее устройство самого распространенного семейства микроконтроллеров - MCS-51. Однако одновременно выяснилось, что для разработки устройства на основе микроконтроллера создания одной только принципиальной схемы недостаточно. Кроме того, требуется разработать и занести во внутреннюю память микроконтроллера программу. Именно она вместе с аппаратурой микроконтроллера и обеспечивает функционирование проектируемого устройства.
В предыдущей главе была рассмотрена система команд микроконтроллера, но знания только системы команд недостаточно для создания программного обеспечения микропроцессорной системы. Нужны специальные программные средства, позволяющие облегчить процесс разработки программы. В настоящее время предлагаются инструментальные интегрированные среды разработки программ.
Микроконтроллеры предназначены для миниатюризации устройств управления, поэтому они интересны, прежде всего, для разработчиков различной аппаратуры. Однако обычно у этих специалистов отсутствуют навыки программирования. В данной главе будут описаны основные принципы разработки программного обеспечения, причем основное внимание будет уделено особенностям построения программ для микроконтроллеров.
Основное внимание будет уделено методу структурного программирования, как наиболее подходящему для современного уровня развития микроконтроллеров. Кроме того, мы остановимся на особенностях построения программ, реагирующих на сигналы, поступающие извне, рассмотрим программную реализацию блоков, которые ранее выполнялись но, и взаимодействие программы с человеком.
Все современные программы пишутся на каких-либо языках программирования, поэтому начнем главу с обзора существующих языков программирования и программ-трансляторов этих языков.
Языки программирования для микроконтроллеров
Программирование для микроконтроллеров, как и программирование для универсальных компьютеров, прошло большой путь развития - от использования машинных кодов до применения современных интегрированных сред, предоставляющих встроенный текстовый редактор, обеспечивающих трансляцию программ, их отладку и загрузку во внутреннюю память микроконтроллеров. В настоящее время исходный текст программы пишется на каком-либо из языков программирования, относящемся к одной из двух групп:
- языки программирования "низкого" уровня;
- языки программирования "высокого" уровня.
Классификация языков программирования приведена на рис. 7.1.

Рис. 7.1. Классификация языков программирования
В языках "низкого" уровня каждому оператору соответствует не более одной машинной команды. В их состав обязательно входит набор машинных команд каждого конкретного процессора. Языки программирования низкого уровня в настоящее время называются ассемблерами (старое название "автокоды"). Для каждого процессора существует своя группа ассемблеров. Ассемблеры для одного и того же процессора различаются между собой дополнительными возможностями, облегчающими программирование.
Языки программирования "высокого" уровня позволяют заменять один оператор несколькими машинными командами. Это увеличивает производительность труда программистов. Кроме того, языки "высокого" уровня позволяют писать программы, которые могут выполняться на различных микропроцессорах. (Естественно, что при этом необходимо использовать программы-трансляторы для соответствующего процессора.) В настоящее время для микроконтроллеров широко используются такие языки программирования высокого уровня, как С и PLM.
О преимуществах и недостатках языков высокого и низкого уровней говорилось достаточно много. Выбор языка программирования зависит от состава аппаратуры, для которой пишется программа, наличия тех или иных средств разработки программного обеспечения, а также от требуемого быстродействия всего программно-аппаратного комплекса в целом.
В тех случаях, когда объем ОЗУ и ПЗУ мал (в районе нескольких килобайтов), альтернативы ассемблеру нет. Именно этот язык программирования позволяет получать самый короткий и самый быстродействующий код программы (при прочих равных условиях, т. к. испортить можно все!).
Языки программирования высокого уровня позволяют значительно сократить время создания программы, но при этом увеличивается ее размер, поэтому использование такого языка программирования для микропроцессорных систем требует достаточно большого объема памяти программ (несколько десятков килобайтов). Увеличение объема программы связано с несколькими факторами:
1. Язык программирования рассчитывается на все случаи жизни, поэтому в большинстве случаев человек мог бы написать программу короче, исключив ненужные в данном конкретном случае проверки или защиты.
2. Если программист не знает, к чему приводит использование тех или других операторов языка программирования, то он может выбирать операторы, неоптимальные как с точки зрения длины машинного кода программы, так и с точки зрения быстродействия программы.
3. Программист не использует подпрограммы там, где они могли бы сократить объем программы, т. к. на языке программирования высокого уровня это всего один или несколько операторов.
Первый из этих пунктов постепенно утрачивает свое значение с появлением все более совершенных трансляторов. Третий пункт тоже решается тем же путем при применении различных видов оптимизаторов, входящих в состав компилятора. Однако в большинстве случаев оптимизатор не может определить одинаковые действия, если они отличаются хотя бы одной командой. Кроме того, оптимизатор работает только в пределах одного программного модуля! Понятие программного модуля будет рассмотрено позднее.
Виды программ-трансляторов
Процесс преобразования операторов исходного языка программирования в машинные коды микропроцессора называется трансляцией исходного текста. В настоящее время ручная трансляция программ практически не используется. Трансляция производится специальными трансляторами.
Существуют два больших класса таких программ: компиляторы и интерпретаторы. При использовании компиляторов весь исходный текст программы преобразуется в машинные коды, и именно эти коды записываются в память микропроцессора. При использовании интерпретатора в память микропроцессора записывается исходный текст программы, а трансляция производится при считывании очередного оператора. Естественно, что быстродействие интерпретаторов намного ниже, чем у компиляторов, т. к., например, при использовании оператора в цикле он транслируется многократно.
Применение интерпретатора может обеспечить выигрыш только в случае его разработки для языка программирования "высокого" уровня. В этом случае может быть сэкономлена внутренняя память программ, а также облегчен процесс отладки (при применении языка программирования BASIC) или облегчен перенос программ с одного типа процессора на другой (в случае использования языка программирования Java).
При программировании на ассемблере применение интерпретатора приводит к проигрышу по всем параметрам, поэтому для языков программирования низкого уровня применяются только программы-компиляторы.
Для программирования микроконтроллеров как на языке программирования "низкого" уровня, так и на языке программирования "высокого" уровня чаще используются компиляторы, поэтому рассмотрим подробнее виды этих трансляторов.