Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
Скачать 3.49 Mb.
|
XYZ уменьшается на единицу и становится равным 9- ти Эта девятка сохраняется в том же регистре XYZ. Так как это число неравно, то происходит переход на начало 2- го внутреннего цикла программы и все повторяется снова до тех пор, пока, после очередного вычитания единицы, в регистре XYZ не установится число 0. Как только это произойдет, будет осуществлен переход не на начало следующего внутреннего цикла программы, как это было ранее (первый сценарий работы программы, а на второй сценарий работы программы, который, в общем виде, называется " программа исполняется далее " По этому сценарию, в пределах дозволенного, могут осуществляться какие угодно действия ( определяется замыслом программы. Из этого примера видно, что происходит то, что называется ветвлением программы Еще один пример К выводам порта В подключен 7- сегментный индикатор Полный цикл программы равен, например, 1 сек, а его сегменты высвечиваются в течение 0,1 сек, а остальное время погашены Требуется увеличить это соотношение Следовательно , необходимо "встроить " (врезать ") в тот участок программы, в котором индикатор активен, подпрограмму задержки, функция которой заключается в " закольцовке " рабочей точки программы внутри этой подпрограммы А как же иначе, ведь рабочая точка программы всегда должна находиться в движении ? Вот и пусть она "мотает " заданное программистом количество "кругов " в подпрограмме задержки, ведь время- то идет Такие подпрограммы имеют в своей основе все те же команды ( INCFSZ ), только 29 безусловные переходы при этом гораздо "скромнее " - всего на несколько команда не на десятки, то есть, рабочая точка программы, на время задержки, "крутится " по относительно малому (с малым количеством команд) кольцу подпрограммы задержки Выглядит это так Подпрограмма задержки, в простейшем случае, начинается с команды DECFSZ ( INCFSZ ) и обращается к регистру общего назначения, в который , перед ее началом (в промежутке времени между моментом активации индикатора и до начала подпрограммы задержки, закладывается некое число (константа, которое и будет определять время задержки ( количество "колец "). Предположим, что в регистр XYZ заложено число (константа) 250. СтОит только рабочей точке программы войти в подпрограмму задержки, она не выйдет из нее до тех пор, пока задержка не будет полностью отработана Смысл этой " закольцовки " заключается в том , что при выполнении, например, команды DECFSZ и отсутствии нулевого результата операции декремента, переход, в конечном итоге, происходит на все туже команду DECFSZ и все повторяется по новой, пока число 250 не уменьшится до нуля, а это требует времени Вот Вам и задержка При нулевом результате операции, рабочая точка программы выходит из подпрограммы задержки, после чего индикатор переводится в пассивное состояние и программа исполняется далее Зная длительность машинного цикла, можно точно просчитать время задержки Этот пример, конечно, простейший, так как для относительно больших задержек, при длительности машинного цикла = мкс (кварц 4 Мгц .), одного регистра недостаточно (необходимо несколько регистров с последовательным их декрементом. С этим мы разберемся позднее Сейчас главное - прочувствовать "кольцевую природу " программ и представить себе, как в главном "кольце " (цикле) программы, образуются большие и маленькие "кольца ", и как рабочая точка программы в них "входит, выходит, идет по прямой, заходит в другое кольцо " и т д Примечание : все, сказанное выше, относится и к команде INCFSZ Отличие - только в направлении счета (+1). Оставшиеся две команды ветвления BTFSC и BTFSS ориентированы на операции с битами регистров При применении этих команд, никаких действий с байтами не производится Критерием ветвления является значение выбранного бита (0 или 1). Например, если на момент исполнения команды, значение выбранного бита регистра (например, бита) равно 1, тов соответствии с логикой команды, выполняется следующая команда, а если значение этого бита равно 0, то вместо следующей команды, исполняется "пустышка ", в виде команды (нет действия или операции Задержка на 1 м ц .). После этого "пустого " машинного цикла, выполняется следующая команда (вторая после. Обращаю Ваше внимание на то, что в этом случае, команда NOP как бы "виртуальна " формируется аппаратными средствами ПИКа ), так как в тексте программы команды NOP нет , хотя, по факту, она и заменяет , в случае равенства 2- го бита нулю, следующую, после , команду Получается , что в этом случае, команда присутствует в тексте программы, ноне исполняется (вместо нее, исполняется " виртуальный " NOP ). Итоговый смысл- в случае равенства го (в данном случае) бита единице, исполняется следующая, после команды, команда- в случае равенства го (в данном случае) бита нулю, происходит как бы " скачёк " через эту "следующую" команду (посредством исполнения, вместо нее, " виртуального " NOP а ). Естественно , что никакого "скачка " через команду не происходит, ведь " виртуальный " исполняется, но впечатление "скачка " создается Кстати , это очень полезное впечатление, от которого ненужно отмахиваться, а нужно использовать в своей работе (очень удобно, не забывая при этом про " виртуальный Примечание словосочетания " виртуальный Вы нигде не найдете, так как это моя 30 фантазия Слово "виртуальный " означает, что тона что указывает это слово, исполняется не программно, а аппаратно Ведь нужно же, "для порядка ", кратко и емко "обозначить это явление "? В соответствии со сказанным, время исполнения команды, в зависимости от сценария ее исполнения, будет составлять либо 1, либо 2 машинных цикла Вот Вам и объяснение того, что Вы видите в 4- м столбце таблицы команд, в строке с командой BTFSC {1(2)}. Тоже самое, с учетом специфики команд, относится и к остальным командам ветвления, INCFSZ, BTFSS ). А если , после команды, исполняется команда безусловного перехода, как это и происходит во многих случаях Пример самого распространенного варианта btfsc XYZ,2 goto Cycle ----- -й сценарий если й бит регистра XYZ равен 1, то происходит безусловный переход в подпрограмму , например, й сценарий если й бит регистра XYZ равен 0, то перехода в подпрограмму Cycle не происходит (вместо этого - виртуальный NOP" ) и программа исполняется далее ( дальнейшие команды программы обозначены- ---- ). Еще один вариант btfsc XYZ,2 goto Cycle goto й сценарий если й бит регистра XYZ равен 1, то происходит безусловный переход в подпрограмму Cycle 2- й сценарий если й бит регистра XYZ равен 0, то происходит безусловный переход в подпрограмму Mem Команда goto игнорируется (вместо нее исполняется " виртуальный NOP" ). Еще один вариант btfsc XYZ,2 movwf PortB ----- -й сценарий если й бит регистра XYZ равен 1, то содержимое аккумулятора ( W ) копируется в защелки порта В После этого копирования, программа исполняется далее 2- й сценарий если й бит регистра XYZ равен 0, то копирования содержимого аккумулятора в защелки порта В не происходит (вместо этого - виртуальный NOP" ), и программа исполняется далее В первых двух вариантах, используются переходы, а в последнем, не используются В любом из этих случаев, происходит ветвление, так как имеется два сценария работы Все , что сказано выше, относится и к команде BTFSS Единственное различие в том , что критерий анализа меняется на противоположный ( сценарии меняются местами. Начинающим, в первую очередь, необходимо обратить внимание на команду безусловного перехода GOTO Сначала нужно освоить ее, а потом переходить к изучению команды условного перехода CALL В принципе , при составлении программ, можно вообще не применять команду, а пользоваться только командой GOTO как по своему прямому назначению, таки заменяя ей команду CALL Обе эти команды, "стратегически ", осуществляют переход по одному и тому же принципу ( типа "куда захочу, туда и перейду "), но есть "тактические " отличия Команда GOTO "гуляет сама по себе " (стек не задействована - только в "связке " с командой возврата RETURN или RETLW 31 А как же иначе, ведь после отработки той подпрограммы, в которую осуществлен условный переход, для обеспечения возврата "в то место, откуда пришел ", из стека, нужно "выгрузить " адрес возврата Принцип замены команды CALL на GOTO состоит в том , что, кроме команды, по которой происходит переход, необходима еще одна команда, которая организует возврат В случае организации условного перехода ( CALL ), возврат происходит на команду, которая не помечена меткой Следовательно , при замене условного перехода на безусловный, необходимо выставить на команде, на которую нужно вернуться, метку, а в рабочей части команды возврата (в данном случае, команды) указать эту метку В общем виде, это выглядит так ----- ----- goto Cycle Metka xxxx xxxx ----- ----- ----- ----- Cycle yyyy yyyy ----- ----- goto Metka ----- ----- ----- -обозначены какие- нибудь команды программы Их может быть разное количество (зависит от программы. По команде безусловного перехода, сначала осуществляется переход в подпрограмму Cycle Следующая , после GOTO, команда , обозначенная, для обеспечения дальнейшего возврата, помечается меткой Metka Происходит переход в подпрограмму Cycle , иона, начиная с первой ее команды, обозначенной, исполняется до своей последней команды, в качестве которой используется все та же команда ( goto Metka ), нона этот раз, она обеспечивает возврат После этого, происходит возврат на команду, выделенную меткой, и программа исполняется далее Между Metka и Cycle может быть, например, 10, 50, 100 или другое количество команд, в которых также могут быть организованы переходы и возвраты Таким образом можно организовать переходы и возвраты без использования команды, то есть без работы со стеком Результат - один и тот же Рекомендую начинающим, на первых порах, поступать именно так, а со стеком поработаете тогда, когда переходы и возвраты перестанут вызывать у Вас затруднения Для любознательных описанная выше процедура, для случая условного перехода, выглядит так Первую сверху команду GOTO нужно заменить на команду CALL Метка Metka не нужна Нижняя команда GOTO заменяется на специальную (для работы со стеком) команду возврата (точку возврата указывать ненужно, так как ее адрес "лежит " в вершине стека. Команда RETLW также работает со стеком От команды RETURN она отличается только тем, что, при возврате, осуществляется действие в регистр W загружается указанная константа Команда RETURN никаких действий, кроме возврата по стеку, не производит Команда RETFIE применяется только для возврата из подпрограммы прерываний, о которой будет отдельный разговор Команда CLRWDT используется для периодического, программного сброса сторожевого таймера, если он включен В отличие от команды, в которой все ясно и понятно (копирование байта из аккумулятора в указанный регистр, команда MOVF может вызвать у начинающих некоторые затруднения 32 Команда MOVF копирует содержимое указанного регистра либо в регистр W (аккумулятор, либо в тот же, указанный регистр В основном , сохранение происходит в регистре W ( команда MOVF копирует , в регистр W, содержимое указанного в команде регистра Казалось бы, "бестолковое " копирование содержимого, указанного в команде регистра, в этот же регистр, все- таки имеет практический смысл можно проверить, равен или нет нулю результат этой операции, а затем "разветвиться " на 2 сценария Если содержимое регистра равно 0, то флаг нулевого результата Z поднимется (установится в 1), а если нет - опустится (установится в 0). Манипуляции " с флагом Z будут рассмотрены позднее Чаще всего команда MOVF применяется для считывания данных, с выводов портов ( регистры PORTA и PORTB это регистры специального назначения, в регистр W Выглядит это так movf или PortB,W В дальнейшем , с целью дальнейшей обработки результата этого считывания, можно скопировать содержимое регистра W в один из регистров общего назначения Например , для выяснения состояния клавиатуры, подключенной к выводам порта Еще раз обращаю Ваше внимание на то, что напрямую скопировать данные, из одного регистра в другой , нельзя Их (данные) нужно сначала скопировать, из регистра – адресата, в буферную память (в регистра затем скопировать данные из нее, в регистр - получатель Для случая копирования данных из регистра PortB в регистр общего назначения, это выглядит так movf PortB,W movwf Буквально скопировать содержимое регистра PortB в аккумулятора затем скопировать содержимое аккумулятора в регистр XYZ Или проще переслать содержимое регистра PortB в регистр XYZ Примечание : в приведенных выше и ниже примерах использования команд, я не придерживаюсь правил, используемых при написании программ Синтаксические правила написания программ будут изложены позднее, и этим правилам Вы будете обучаться в специализированном редакторе программы MPLAB Стандартные логические операции с корнями AND (И, IOR (ИЛИ, XOR (" исключающее ИЛИ "), COM (инверсия) в особых пояснениях не нуждаются (это из основ цифровой техники. При выполнении команд циклического сдвига RLF или RRF , происходит циклический сдвиг влево или вправо содержимого регистра, к которому обращается команда сдвига Циклический сдвиг происходит через флаг переноса - зама (нулевой бит регистра, с названием С Эти команды используются, например, при преобразованиях кодов, при организации сложных арифметических действий и т д При организации этих процедур, используется также и команда SWAPF Начинающим советую пока, на время, "отложить последние 3 команды в сторону " и особо на них не "зацикливаться ". Разборки " сними будут позднее Команда NOP (нет операции) на первый взгляд может показаться не слишком значимой, но это не так При составлении программ, достаточно часто встречаются ситуации, когда необходимо осуществить небольшую задержку выполнения какой- то последующей команды, не производя при этом никаких операций с числами , или ситуации, когда необходимо сделать время исполнения обеих сценариев команды ветвления одинаковыми, не производя при этом никаких операций, и т д В этих случаях, используется команда NOP Если NOP ы вставляются в "линейный " участок программы, то каждый NOP это задержка на машинный цикла еслиbNOPbы "вставляются " в циклические подпрограммы, тов зависимости от их "конструкции ", время исполнения программы, в итоге , может увеличиться на десятки, сотни и даже тысячи машинных циклов Примечание : я постарался объяснить Вам только то, что необходимо для "старта ". Детальные "разборки " с командами последуют далее, когда начнется "живая " работа с текстами программ и когда будут "подворачиваться " удобные поводы На мой взгляд, теоретическое обучение есть обучение, хотя и совершенно необходимое, но 33 какое- то "недоношенное ", и которое , по своей эффективности, "в подметки не годится " обучению на "живых " примерах Дополнительно Оговорка : если Вы только начинаете и не имеете опыта, то изложенная ниже информация, вернее всего, будет восприниматься "туговато ", но, все- таки, я советую Вам бегло с ней ознакомиться с целью того, что называется "быть в курсе ". Потом, когда поднаберетесь опыта, можно разобраться с ней более детально Об ошибках, допущенных в "фирменном" описании системы команд среднего семействам PICmicro. Справочник по среднему семейству м / контроллеров PICmicro", перевод технической документации DS33023A компании Microchip Technology Incorporated, ООО " Микро - Чип ",2002) Пояснения Лично я, "въезжал " в команды при помощи "разборок " с проверенными в работе текстами программ и пользовался "фирменной " распечаткой команд только в части касающейся самих команд и краткого их названия, без детальных разбирательств с примерами применения команд, приведенными в этой распечатке все примеры я брал из "живых " текстов программ Когда возникла необходимость загрузки на сайт файла таблицы команд, я, доверяя профессионалам, без всякой "задней мысли ", просто скопировал примеры применения команд из "фирменной " технической документации, особо не задумываясь о том , что что- тов ней может быть "криво ". Основанием для такой легкомысленности являлось то, что у меня просто не было практической необходимости в "разборках " с примерами применения команд этой таблицы по той простой причине, что с этими примерами я детально разбирался, как говорится, "в живую ", работая непосредственно с текстами проверенных в работе программ, что гарантирует максимальное качество этих детальных "разборок ". Так это "святое неведение " и продолжалось бы, если бы не вопросы Дмитрия Дубровенко Он попытался детально разобраться с примерами "фирменной " таблицы и "заработал " себе "головную боль " в виде вопросов, с которыми он ко мне и обратился Вот уж действительно внимательный и дотошный человек Побольше бы таких Я наконец - то удосужился "въехать " в эти примеры, и у меня "волосы встали дыбом ": никак не ожидал от профессионалов такого подвоха Вот уж воистину "доверяй, но проверяй ". Ниже, я постараюсь объяснить, в чем тут дело и привести таблицу команд в "божеский вид ". Исходные данные Кривая, "фирменная" таблица команд (та, что раньше "лежала" в этом разделе, находится в |