Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
![]()
|
bsf , программно управлять его состояниями Если она высокая, то используя команды переходов, нужно "уйти " в соответствующую подпрограмму (подпрограммы, так как в этом случае, потребуется большее количество команд Например , требуется, чтобы исполнительное устройство сработало по совокупности событий высокие температура и задымленность Если первой анализируется температура, то при наличии числа, например, от .80 до .90, осуществляется переход на исполнение подпрограммы (подпрограмм) анализа задымленности В ее состав должна входить, аналогичная рассмотренной, группа команд цифрового компаратора, работающая с числами , величины которых зависят от уровня выходного сигнала датчика задымленности Если получены утвердительные ответы на оба вопроса (Температура выше нормы" и "Уровень задымленности выше нормы, то срабатывает исполнительное устройство пожаротушения Естественно , что при этом, конструкция и устройства и программы усложняется (два датчика. Этот пример, может быть, и не слишком удачный, но "глобальный " смысля надеюсь, понятен Существуют и комбинированные (не "однообразные ") варианты "ухода " рабочей точки программы, из группы команд, реализующей цифровой компаратор Например , если анализируемое число равно одной константе, то осуществляется прямое управление выводом порта, а если анализируемое число равно другой константе, то осуществляется переход на нечто такое, что сложнее прямого управления выводом порта В основном , цифровой компаратор является всего- лишь одним из элементов "программного комплекса ", и этот "элемент " участвует в управлении исполнительным устройством ( устройствами ), состояния которого многовариантны В этом случае, речь идет не о прямом , а об опосредованном воздействии на исполнительное устройство Пример исполнительного устройства, состояния которого многовариантны 7- сегментный индикатор Пример опосредованного воздействия цифрового компаратора, на работу 7- сегментных индикаторов гашение незначащих нулей в линейке из нескольких таких индикаторов 190 В очень общем виде, это выглядит так Несколько последовательно соединенных компараторов, анализируют несколько чисел, предназначенных для отображения в линейке , начиная от числа, отображаемого в самом левом (старшем) знакоместе линейки Если , до первой значащей цифры (не ноль, обнаружен ноль (нули, то он (они) гасится (не выводится на индикацию. Правее первой значащей цифры (включая и ее ), гашения нет "Фундаментом всего этого сооружения " и других подобных устройств, является цифровой компаратора его "сердцем ", флаг нулевого результата, так что он вполне заслуживает к себе внимания Следует отметить то, что цифровой компаратор можно реализовать и с использованием флага С , речь о котором пойдет ниже Разбираемся с флагами C и DC. Если принцип работы флага Z не является чем- то уж очень сложным, то понимание принципов работы флагов переноса- заёма C и десятичного переноса- заёма DC , для большинства начинающих, является своеобразным "камнем преткновения ". Постараюсь убедить Вас в том , что "не так страшен черт, как его малюют ", а заодно , на примере флагов C и DC , расскажу о методике "въезда " в операции , которые вызывают затруднения Это выглядит так Создается некая группа команд, "обслуживающая " выполнение операции, вызывающей затруднения Для того чтобы можно было "полноценно " работать в симуляторе , необходимо "врезать " эту группу команд в любую простенькую программу, в которой регистр (регистры) специального назначения, использующийся в этой группе команд, "прописан " в "шапке " программы или "прописать " его, если такого регистра нет В противном случае, после ассемблирования , будет выдаваться сообщение об ошибке типа "происходит обращение к регистру , который не задействован ". Для того чтобы долго до нее не "добираться ", эту группу команд целесообразно "врезать " вначале программы При этом, то, как именно будет работать программа, совершенно безразлично Все внимание - на "врезанную " группу команд В соответствии со сказанным, нужно как бы "родить дитя от суррогатной матери ". В качестве таковой, используем известную Вам , простенькую программу Multi.asm Откройте проект Multi Куда "врезать " проверочную группу команд Можно "вставить " ее в самое начало программы, но при этом нужно будет переносить название ПП START на первую команду этой группы Можно сделать итак, но лучше "оставить в покое " название подпрограммы, а "врезаться " где- нибудь пониже В "промежутке " между командами выбора 1- го банка и выбора 0- го банка, эту "врезку " можно делать только в том случае, если проверочная группа команд работает в 1- м банке В большинстве случаев, она работает в 0- м банке "Не мудрствуя лукаво ", "врезаем " проверочную группу команд в "промежуток " между командами и .32 (и волки сыты, и овцы целы "). Теперь определяемся с ее составом Если необходимо разобраться с флагами C и DC , то нужно работать с командой , которая воздействует на оба этих флага Посмотрите в распечатку команд Таких команд 4: две - сложения и две - вычитания Операция сложения, намой взгляд, более проста и привычна , чем операция вычитания Значит , "отсеиваем " 2 команды вычитания Остались команды сложения ADDWF и ADDLW Можно применить и ту , и другую , но для обеспечения простоты "конструкции " проверочной группы команд, выгоднее использовать команду операции с константой ( ADDLW ), а не команду операции с содержимым регистра ( ADDWF ), так как в последнем случае, нужно будет задействовать регистр общего назначения, и запись в него производить в 2 приема ( через регистр. 191 То есть, в случае применения команды ADDWF, потребуется 5 команд, плюс задействование регистра общего назначения, а в случае применения команды ADDLW, потребуется всего 3 команды и никаких регистров задействовать ненужно Итак, используем команду (суммирование содержимого регистра W и константы, с сохранением результата в регистре W ). Итак, первое слагаемое (константа) в наличии Ее числовое значение указывается в рабочей части команды ADDLW На момент исполнения команды, второе слагаемое должно "лежать " в регистре W Следовательно , до исполнения команды, в регистр W, нужно записать числовое значение второго слагаемого Для того чтобы, в симуляторе , выяснить, когда поднимаются флаги C и DC , перед выполнением команды ADDLW их необходимо сбрасывать (устанавливать в ноль ). Следовательно, перед исполнением команды, должна исполниться команда Status,0 , если работаем с флагом C, или команда Status,1 , если работаем с флагом DC Примечание : команды bcf и bsf на флаги не влияют Получается следующее для работы с флагом C movlw X bcf Status,0 addlw для работы с флагом DC movlw X bcf Status,1 addlw и – слагаемые числа Разбираемся с флагом C. Врежьте " указанную выше группу команд (для работы с флагом C ), в текст программы Multi.asm, между командами и Естественно, и " пропечатывать " ненужно Это символьные обозначения Просто оставьте пустое место для чисел Их можно будет "вписать " позднее Все готово для того чтобы "выпытать " у флага C его "тайны ". Методика этой "пытки " очень проста в качестве чисел X и Y подставляем различные их значения (от .00 досмотрим, что из этого получится, и анализируем результат Сразу возникает вопрос "Куда смотреть и какие значения чисел подставлять" Ответ : смотреть - в окно RAM или SFR , а из чего исходить при выборе значений этих чисел, давайте разбираться Посмотрите в комментарий к флагу C В нем говорится о каком - то старшем бите и не оговаривается, старшем бите чего Полубайт (4 бита) отпадает, так как с ним работает флаг (см распечатку. Остается байт Следовательно , речь идет о каком - то непонятном (пока) переносе, чего- то еще более непонятного, из старшего бита байта Байт может отобразить значения чисел от .00 до .255, а старший бит байта устанавливается в 1 во второй половине этого диапазона чисел (начиная с .128) и сбрасывается , изв, при переходе от числа .255 к .00. Вполне логично "привязаться " к этому , наиболее "резкому цифровому скачку " (переход от к .00) и предположить , что при этом, должно что- то произойти А именно , флаг C должен , на этот "скачек ", "среагировать ", то есть, подняться (установиться в 1). Вопрос " В каком случае, результат исполнения команды ADDLW может быть бОльшим , чем ?" Ответ однозначен если сумма этих чисел больше, чем .255. Но 8- битное число не может быть большим, чем .255. А если нужно просуммировать, например .250 и .200 ? Получится не .450, а (.250+.200)-.256=.194. 192 Число .256 "исчезло " по причине того, что разрядности одного регистра маловато будет В подобных случаях, если не принять мер по увеличению разрядности регистра, тов каждом случае превышения значения суммы, над числом .255, будет "исчезать " число, равное 256 общее количество чисел, которые способен отобразить один байт. В ПИКах , нельзя реализовать, например, 9, 10, 11, ... - разрядный регистр общего назначения Можно реализовать только разрядность, кратную 8- ми, задействуя несколько регистров общего назначения Только в этом случае можно работать с "большими " числами Количество задействованных регистров зависит от максимального значения числа, которое нужно в них отобразить Например , если это значение равно .50 000, то нужно использовать двухбайтный регистр ( задействуются 2 регистра общего назначения, который способен отобразить числа от .0 дох. Итак, возникла необходимость в наращивании разрядности Вопрос : "Как программно "состыковать " два отдельных регистра "? Ответ : начну "из аппаратного далекА ". Например, нужно нарастить разрядность двоичного счетчика 555 ИЕ 5. Выход старшего разряда этого счетчика подключается к счетному входу еще одного счетчика, и этот второй счетчик (старший) начинает отсчитывать количество полных циклов счета первого (младшего) счетчика Так называемым выходом переноса, в данном случае, является выход триггера старшего разряда младшего по разрядности счетчика, а сигналом переноса является перепад напряжения, формируемый при переходе от числа .15 к числу .00 (555 ИЕ 5 работает с полубайтом ). А ведь регистры ПИКа имеют точно такую же основу (триггеры, что и 555 ИЕ 5 (и многие другие, следовательно, нарастить разрядность этих регистров можно по такому же принципу То есть, по принципу переноса, из старшего, двоичного разряда "младшей считалки ", в младший , двоичный разряд "старшей считалки ". Если же речь идет о ПИКах , то задача формулируется так нужно организовать перенос из старшего байта регистра младшего разряда в младший байт регистра старшего разряда Только имеется большое горе внутрь ПИКа с паяльником не залезешь и ничего не припаяешь И вообще , гиблое это дело Но то, что выделено темно - синим цветом, можно реализовать программно Чувствуете , "куда ветер дует" А "ветер дует " на флаг C В его названии есть слово "переноси "следит " он за байтом А что если флаг C поднимается в том случае, если результат суммирования больше, чем число .255 ? Самостоятельно проверьте это "гениальное предположение ", используя "вышележащую ", проверочную группу команд (для флага. Изменяя значения чисел X и Y и производя, после этого, суммирования, обратите внимание ( в окне, а можно ив окне) на состояния флага (бит регистра, адрес регистра 03h), в случаях , если сумма этих чисел меньше .255 или больше .255. Работайте в пошаговом режиме Не забывайте о том , что после изменения значений чисел X и / или Y (при этом, в текст программы вносятся изменения, нужно производить ассемблирование , а также и о том, что если речь идет об одном байте, то констант, бОльших чем .255, не бывает Полчаса такой работы более эффективны, чем несколько часов теории Обычно , после такого рода работы, наступает значительное "просветление ", вплоть до того, что человек даже может удивиться, насколько простым оказалось то, что ранее вызывало затруднения Итак , что выясняется Выясняется следующее Если арифметический ( а не по "кольцу "результат сложения двух чисел больше, чем число .255, то флаг С устанавливается в 1. То есть, осуществлен перенос 2. Если этот результат находится в числовом диапазоне .00 … .255, то флаг 193 устанавливается в 0. То есть , переноса нет Вывод : если по фактам возникновения переносов, инкрементировать содержимое регистра более старшего разряда, то можно безошибочно суммировать "большие" условно) числа. До сих пор, речь шла об операции сложения Давайте разберемся с операцией вычитания Если в проверочной группе команд, Вы замените команду сложения, на команду вычитания (а также замените команду на Почему Поймете позже) и произведёте , аналогичную описанной выше (с учетом того, что результат может быть отрицательным, проверку, то выясните следующее Если арифметический результат вычитания двух чисел является числом положительным, находится в числовом диапазоне .00 … .255) , то флаг C устанавливается в. Если этот результат меньше нуля, то есть, он является отрицательным, то флаг C устанавливается в. Теперь, речь идет о заёме В первом случае, зама нет. Во втором случае, зам есть . Вот Вам и ответ на вопрос "Откуда, в комментарии к флагу C , взялось словосочетание перенос - заем " ? Обязательно следует уточнить, что перенос (при суммировании) или зам (при вычитании) возникает не во всех случаях суммирования или вычитания, а только в тех случаях, когда результат суммирования или вычитания "выходит за рамки " числового диапазона .00 … .255 с того или иного "края "). То есть, в тех случаях, когда арифметический результат суммирования больше числа (переноси когда арифметический результат вычитания является отрицательным числом (зам. Во всех остальных случаях, речь идет просто о суммировании и просто о вычитании (без "прибамбасов "). Примеры Если суммируются числа, например, .254 и .03, то фактической суммой будет являться не число .257 (водном регистре отобразить его невозможно, а число .01, плюс перенос ( флаг C установился в 1). Если из числа .01 вычитается число .03, то фактическим результатом вычитания не будет являться отрицательное число Им будет являться число .254, плюс зам (флаг установился в 0). Если Вы сравните эти примеры, то поймете, почему заем имеет инверсное значение ( см комментарии к флагу С ). Ив самом деле, при переносе, бит флага С устанавливается в, а приза меib, он устанавливается в. То есть, зам, по отношению к переносу , является действием типа "наоборот ". А теперь давайте разберемся с "легким бардачком ", возникающим при этом, а заодно , внесем ясность ив вопрос о том , обязательно ли нужно сбрасывать флаги й группы ( флаги Z, C, относятся к й группе) или нет, перед выполнением команд, которые на эти флаги воздействуют Если с переносом все понятно ( бит С установился в 1, то есть, флаг поднялся, то приза ме, флаг С , формально (так как мы ранее "привязались " к тому , что поднятию флага соответствует 1), опустился "Виной этому " то, что заем имеет инверсное значение В этом случае (при применении команд SUBWF или SUBLW ), нужно просто " проинвертировать привязку ", то есть, изменить критерий "поднятия ": флаг поднят 0, флаг опущен 1. В соответствии с этим , вносим коррективы в проверочную группу команд (ранее предполагалось, что флаг С устанавливается в 1 и при переносе, и при заме. 194 Если производится суммирование, то нужно применить команду Status,0 , а если вычитание, то нужно применить команду Status,0 В этом случае, на момент исполнения команд ADDLW или SUBLW с учетом сформулированных выше критериев "поднятия "), флаг С будет гарантированно опущен Что касается ответа на вопрос, сформулированный выше (он выделен темно - зеленым цветом, то ответ такой нет, необязательно, но для начинающих, желательно (я об этом уже говорил ранее. Прочитайте определение флагов 1- й группы , которое дано выше Это и есть первая часть ответа И в самом деле, зачем предварительно сбрасывать все те же флаги, C, DC , если их состояния полностью определяются результатами исполнения соответствующих команд Проще говоря, в каком бы из двух состояний не находился, до момента исполнения команды ( той , которая на него воздействует, флаг 1- й группы , после ее исполнения, этот флаг будет установлен в то состояние, которое соответствует результату выполненной операции Таким образом, из группы команд, реализующих цифровой компаратор, и из группы проверочных команд, работающих с флагами |