РАЗРАБОТКА И ОТЛАДКА УСТРОЙСТВ НА МК (Часть 1)
А. ДОЛГИЙ, г. Москва
В этом номере журнала мы начинаем публикацию цикла статей, в которых подробнейшим образом на "живых" примерах рассматриваются основные приемы разработки, программирования и отладки устройств на микроконтроллере (МК) PIC16F84 из самого популярного сегодня семейства - PICmicro фирмы Microchip. Статьи будут полезны и тем, кто собирается применять МК других типов. Мы надеемся, что публикация цикла поможет многим радиолюбителям приступить к разработке аппаратуры на современной элементной базе.
Среди цифровых интегральных микросхем МК сегодня занимают примерно такое же место, как операционные усилители среди аналоговых. Это - универсальные приборы, их применение в электронных устройствах самого различного назначения постоянно расширяется. Разработкой и производством МК занимаются почти все крупные и многие средние фирмы, специализирующиеся в области полупроводниковой электроники. Перечень и основные параметры МК некоторых популярных семейств можно найти, например, в [1].
Современные МК (их раньше называли однокристальными микро-ЭВМ) объединяют в своем корпусе мощное процессорное ядро, запоминающие устройства для хранения выполняемой программы и данных, устройства приема входных и формирования выходных сигналов, многочисленные вспомогательные узлы. Общая тенденция современного "микроконтроллерострое-ния" - уменьшение числа внешних элементов, необходимых для нормальной работы. На кристалле микросхемы размещают не только компараторы, аналого-цифровые и цифроаналоговые преобразователи, но и всевозможные нагрузочные и "подтягивающие" резисторы, цепи сброса.
Выходные буферы МК рассчитывают на непосредственное подключение наиболее типичных нагрузок, например, светодиодных индикаторов. Почти любой из выводов МК (за исключением, конечно, выводов общего провода и питания) разработчик может использовать по своему усмотрению в качестве входа или выхода. В результате довольно сложный по выполняемым функциям прибор нередко удается выполнить всего на одной микросхеме.
Постоянное удешевление МК и расширение их функциональных возможностей снизило порог сложности устройств, которые целесообразно строить на их основе. Сегодня имеет смысл конструировать на МК даже такие приборы, для реализации которых традиционными методами потребовалось бы менее десятка логических микросхем средней и малой степени интеграции. Пожалуй, главным препятствием на этом пути остается консерватизм разработчиков, многие из которых до сих пор считают МК чем-то непостижимо сложным.
Между тем процессы разработки программы для МК и обычной принципиальной схемы цифрового устройства во многом схожи. В обоих случаях "здание" нужной формы строят из элементарных "кирпичей". Просто "кирпичи" разные: в первом случае - набор логических элементов, во втором - набор команд микроконтроллера.
Вместо взаимодействия между элементами с помощью обмена сигналами по проводам - пересылка данных из одной ячейки памяти в другую внутри МК. Процесс пересылки "выплескивается" наружу, когда МК поддерживает связь с подключенными к нему датчиками, индикаторами, исполнительными устройствами и внешней памятью. Различаются и рабочие инструменты разработчика. На смену привычным карандашу, бумаге, паяльнику и осциллографу приходят компьютер и программатор, хотя на последнем этапе отладки изделия без осциллографа и паяльника все же не обойтись.
Еще одна трудность - недостаточное количество полноценной технической документации и справочной литературы на русском языке. Большинство публикаций подобного рода в периодических изданиях и особенно в русскоязычном Интернете, зачастую - не более чем подстрочные переводы английских оригиналов. Причем переводчики, иногда мало знакомые с предметом и терминологией, истолковывают "темные" места по-своему, и они (места) оказываются довольно далекими от истины. Практически отсутствуют русскоязычные программные средства разработки и отладки программ МК.
Первое знакомство с МК для многих начинается с повторения одной из опубликованных в "Радио" или другом издании конструкций на их основе. И здесь сразу проявляется главное отличие МК от обычной микросхемы: он не способен делать что-либо полезное, пока в его внутреннее (иногда внешнее) запоминающее устройство не занесена программа - набор кодов, задающий последовательность операций, которые предстоит выполнять. Процедуру записи кодов в память МК называют его программированием (не путать с предшествующим этому одноименным процессом разработки самой программы).
Необходимость программирования, на первый взгляд, может показаться недостатком. На самом же деле это главное достоинство, благодаря которому можно, изготовив, например, всего одну плату с МК и несколькими соединенными с ним светодиодными индикаторами и кнопками, по желанию, превращать ее в частотомер, счетчик импульсов, электронные часы, цифровой измеритель любой физической величины, пульт дистанционного управления и контроля и многое другое.
Возможность сохранять в секрете коды программы помогает производителям аппаратуры на МК в борьбе с конкурентами. Правда, излишняя секретность программ нередко создает радиолюбителям дополнительные трудности при ремонте или совершенствовании устройств на МК "чужой" разработки. Но это - другой вопрос.
Еще недавно, приступая к проектированию конструкции на МК, разработчик стоял перед проблемой: можно ли решить поставленную задачу, используя приборы одного-двух известных ему типов. Сегодня ситуация изменилась в корне. Из множества доступных МК следует выбрать тот, с помощью которого задача будет решена оптимальным образом. К сожалению, так поступают далеко не все. Возникла даже определенная "мода" на изделия тех или иных типов, образуются своеобразные группировки сторонников МК определенных семейств. Свой выбор они обосновывают, как правило, на уровне "нравится - не нравится". Нередко отрицательное мнение о каком-либо приборе объясняется единственной неудачной попыткой его применения, зачастую без попытки анализа и устранения причин неудачи. Некоторые фирмы распространяют документы под названием "Правда о..." с "объективным" сравнением своих приборов с изделиями конкурентов, и, как правило, - в пользу первых. Особо доверять подобным публикациям не стоит, всегда найдется отчет о сравнении с обратными результатами и выводами.
Следует сказать, что, как и во многих других случаях, заведомо хороших или плохих МК нет и не может быть. Каждый из них способен показать отличные результаты при решении задач определенного класса и с трудом справляется с другими. Отсюда и разнообразие типов. Как правило, выигрыш по одному параметру сопровождается ухудшением других. Самые простые примеры: МК, рассчитанный на многократное перепрограммирование, всегда дороже однократно программируемого аналога, а более скоростной прибор чувствительнее медленного к импульсным помехам и требовательнее к трассировке печатной платы. Конечно, существуют универсальные приборы, в достаточной мере пригодные для решения широкого класса задач. Тем не менее проектируя, скажем, устройство с жидкокристаллическим дисплеем, стоит подумать об использовании в нем МК с встроенным контроллером такого дисплея.
Однако если необходимо лишь повторить ту или иную конструкцию, особой возможности выбирать МК нет, нужно использовать указанный в описании или его полный аналог, например, из числа изготавливаемых другими фирмами по лицензии. На вопрос, можно ли заменить МК одного типа другим, зачастую приходится давать отрицательный ответ, хотя теоретически такая возможность имеется: надо лишь переработать программу, а если число и назначение выводов заменяемого и заменяющего МК различны, то и печатную плату.
Если речь идет о замене МК близким по структуре и принадлежащим к тому же семейству или о замене устаревшего изделия современным аналогом, адаптировать программу, как правило, удается. Фирма Microchip даже включает в справочные данные своих МК рекомендации по такой адаптации. В общем случае полноценный перенос программы на другой МК требует наличия не только публикуемой обычно "прошивки" РПЗУ, а и полного исходного текста, желательно с комментариями программиста. Листинг, полученный в результате дизассемблирования "прошивки", - далеко не полноценный эквивалент. От программиста потребуется значительно более высокая квалификация, чем достаточная для разработки "с нуля", не меньшими будут и трудозатраты.
Начинать самостоятельную разработку устройства на МК и, естественно, программы для него рекомендуется с проработки и составления блок-схемы алгоритма его работы [2]. Только по результатам этого этапа можно сделать правильный выбор МК. Свойственное многим "суперпрограммистам" пренебрежение разработкой алгоритма, ускоряя, на первый взгляд, работу, приводит к излишней путанице в программе и невозможности для самого автора разобраться в ней спустя некоторое время.
Наш дальнейший рассказ построим на конкретном примере. Недавно автору этих строк потребовался счетчик, способный подсчитывать пересечения неким предметом определенного рубежа в одну и другую стороны. Полистав последние номера журнала "Радио", нашел подходящее устройство [3], но оно показалось слишком сложным (11 микросхем, в том числе РПЗУ большого объема) и к тому же не обладало некоторыми необходимыми функциями, в частности, возможностью предварительной установки показаний счетчика и запоминания его состояния после выключения питания. Появилась идея изготовить нужный прибор на МК. По причинам, изложенным далее, был выбран популярный сегодня МК PIC16F84. В результате родилась схема устройства (рис. 1), содержащего всего две микросхемы. (Вообще говоря, можно было бы обойтись и одной, исключив дешифратор DD1, как это сделано, например, в [4], но у МК не осталось бы свободных выводов, необходимых для того, чтобы при совершенствовании прибора подключить, например, командные кнопки).
В устройстве допустимо применение микроконтроллера PIC16F84 с любыми предельной частотой, типом корпуса и рабочим интервалом температур (об этих параметрах говорят цифровые и буквенные индексы после дефиса в обозначении микросхемы, например, -101/Р). А если совершенствование программы не предполагается, можно использовать и дешевый однократно программируемый аналог PIC16CR84.
Рис. 1Датчики перемещения предмета - транзисторные оптроны с открытым каналом АОТ147Б (U1, U2). Нагрузкой их фототранзисторов служат имеющиеся в МК внутренние резисторы. Допустимо использовать и оптопары, состоящие из отдельных свето- и фотодиодов (фототранзисторов), как это сделано в [3]. В подобном случае, возможно, придется подобрать резистор R1, задающий ток через светодиоды.
Оптические датчики при необходимости заменяют любыми другими: магнитными, контактными, индуктивными. Важно лишь, чтобы при их срабатывании на соответствующих входах МК изменялись логические уровни.
В устройстве применен четырехразрядный семиэлементный светодиодный индикатор СА56-11SR фирмы Kingbright. Его достоинство - большие цифры и достаточно яркое свечение при небольшом потребляемом токе. Возможно использование любых семиэлементных светодиодных индикаторов с общим анодом, например, четырех отечественных АЛС324Б. Набор резисторов DR1 можно заменить семью обычными резисторами сопротивлением 300 Ом.
Программа, которую необходимо занести в память МК DD2, чтобы превратить устройство в счетчик, функционально подобный [3], приведена в табл. 1. При включении питания во всех разрядах индикатора зажигаются нули. После каждого выполнения цикла "затенен КГ - "затенены U1 и U2" - "не затенен U1" - "не затенен U2" показания увеличиваются на единицу. Счетчик реверсивный, поэтому при срабатывании датчиков в обратном порядке показания на столько же уменьшаются. Максимальное число - 9999, после него следует ноль.
В следующих статьях цикла будет подробно рассказано о том, как создавались и отлаживались схема и программа счетчика, об их совершенствовании и введении дополнительных функций. Этими примерами будут проиллюстрированы основные возможности МК PIC16F84 и приемы работы с предоставляемыми фирмой Microchip бесплатными средствами программирования и отладки. Они объединены в пакет MPLAB, последнюю версию которого можно "скачать" с Интернет-сайтов www.microchip.com или www.microchip.ru. Если это будет сделано ко времени выхода журналов со следующими статьями цикла, освоение изложенного в них материала будет значительно облегчено.
Для того чтобы занести коды из табл. 1 во внутреннюю память программ МК, необходим программатор. Однако он не "умеет" читать коды с журнальных страниц, поэтому прежде всего требуется создать в компьютере файл с этими кодами в формате, "понятном" программатору. В табл. 1 они приведены в так называемом НЕХ-формате, разработанном фирмой Intel и ставшем фактическим стандартом для программирования ПЗУ различного назначения. (Нужно сказать, что других одноименных форматов, например, Microchip HEX, не существует, используются подобные названия лишь по недоразумению). Аналогичные форматы, разработанные другими фирмами, не нашли широкого применения и предназначены, как правило, лишь для аппаратных и программных средств собственной разработки, в большинстве своем "понимающих" и Intel НЕХ-формат.
Коды вводят в компьютер с помощью любого текстового редактора, в том числе Microsoft Word, точно в том виде, в котором они приведены в табл. 1. Если имеется сканер и программа распознавания текста, например, FineReader, можно воспользоваться ими. Но в последнем случае считанные данные придется сверить с оригиналом, так как автоматическое распознавание не идеально (возможны ошибки). Учтите, что в НЕХ-файлах применяются только символ двоеточия, цифры и латинские буквы A-F. Каждую строку начинают двоеточием в первой позиции и заканчивают нажатием на клавишу ENTER. Пробелы не допускаются. Закончив ввод и проверив коды, сохраните файл в режиме "Текст DOS" или "Только текст", присвоив ему любое имя с расширением .hex.
Нередко коды программ публикуют в виде так называемого "дампа памяти". Это более удобная для зрительного восприятия (чем в НЕХ-формате) таблица. Она состоит из строк, начинающихся шестнадцатиричным адресом (обычно четырехразрядным), за которым через пробелы следуют двухразрядные шестнадцатиричные коды, хранящиеся в следующих одна за другой ячейках (байтах) памяти. Адрес в начале строки относится к первой из ячеек, а всего их обычно 16. Для сравнения в табл. 2 приведен дамп, содержащий те же данные, что и табл. 1. HEX и дамп легко преобразовать один в другой следующим образом (см. табл. 3).
Первые два знака после двоеточия - число байт информации в строке. В данном случае их 16 (10Н). Далее следует адрес первого байта (0020Н), за ним - двухразрядный код назначения строки:
00 - строка содержит данные;
01 - завершающая строка файла (:00000001FF); она не содержит данных, число байт и адрес в ней - нулевые. Во многих случаях для опознания строки как завершающей достаточно нулевого числа байт;
02 - в области данных находится адрес сегмента памяти, относительно начала которого отсчитывают адреса, задаваемые в следующих строках. Следует помнить, что два байта адреса сегмента следуют в по-
рядке старший-младший. Число, которое необходимо прибавлять к текущим адресам, получают сдвигом двоичного кода адреса сегмента на четыре двоичных разряда влево, т. е. умножением его на 16;
03 - в области данных находятся четыре байта стартового адреса программы в обычном для IBM PC формате CS:IP;
04 - в области данных находятся (в порядке от старшего к младшему) четыре байта абсолютного адреса, значение которого без всяких преобразований следует прибавлять к адресам, указанным в следующих строках;
05 - то же, что 04, но задает абсолютное значение адреса старта программы.
Строки с кодами назначения 02 и 04 используют, если необходимо задать адреса, превышающие OFFFFH. Для программирования МК с памятью небольшого объема (таких, как PIC16F84) в них нет необходимости. Тем не менее иногда подобную строку, задающую нулевой начальный адрес, помещают в начало НЕХ-файла. Ее можно безболезненно удалить.
Строки с кодами 03 и 05 встречаются весьма редко, поскольку адрес старта программы МК чаще всего определяется архитектурой последнего и не может быть изменен. У МК семейства PICmicro он нулевой.
За кодом назначения следует область данных из указанного в начале строки числа байт. Строка завершается контрольным байтом. Алгоритм подсчета его значения довольно прост: восемь младших двоичных разрядов суммы всех байт строки, включая ее длину, два байта адреса, код назначения, данные и контрольный, должны быть равны нулю.
Первоначально НЕХ-формат предназначался для хранения восьмиразрядных данных. Коды большей разрядности разбивают на соответствующее число байтов, которые записывают в файл в порядке от младшего к старшему. Например, каждой из 14-разрядных команд МК PIC16F84 отводят по два байта, причем два старших двоичных разряда второго байта остаются свободными (код в этом байте не превышает 3FH).
В результате адреса в НЕХ-файле удвоены по сравнению с действительными адресами команд программы. Например, строка
:080008008C0003088D000408CO описывает такую последовательность программных кодов:
Адрес Код
004 008С
005 0803
006 008D
007 0804
Некоторые программные средства (как правило, ведущие свою родословную не от IBM-совместимых компьютеров) записывают в файл и воспринимают байты данных в обратном порядке - старший, за ним младший. На это стоит обратить внимание, если программатор "капризничает", не желая правильно читать файл.
Описанный формат представления многоразрядных данных часто называют Merged (склеенный). Изредка встречается другой вариант: НЕХ-файл разбивают на два, один из которых содержит все младшие, а второй - все старшие байты слов программы. Такой формат называют Splitted (расщепленный).
Следует учесть, что файл может не задавать сплошной последовательности кодов. Например, между кодами в первых двух строках табл. 1 остается незаполненным промежуток в шесть байт (три команды программы). Никакой информации об их содержимом НЕХ-формат не дает. В зависимости от алгоритма работы программатора они остаются в незапрограммированном исходном состоянии или в них сохраняются коды, записанные ранее. В табл. 2 неиспользованные ячейки заполнены нулевыми кодами.
Как известно, МК содержат постоянную память различного назначения: FLASH либо однократно программируемую для программы, EEPROM для данных, специальные ячейки конфигурации и идентификации МК. Информацию, предназначенную для этих областей, нередко хранят в отдельных файлах и при программировании приходится вручную указывать, куда именно ее записать. Но в семействе PICmicro принято решение, позволяющее объединить все в одном НЕХ-файле. Упомянутые выше области, находящиеся для процессора МК в разных адресных пространствах, с точки зрения программатора объединены в одно. Для PIC16F84 распределение следующее (в скобках - "байтные" адреса):
0-3FFH (0-7FFH) - коды программы; у МК с памятью большего объема эта область может быть расширена до 1FFFH(3FFFH);
2000Н-2003Н (4000Н-4007Н) - коды идентификации;
2007Н (400ЕН, 400FH) - слово конфигурации;
2100Н-213FH (4200Н-427FH) -коды, записываемые по адресам 0-3FH EEPROM.
Несмотря на то что организация EEPROM - восьмиразрядная, в данном случае каждому из предназначенных для него кодов в НЕХ-файле отводят по два байта, старший из которых - с нулевым содержимым.
ЛИТЕРАТУРА
1. Зобнин Ю., Волох Г., Тамазов А. Микроконтроллеры популярных семейств. - Радио, 2000, № 6, с. 51,52; № 7, с. 53,54; № 8, с. 53,54; № 9, с. 50.
2. Гладштейн А. Проектируем устройства на микроконтроллерах. - Радио, 2000, № 11, с. 25, 26; № 12, с. 20-23.
3. Мариевич А. Электронный счетчик витков. - Радио, 2001, № 2, с. 44-46.
4. ЯблоковД., Ульрих В. Частотомер на PIC-контроллере. - Радио, 2001, № 1, с. 21, 22.
Радио 5/2001, с.17-19.