Мир книг по микроэлектронике
Книги авторства Белова Александра
На главнуюРеквизиты автора Сайт МирМК FUSE калькулятор Сайт "Симферополь вчера и сегодня"

<< Предыдущая страница К оглавлению www.mirmk.ru Следующая страница>>

Глава. 10. Алгоритм работы микропроцессорной системы

Как мы уже видели из предыдущих глав, процессор управляет всей микропроцессорной системой. Он и записывает информацию в различные ячейки памяти и в порты, и читает ее от туда. Кроме того он обрабатывает информацию. Производит различные арифметические операции. От куда он знает, что и когда делать! Не уж то он такой умный? На самом деле умный не процессор, а тот, кто его придумал. И еще тот, кто составляет программу для процессора. Любой процессор – это автомат, который способен выполнять конечный набор элементарных команд. В набор входят команды типа «прочитать ячейку памяти», «записать ячейку памяти», «сложить два числа», «вычесть из одного числа другое» и т. д. Более подробно систему команд микропроцессора на примере AT89C2051 мы рассмотрим чуть позже. Каждая команда имеет свой код. При чем некоторые команды кодируются не одним, а несколькими байтами. Уже упомянутый процессор AT89C2051 имеет набор команд, коды которых занимают от одного до четырех байт.

Для того, что бы процессор выполнил некую последовательность команд, коды этих команд записывают в ОЗУ микропроцессорного устройства. Последовательность таких кодов в памяти и есть программа. У каждого процессора определена область памяти, куда нужно записывать программу. Коды первой команды программы записывают в память, начиная с первой ячейки этой области. Если команда состоит из одного кода, она займет одну первую ячейку. Если две – займет первую и вторую. В общем, команда займет столько ячеек, сколько ей нужно. Коды следующей команды записываются сразу после последнего кода предыдущей. Процессор устроен так, что сразу после сброса он читает программу байт за байтом и выполняет, закодированные таким образом, команды. Эту программу, по которой должен работать процессор, должен придумать и записать предварительно в память программист. От искусства программиста зависит, заставить микропроцессор делать именно то, что ему нужно. В микропроцессорных устройствах та часть памяти, которая используется для хранения программ, выполняется обычно в виде ПЗУ. Благодаря этому, записанная в него программа при выключении питания не теряется и при повторном включении микропроцессорное устройство начинает нормально работать.

Для хранения программ используется только часть памяти. Остальная память выполняется обычно в виде ОЗУ и служит для того, что бы процессор мог хранить в ней промежуточные результаты работы и другие вспомогательные данные. Из типовой схемы микропроцессорного устройства (рис. 28) видно, что в ней для хранения, как программ, так и данных используется одно адресное пространство памяти. Это позволяет гибко использовать память системы. В зависимости от конкретной программы одну и ту же область памяти может занимать программа, а могут данные. Однако однокристальные микроконтроллеры, одним из представителей которых является наш AT89C2051, составляют исключение. Большинство из них имеет две отдельные памяти: память данных и память программ. Но об этом подробнее мы расскажем при описании этой микросхемы.

Работа микропроцессорного устройства начинается с начального сброса. Для этого сразу после включения питания специальная схема подает импульс сброса на вход RESET процессора. По этому сигналу сбрасываются все внутренние регистры процессора. Сбрасывается и специальный регистр - счетчик адреса команд. Каждый процессор имеет множество внутренних регистров. Далее мы остановимся на этом подробнее. Регистр адреса команд предназначен для хранения адреса выполняемой в данный момент команды. Так как при сбросе регистр команд обнуляется, то после окончания действия сигнала сброса процессор начинает выполнение программы с нулевого адреса. Именно нулевой адрес чаще всего используется в качестве начала программной области памяти. В результате первое, что делает процессор после сброса – читает число, записанное в памяти по нулевому адресу. Это число процессор воспринимает, как  код первой команды. Он выполняет эту команду. Затем он увеличивает значение внутреннего счетчика адреса, и читает код следующей команды, выполняет ее и т. д. Если после чтения кода команды процессор определяет, что такая команда должна состоять не из одного, а из нескольких кодов, то прежде, чем выполнить команду, процессор читает столько кодов, сколько нужно. Информация о том, сколько байт читать и как выполнять каждую из команд, записана в виде микрокоманд внутри самого процессора.

Рассмотрим теперь, какие же команды обычно выполняют микропроцессоры.

Все команды любого микропроцессора можно разделить на три большие группы:

Первая группа – это команды перемещения данных. По этим командам процессор переписывает данные из одной ячейки памяти в другую. Причем это могут быть как ячейки внешнего ОЗУ, так и внутренние регистры временного хранения информации.

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

К третьей группе относятся команды передачи управления. Мало, какую программу можно составить лишь из одной последовательной цепочки команд. Подавляющее число алгоритмов требуют разветвления программы. Это значит, что программа должна выполнять разные действия в зависимости от какого либо условия. Например в устройстве управления спутниковой антенной имеется клавиатура управления. При нажатии различных клавиш устройство должно выполнять разные ответные действия. При нажатии клавиши «Поворот на восток», устройство должно включить двигатель для поворота антенны в этом направлении. При нажатии клавиши «Поворот на запад», система должна включить двигатель в реверсивном направлении. Для этого внутренняя программа периодически считывает состояние клавиатуры. Состояние клавиатуры – это число, в котором отдельные биты принимают значение в зависимости от того, нажата данная клавиша или нет. Так при нажатой клавише «Поворот на восток» первый бит этого числа будет равен нулю. При отпущенной клавише он будет равен единице. Второй бит того же числа точно так же отвечает за клавишу «Поворот на запад». (В данном примере номера битов выбраны условно). За остальные клавиши управления отвечают оставшиеся биты числа. Подробнее о том, как это сделано мы рассмотрим при описании схемы и программы позиционера. Сейчас нам важно только то, что при разном состоянии клавиш процессор получит разное число состояния клавиатуры. При нажатии клавиши «Поворот на восток» процессор получит число 111111102. А при нажатии на клавишу «Поворот на запад», он получит число 111111012. Далее, в зависимости от полученного числа, выполнение программы должно пойти по разному. Для этого служат команды передачи управления. Для процессора эти команды звучат так: Если число равно 111111102, продолжить выполнение программы с адреса XXX. Где XXX – это конкретный адрес памяти, где начинается та часть программы, которая обрабатывает нажатие первой клавиши. Если условие не выполняется, то процессор продолжает обычное выполнение команд и выполняет следующую команду по порядку. Наглядно это изображено на рисунке 27.

Рис. 27.

Для выполнения команды передачи управления процессор просто записывает в регистр – счетчик команд тот самый адрес XXXX, куда передается управление.

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

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

Рассмотрим применение этих команд на конкретных примерах. В позиционер спутниковой антенны должна вводится последовательность импульсов с датчика поворота антенны. Процессор позиционера должен по каждому импульсу датчика увеличивать или уменьшать содержимое внутреннего счетчика положения антенны в зависимости от направления ее вращения. Однако любой датчик, как уже отмечалось, обладает дребезгом контактов. Предположим, что для борьбы с дребезгом мы хотим, что бы процессор читал сигнал с датчика не один, а, например, 10 раз за каждую операцию проверки его состояния. При каждом считывании состояния датчика процессор получит некое число. Если контакты датчика замкнуты, то процессор прочитает число 1. Если разомкнуты, то 0. Для обеспечения эффекта антидребезга, все десять считываемых числа должны складываться. Затем процессор должен оценить получившийся результат и, если он окажется больше, чем 5, программа будет считать, что в процессе выполнения текущей операции считывания контакт был замкнут.  Если результат меньше или равен 5, то программа будет считать, что контакт был незамкнут. Произойдет некая интеграция входного сигнала от датчика, что уменьшит влияние дребезга контактов.

На самом деле в программе позиционера применен более сложный антидребезговый алгоритм. В дальнейшем мы обязательно рассмотрим его подробнее. А в данный момент этот пример нас интересует лишь потому, что для реализации такого алгоритма применяется команда циклической обработки. Для считывания состояния контакта в программе организуется цикл. Для этого в специальный регистр процессора помещают число – параметр цикла. В нашем случае это 10. Затем программа выполняет отрезок программы, называемый телом цикла. В теле цикла находятся команды чтения регистра ввода/вывода, к которому подключен датчик поворота антенны. Далее происходит выделение из полученного числа нужного бита, суммирование полученных чисел. В конце тела цикла стоит команда циклического перехода. По этой команде процессор вычитает из регистра параметра цикла единицу и проверяет не стало ли оно равно нулю. Если параметр еще не равен нулю, то осуществляется передача управления на начало цикла. После десятого цикла содержимое параметра станет равно нулю и перехода не начало цикла не будет. Процессор продолжит выполнение команд дальше. Этот процесс изображен на рис. 28.

Рис. 28.

 Другой механизм, применяемый в случае необходимости многократно выполнять в программе некие повторяющиеся действия – это подпрограммы. Возможность работы с подпрограммами так же имеется в любом процессоре. Что же такое подпрограмма? Предположим некий один и тот же набор действий нам нужно производить в разных местах программы. Например, программа формирует сигнал включения двигателя поворота антенны в двух случаях. Во первых при ручном управлении антенной. При этом кнопки ручного поворота служат для подачи команды процессору. А уже процессор включает двигатель. Второй вариант – управление поворотом антенны с пульта дистанционного управления. И, наконец, автоматическое управление в режиме установки в одну из записанных в память позиций.

Итак, мы видим, что одно и то же действие должно выполняться в трех разных частях программы. Конечно, включение двигателя - это слишком простая операция. Но в реальной программе обязательно понадобится одну и ту же сложную последовательность команд выполнять в разных частях алгоритма. В таких случаях ее оформляют в виде подпрограммы. Подпрограмма – это часть программы, которую можно вызвать из разных мест основной программы (в том числе и из других подпрограмм). После выполнения подпрограммы управление передается к той части программы, от куда была вызвана подпрограмма.

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

Рис. 29.

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

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

 

<< Предыдущая страница К оглавлению www.mirmk.ru Следующая страница>>