PIC Tutorial - От регистров к прерываниям

Попробуйте наш инструмент устранения неполадок





Прежде чем вдаваться в подробности программирования PIC, было бы сначала важно изучить несколько хороших методов программирования.

Понимание регистров

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



Вышеупомянутая функция позволяет нам добавлять комментарии или замечания, чтобы они не становились частью программы, но помогает нам идентифицировать программу с помощью комментариев рядом с ней. Добавление комментариев является рекомендуемой практикой при программировании любой ИС.

Следующим важным моментом в курсе является присвоение имен различным константам (вы выучите их позже). Это aso упрощает понимание того, что написано или относительно задействованных значений, вместо того, чтобы путаться с включенными числами.



Вышеупомянутое должно быть выполнено в форме реальных имен для мгновенного распознавания, например COUNT, важно отметить, что здесь используются все заглавные буквы, чтобы сделать его отличным, а также указать, что это постоянное значение.


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

2. Регистры.

Регистр в PIC - это область, которая принимает письменные данные, а также позволяет читать из нее. Вы можете сравнить его с листом бумаги, на котором вы можете визуализировать содержимое, а также добавить, написав поверх него.

На рисунке ниже изображена типичная карта регистрового файла, встроенная в PIC16F84. Формат не является чем-то, что фактически устанавливается внутри PIC, он просто указывает, как биты могут быть расположены внутри чипа, и понимать некоторые из задействованных команд.

Вы можете видеть, что он в основном разделен на банк 0 и банк 1. Банк 1 отвечает за управление фактической работой PIC, например, он сообщает PIC, какие биты в порту A назначены как входы, а какие - как выходы.

Банк 2 предназначен только для манипулирования информацией.

Давайте разберемся в этом на следующем примере:

Предположим, мы хотим назначить один бит на высокий уровень PortA. Для этого нам сначала нужно перейти к банку 1 для установки указанного бита или вывода в порту A в форме вывода. После этого мы возвращаемся в банк 0 и доставляем логическую 1 (бит 1) на этот конкретный вывод.

Наиболее распространенные регистры, которые мы хотели бы использовать в Банке 1, - это STATUS, TRISA и TRISB.

СТАТУС помогает нам вернуться в банк 0, TRISA позволяет нам выбирать, какие контакты в порту A являются выходами, а какие могут быть входами, в то время как TRISB упрощает выбор между выходом и входным контактом в порту B. Регистр SELECT в банке 0 позволяет пользователю перейти в банк 1.

Давайте резюмируем всю концепцию следующим описанием:

ПОЛОЖЕНИЕ ДЕЛ:

Чтобы переключиться с банка 0 на банк 1, мы даем команду регистру STATUS. Это реализуется установкой бита № 5 регистра STATUS в 1. Чтобы вернуться обратно в банк 0, мы присваиваем бит 5 регистра STATUS нулю. Регистр STATUS расположен по адресу 03h, здесь h означает номер. может быть в шестнадцатеричной системе счисления.

ТРИСА и ТРИСБ:

Они расположены по адресам 85h и 86h соответственно. Для программирования вывода как выхода или входа мы просто доставляем ноль или единицу конкретному биту в регистре. Теперь это можно сделать двумя способами: двоичным или шестнадцатеричным. Если кто-то не может преобразовать параметр, он или она может обратиться к научному калькулятору для реализации значений.

Теперь у нас есть 5 контактов в порту A, что соответствует 5 контактам. Если мы намерены зафиксировать один из выводов в качестве входов, мы даем «1» конкретному биту.

В случае, если мы хотим назначить один из выводов как выходы, мы должны установить конкретный вывод на «0». Биты точно соответствуют битам, или, точнее, бит 0 - это RA0, бит 1 - это RA1, бит 2 = RA2 и так далее. Давайте разберемся с этим так:

Предположим, вы хотите исправить RA0, RA3 и RA4 как выходы, а RA1 / RA2 как i / ps, вы должны сделать это, отправив 00110 (06h). Убедитесь, что бит 0 направлен вправо, как показано здесь:

Порт A Контакт RA4 RA3 RA2 RA1 RA0

Номер бита 4 3 2 1 0

Двоичный 0 0 1 1 0

То же самое и с TRISB.

ПОРТА и ПОРТБ

Чтобы вывести один из выходных контактов на высокий уровень, мы просто предлагаем «1» для соответствующего бита в нашем регистре PORTA или PORTB. Аналогичную процедуру можно выполнить и для регистров TRISA и TRISB. Прежде чем мы перейдем к нашему первому примеру кодирования, давайте просто разберемся с комбинацией большего количества регистров, а именно: w и f.

W и F

Регистр W - это обычный регистр, который позволяет вам назначать любое значение по вашему выбору. Как только вы присвоите W величину, вы можете добавить ее к другому значению или просто переместить. Если присвоено другое значение, данные просто перезаписываются на W.

Регистр F направляет свои письменные материалы в регистр. Мы бы потребовали, чтобы этот регистр F назначал значение над регистром, может быть над регистрами STATUS или TRISA, поскольку они не позволяют нам помещать значения непосредственно над ними. Пример программы

Давайте рассмотрим следующий пример кода, который покажет нам, как реализована указанная выше инструкция, а также засвидетельствует несколько инструкций в курсе.

Начнем с исправления порта A, как описано выше.

Для этого нам нужно перейти из банка 0 в банк 1, это делается путем установки регистра STATUS, расположенного по адресу 03h, бит 5 на 1.

ЧФ 03ч, 5

BSF означает набор битов F. Мы используем два числа после этой инструкции - 03h, который является адресом регистра STATUS, и число 5, которое соответствует номеру бита.

Итак, мы говорим: «Установите бит 5 в адресе 03h в 1».

Сейчас мы в Банке 1.

MOVLW 00110b

Мы помещаем двоичное значение 00110 (буква b означает, что число является двоичным) в наш регистр общего назначения W. Я, конечно, мог бы сделать это в шестнадцатеричном формате, и в этом случае наша инструкция была бы такой:

MOVLW 06h

Либо работает. MOVLW означает «переместить буквенное значение в W», что на английском языке означает поместить следующее значение непосредственно в регистр W.

Теперь нам нужно поместить это значение в наш регистр TRISA, чтобы настроить порт:

MOVWF 85h

Эта инструкция указывает «Переместить содержимое W в следующий адрес регистра», в этом случае адрес относится к TRISA.

На этом этапе наш регистр TRISA имеет цифру 00110 или представлен графически:

Порт A Контакт RA4 RA3 RA2 RA1 RA0

Двоичный 0 0 1 1 0

Ввод / вывод O O I I O

Итак, теперь у нас есть контакты порта A, мы должны вернуться в банк 0, чтобы настроить одну из информации.

BCF 03ч, 5

Эта инструкция выполняет обратную BSF. Это подразумевает «Bit Clear F». Соответствующая пара чисел - это адрес регистра, в данном случае регистр STATUS, а также битовая цифра, в данном случае бит пять. Что именно мы закончили в настоящее время, так это определенный бит пятый на нашем

Регистр СТАТУСА на 0

В этот момент мы вернулись в банк 0.
Ниже приведен код в одном блоке:

BSF 03h, 5 Перейти в банк 1
MOVLW 06h Поместите 00110 в W
MOVWF 85h Переместите 00110 на TRISA
BCF 03h, 5 Вернитесь в банк 0

В последнем руководстве мы подтвердили, что вы можете установить контакты порта ввода-вывода на PIC как входные или выходные.

В этом курсе я помогу вам отправлять данные в порты.

Отправка данных в порты

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

Не пытайтесь собрать и запрограммировать ваш PIC с результатами, приведенными ниже, поскольку они являются только иллюстрациями. Первоначально мы установим порт A бит 2 как выход:

Это можно было узнать из предыдущего руководства. Единственное различие может заключаться в том, что мы зафиксировали каждый бит контактов на A в качестве вывода, передав 0h в регистр с тремя состояниями. Итак, что теперь он должен сделать, это включить светодиод.

Мы достигаем этого, устанавливая высокий уровень для одного из выводов (тот, к которому подключен светодиод). Другими словами, мы применяем к булавке цифру «1». Именно так это и выполняется (поясняйте комментарии к каждой строке):

Таким образом, теперь мы сделали то, что светодиод сначала включили, а затем выключили. Мы хотим, чтобы светодиод постоянно включался и затем выключался.

Мы достигаем этого, заставляя программу вернуться в начало. Мы достигаем этого, изначально устанавливая тег в начале нашей программы, а затем информируя программу о том, что она должна вернуться туда. Мы указываем тег довольно просто.

Мы вводим термин, скажем СТАРТ, затем набираем код:

Как показано, мы изначально упомянули выражение «Старт» непосредственно в самом начале программы.

Затем, в самом конце программы, мы прямо упомянули «goto Start». Инструкция «goto» выполняет только то, что объявляет.

Эта программа будет последовательно включать и выключать светодиод всякий раз, когда мы включаем цепь, и имеет тенденцию выключаться, когда мы отключим электричество. Может, стоит еще раз проверить нашу программу:

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

Позже это может вызвать небольшое недоумение, если вы попытаетесь устранить неполадки в программе и при написании кода запомните все адреса.

Хотя комментарии могут быть размещены, они могут стать немного загроможденными. Это потребует именования чисел и может быть выполнено дополнительной инструкцией: 'equ'. Инструкция 'equ' предполагает, что некоторые данные могут быть равны другим.

Возможно, это не инструкция для ПОС, а скорее для ассемблера. Эта инструкция облегчает присвоение имени ячейке адреса регистра или константы термину программирования.

Мы установим несколько констант для нашей программы, а также увидим, насколько просто читать программу.

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

поэтому всегда располагайте их в начале программы. Мы перепишем программу еще раз, исключив комментарии, чтобы сравнить предыдущую маркировку с последней.

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

У нашей программы мигания светодиодов может быть небольшой недостаток.
Для завершения каждой инструкции требуется 1 тактовая последовательность. В случае, если мы используем кристалл 4 МГц, тогда каждая инструкция требует для завершения 1/4 МГц или 1 мкс.

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

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

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

Назовем эту константу COUNT. После этого мы должны определить, с какого числа нужно начинать отсчет. Конечно, самое большое число, которое мы могли бы включить, это 255, или FFh в шестнадцатеричном формате. Как я уже говорил в предыдущем руководстве, инструкция equ назначает выражение для ситуации с регистром.

Это означает, что независимо от того, какое количество мы выделяем для COUNT, оно будет соответствовать элементам регистра. В случае, если мы попытаемся обозначить значение FFh, мы получим ошибку при компиляции программы.

Причина в том, что это местоположение FFh, поэтому мы не можем получить к нему доступ. Следовательно, как нам обозначить настоящий номер? Конечно, это потребует небольшого бокового размышления.

Если, возможно, мы назначим наш COUNT адрес, например, 08h, это будет указывать на основное назначение регистра цели. По умолчанию для нетронутых областей установлено значение FFh. Следовательно, если COUNT приводит к 08h, вы столкнетесь со значением FFh при первом включении. Тем не менее, как мы можем связать COUNT с другим числом? Все, что мы применяем, - это сначала «переместить» оценку в этот пункт назначения.

В качестве иллюстрации предположим, что мы хотели, чтобы COUNT имел значение 85h, мы не можем упомянуть COUNT equ 85h, так как это позиция нашего трехстороннего регистра для порта A. Именно мы добиваемся следующего: movlw 85hFirst put значение 85h в регистре W movwf 08h

Теперь переместите его в наш регистр 08h. Впоследствии, если мы выразим COUNT equ 08h, COUNT будет соответствовать значению 85h. Нежно, не правда ли! Следовательно, сначала мы определяем нашу константу: COUNT equ 08h Затем мы должны уменьшить это COUNT на единицу, пока оно не станет равным нулю.

Просто так получается, что существует одна инструкция, предназначенная для выполнения этого за нас, используя «goto» и тег.

Мы собираемся применить следующую инструкцию: DECFSZ COUNT, 1 В этой инструкции говорится: «Уменьшите регистр (здесь COUNT) на число, которое отслеживает запятую. Если мы достигнем нуля, прыгнем на две позиции вперед ». Давайте сначала обнаружим его в действии, прежде чем вводить его в наш курс.

Сначала мы установили нашу константу COUNT равной 255. Последующий сегмент позиционирует тег, называемый LABEL, рядом с нашей инструкцией decfsz.

Decfsz COUNT, 1 уменьшает значение COUNT на единицу и сохраняет конечный результат прямо в COUNT. Кроме того, он проверяет, имеет ли COUNT значение 0.

Если этого не происходит, в этом случае запускается переход программы к следующей строке. Теперь у нас есть объявление goto, которое возвращает нас к нашей инструкции decfsz.

В случае, если значение COUNT совпадает, тогда инструкция decfsz приводит к тому, что наша программа перескакивает на 2 позиции вперед и отправляется туда, где мы заявили «Продолжайте здесь».

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

Понимание циклов задержки

Если нам потребуется более существенная задержка, мы можем продолжить один цикл за другим. Чем больше петель, тем дольше задержка. Давайте, по крайней мере, двое, предполагая, что мы хотим наблюдать за миганием светодиода. Мы поместим эти циклы задержки в нашу программу и сделаем это, сделав ее настоящей программой, добавив комментарии:

Можно скомпилировать эту программу, после чего запрограммировать PIC. Очевидно, убедитесь, что вы пытаетесь проверить схему, чтобы проверить, действительно ли она работает. Ниже приведена принципиальная схема, которую вы должны построить, как только запрограммируете PIC.


Хорошо, вы могли бы составить свою первую программу PIC, а также сконструировать схему для включения и выключения светодиода. До сих пор, если вы прошли эти курсы, вы могли выучить в общей сложности семь инструкций из 35, но, без сомнения, до сих пор вы могли управлять портами ввода-вывода!

Не могли бы вы изменить циклы задержки, чтобы светодиодная вспышка отображалась быстрее - каково минимальное значение COUNT, чтобы, по сути, видеть светодиодную вспышку? Или, может быть, вы захотите включить третью или дополнительную петлю задержки после начальной, чтобы стабилизировать светодиод. уникальная константа для каждого цикла задержки.

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

Что такое подпрограммы

Преимущества использования подпрограммы заключаются в том, что, вероятно, будет проще изменить значение один раз внутри подпрограммы, а не, скажем, десять раз на протяжении всей вашей программы, а также это значительно способствует снижению уровня памяти, потребляемой вашей программой внутри подпрограммы. ПОС. Мы проверим подпрограмму:

Первоначально нам нужно предоставить нашей подпрограмме обозначение, и в этой ситуации мы выбрали ROUTINE. После этого мы набираем код, который хотим вести как обычно. Вот почему мы выбрали задержку в нашей программе мигания светодиодов. Наконец, мы завершаем подпрограмму вводом инструкции RETURN.

Чтобы начать выполнение подпрограммы из любого места в нашей программе, мы быстро набираем команду CALL, а затем - обозначение подпрограммы.

Мы рассмотрим это немного подробнее. Как только мы дойдем до раздела нашей программы, который называется CALL xxx, где xxx - это имя нашей подпрограммы, программа переходит в то место, где установлена ​​подпрограмма xxx. Инструкции внутри подпрограммы выполняются.

Всякий раз, когда выполняется инструкция RETURN, программа возвращается к нашей основной программе к инструкции, следующей за нашей инструкцией CALL xxx.

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

Тем не менее, вам следует знать несколько факторов. Изначально, как и в случае с нашей основной программой, необходимо подтвердить любые конкретные константы, прежде чем вы сможете их использовать.

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

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

PIC не будет различать подпрограмму и основную программу. Мы проверим нашу программу с мигающими светодиодами, однако на этот раз мы собираемся использовать подпрограмму для цикла задержки. В идеале вы обнаружите, насколько менее сложной выглядит программа, а также вы можете узнать, как подпрограмма применяется на практике.

В конце концов, вы можете заметить, что, используя подпрограмму для нашего цикла задержки, мы могли бы уменьшить размеры программы.

Каждый раз, когда нам нужна задержка, возможно, когда светодиод горит или выключен, мы в основном вызываем подпрограмму задержки. По завершении подпрограммы программа возвращается к строке, следующей за нашей инструкцией «Вызов». На рисунке выше мы включаем светодиод.

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

С помощью подпрограммы мы смогли уменьшить размер нашей программы до 103 байтов. Это не могло показаться таким фантастическим, однако, учитывая тот факт, что у нас всего 1024 байта внутри PIC, каждая небольшая сумма выигрывает.

В следующем руководстве давайте проверим чтение из портов.

До сих пор мы составляли порт A, чтобы иметь возможность включать и выключать светодиод. На этом этапе мы увидим, как мы собираемся считывать выводы ввода / вывода на портах.

Чтение портов ввода / вывода

Это сделано для того, чтобы мы могли подключить внешнюю цепь и влиять на любые конкретные выходы, которые она предлагает.

Если вы запомните наши предыдущие курсы, если вы хотите установить порты ввода-вывода, нам нужно было перейти с банка 0 на банк 1. Сначала мы сделаем это:

На данный момент у нас есть фиксированный бит 0 порта A для ввода. Теперь мы должны проверить, высокий или низкий уровень булавки. Для этого можно использовать только одну из двух инструкций:

BTFSC и BTFSS.

Инструкция BTFSC означает: «Проведите битовую проверку регистра, а также назначенного нами бита.

Если это 0, в этом случае мы опускаем следующую инструкцию ’. BTFSS подразумевает: «Проведите битовую проверку в регистре и установите бит. Если он установлен в 1, мы пропускаем последующую инструкцию.

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

Код здесь:

BTFSS PortA, 0 Начало работы Продолжайте здесь:
:

Программа просто переключится на «Продолжить здесь» при условии, что бит 0 на PortA назначен на 1.

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

Возможно, эту программу можно реализовать самостоятельно, но мы каким-то образом включили листинг.

Вы можете попытаться создать всю программу, чтобы проверить, поняли ли вы принципы. Мы будем использовать эквивалентную схему, как и раньше, с включением переключателя RA0 PIC и положительной шины нашего источника питания.

Что мы здесь сделали, так это включить светодиод. Впоследствии я определяю, замкнут ли переключатель.

Если он ограничен, я подключаюсь к нашей подпрограмме задержки. Это дает нам такую ​​же задержку, как и раньше, однако на данный момент мы связываемся с ней два раза.

То же самое относится к выключенным светодиодам. Если переключатель не замкнут, то у нас есть предыдущие записанные периоды включения и выключения.

Вы следовали этим урокам с самого начала? Возможно, вы пытаетесь понять, что в настоящее время открыли десять из 35 инструкций для PIC 16F84! И каждый бит из этого можно узнать, просто включив и выключив светодиод.

До сих пор мы включили и выключили мигание PIC светодиода.

Впоследствии мы смогли использовать наш PIC, включив переключатель, тем самым изменив скорость вспышки.

Эффективное использование пространства памяти

Единственная проблема в том, что программа довольно длинная и неэффективно использует память. Это казалось нормальным, когда я впервые включал команды, однако должен быть более простой способ его выполнения. Положительно, разберем, как мы буквально включали и выключали светодиод.

movlw 02hmovwf ПОРТАmovlw 00hmovlw ПОРТА

Сначала мы заполнили регистр w значением 02h, после чего передали его в регистр PortA для включения светодиода. Чтобы отключить его, мы упаковали w в 00h, после чего переместили его в наш регистр PortA.

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

Следовательно, нам нужно было передать два набора информации пару раз (один раз в регистр w, затем в PORTA), а также дважды вызвать подпрограмму (один раз для включения, затем один раз для выключения). Таким образом, как добиться этого с большей эффективностью? Очень просто.

Мы используем другую инструкцию, известную как XORF. Инструкция XORF выполняет функцию исключающего ИЛИ в регистре, которую мы оговариваем с информацией, которую мы предоставляем. Я считаю, что должен прояснить, что такое эксклюзивное операционное, прежде чем мы продолжим. В случае, если у нас есть два входа и один выход, входом может быть только 1, если и пока эти два входа различаются. Хотя они одинаковы, тогда на выходе, вероятно, будет 0. Следующая таблица истинности для тех, кто решит проверить их:

А Б F0 0 00 1 11 0 11 1 0

На этом этапе мы проверим, что происходит, если мы визуализируем B так же, как наш предыдущий вывод, и просто изменяем значение A:

А Б Ф
0 0 0
0 0 0
1 0 1
1 1 0
1 0 1

Если мы сохраним значение A таким же, как 1, и мы будем использовать исключающее ИЛИ с выходом, выход будет переключаться. Если вы не можете заметить это из таблицы истинности, ниже это можно увидеть с использованием двоичного кода:

0 Токовый выход
EX-OR с 1 1 новым выходом
EX-OR с 1 0 новым выходом

Возможно, вы обнаружите, что, выполняя исключительное ИЛИ для вывода с 1, мы теперь будем переключать вывод с 0 на 1 на 0.
Следовательно, чтобы включить и выключить наш светодиод, нам потребуется всего пара предложений:

MOVLW 02h
XORWF ДВЕРЬ, 1

Что именно мы и будем делать, так это добавить в наш регистр w значение 02h. В этом случае мы используем эксклюзивное ИЛИ для этого номера независимо от того, что находится на нашем PortA. Если бит 1 равен 1, он изменится на 0. Если бит 1 равен 0, он изменится на 1. Давайте рассмотрим этот код один или два раза, чтобы показать, как он работает с двоичным кодом:

ДВЕРЬ
00010
xorwf 00000
xorwf 00010
xorwf 00000
xorwf 00010

На самом деле нам не нужно каждый раз загружать идентичное значение в наш регистр w, поэтому можно выполнить это один раз в начале и просто вернуться к нашей команде переключения. Кроме того, нам не нужно фиксировать значение в нашем регистре PortA. Причина? Конечно, поскольку при включении он равен 1, мы можем легко переключить его. Я, в качестве альтернативы 0 при включении, мы бы даже сейчас переключили его.

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

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

Изменить размеры программы (байты)
Мигающий светодиод Original 120
Добавлена ​​подпрограмма мигающего светодиода 103
Мигающий светодиод Используемая функция XOR 91
Светодиод с переключателем оригинал 132
Светодиод с функцией XOR переключателя 124.

Таким образом, мы не только обнаружили несколько новых инструкций, но и, конечно же, уменьшили размер наших сценариев!

Ниже мы проанализируем, как вы можете перемещать отдельные биты, выполнять определенные простые арифметические операции, а также таблицы данных.

Логические менеджеры

В прошлом уроке я представил операцию Исключающее ИЛИ. Функция ExOR понимается как логический оператор.

В этом руководстве я расскажу о дополнительных логических операторах, которые продвигает PIC. В точечных программах не будет никаких примеров, однако мы научимся простым методам использования операторов, применяя небольшие участки кода.

И Функция И в основном анализирует два бита и выдает 1, если они одинаковы, и 0, если они различны. Например, если мы упомянули 1 И 1, результатом будет 1, а в случае, если мы объявили 1 И 0, результатом будет 0.

Излишне говорить, что мы также можем оценивать слова, так же как и все, что выполняет функция И, - это просмотр двух терминов по крупицам. Пример ниже демонстрирует, как два 8-битных слова соединяются оператором AND вместе с продуктом:

11001011
И 10110011
Равно 10000011

Надеюсь, вы согласитесь, результат будет просто иметь 1, когда 2 единицы идут рука об руку друг с другом в паре слов. Например, мы можем использовать функцию И для проверки портов.

В случае, если мы проверяем несколько контактов ввода / вывода, которые связаны со схемой, и мы должны следить за конкретной ситуацией, в которой только несколько контактов находятся в высоком уровне, в этом случае мы можем в значительной степени прочитать порт, после которого И результат с условием, которое мы изучаем, идентичный приведенному выше примеру.

PIC предоставляет нам два ингредиента для AND.
Это ANDLW и ANDWF. ANDLW позволяет нам выполнять функцию И с данными регистра W и суммой, которую мы оговариваем.

Синтаксис: ANDLW, в котором мы будем выполнять И с содержимым W.

Результат выполнения функции И будет сохранен непосредственно в регистре W.
ANDWF позволяет нам выполнять функцию И для регистра W и другого регистра, например, ПОРТА. Синтаксис: ANDWF, d в котором регистр, который нас интересует, например PORTA, а d показывает PIC, где вы должны разместить результат. Если d = 0, результат помещается в регистр W, а при d = 1 конечный результат сохраняется в регистре, который мы оговорили. Две части кода ниже показывают хороший пример каждой функции И.

Первоначально проверяется состояние PORTA, в котором нам нужно проверить, являются ли входы 1100. Мы можем поместить результат обратно в регистр W.

movlw 1100
ANDWF 05h, 0 Теперь вторая иллюстрация может проверять содержимое регистра W:
ANDLW 1100

ИЛИ ЖЕ

К настоящему времени мы обнаружили одну функцию ИЛИ, а точнее XOR. Это превращается в 1, если два бита не одинаковы, но различны. Вы можете найти другую функцию ИЛИ под названием IOR, которая является включающей ИЛИ. Эта функция будет генерировать 1, если любой бит равен 1, но дополнительно, если каждый бит равен 1. Ниже приводится четкая таблица истинности, чтобы проиллюстрировать это:

А Б О / П
0 0 0
0 1 1
1 0 1
1 1 1

Что такое арифметические операторы

ДОБАВИТЬ

Эта функция выполняет то, что обычно требует. Он вносит две цифры! В случае, если результат сложения двух цифр превышает 8 бит, в этом случае, вероятно, будет установлен флаг CARRY. Флаг CARRY расположен по адресу 03h бит 0.

Когда этот бит запланирован, то два числа превышают 8 бит. Когда это 0, в этом случае результат находится в пределах 8 бит. Как и раньше, PIC предоставляет нам два стиля ADD, а именно ADDLW и ADDWF. Как вы могли предположить, это очень похоже на приведенную выше функцию. ADDLW предлагает содержимое регистра W. Синтаксис следующий: ADDLW ADDWF добавляет содержимое регистра W и некоторого другого регистра, который мы назначаем.

Синтаксис: ADDWF, d - где

SUB

На данный момент, я думаю, вы не можете предположить, что выполняет эта функция! Вы действительно подозреваете, что эта функция
вычитает один бит из другого. И снова PIC предлагает нам 2 вкуса: SUBLW и SUBWF. Синтаксис точно такой же, как у функции ADD, за исключением того, что вы, очевидно, набираете SUB вместо ADD!

Приращение В случае, если мы хотим включить 1 в число в PIC, мы могли бы абсолютно использовать функцию ADD и использовать номер один. ~ Сложность в том, что мы должны сначала поместить цифру в регистр W, а затем использовать элемент управления ADDLW 1 для ее увеличения. Если мы захотим включить 1 в регистр, ситуация может быть еще хуже. Сначала мы должны поместить число 1 в регистр W, а затем использовать ADDWF, 1. Поэтому, например, чтобы включить 1 в ячейку 0C, нам понадобится следующая часть скрипта:

movlw 01
addwf 0c, 1

Существует более простой способ сделать это. Мы можем использовать команду INCF. Синтаксис следующий: INCF, d, где, - регистр или место, которое нас интересует, а d показывает PIC, где вы должны расположить результат. В случае d = 0 результат находится в регистре W, а в случае d = 1 последствия устанавливаются в регистре, который мы оговорили.

Используя эту индивидуальную инструкцию, мы можем фактически выполнить пятьдесят процентов кодирования. В случае, если мы хотели, чтобы результат был восстановлен в регистре W, в этом случае, используя приведенный выше пример, нам, возможно, пришлось бы включить дополнительную команду для сдвига элементов 0C обратно в регистр W, после чего вернуть регистр 0C в no независимо от того, что это было.

Есть команда увеличения. Это INCFSZ. Эта команда может увеличивать регистр, который мы оговариваем, однако, если регистр будет равен 0 после приращения (это произойдет, пока мы включим от 1 до 127), после этого PIC, вероятно, пропустит следующую инструкцию. Часть кода ниже отражает это:

Петля incfsz 0C
Goto Loop
:
:
Остаток программы.

В приведенной выше части кода 0C будет увеличиваться на 1. Далее мы владеем инструкцией, которая сообщает PIC, что нужно вернуться к нашему тегу с именем Loop и снова увеличить 0C на 1. Это продолжается до тех пор, пока 0C не станет равным 127. В этом случае, когда мы увеличиваем 0C на 1, 0C теперь будет соответствовать 0. Наша инструкция INCFSZ может очень хорошо проинформировать PIC, чтобы он пропустил следующую инструкцию, которая в данном случае является объявлением goto, следовательно, PIC продолжит выполнение оставшейся части программы.

Декремент

К настоящему времени мы обсудили функцию декремента в предыдущем обучении, поэтому я больше не буду ее пересматривать.

Дополнение

Последняя инструкция в этом обсуждении перевернет каждый бит в регистре, который мы оговариваем. Синтаксис: COMF, d где

Понимание битовых операций

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

В конце этого курса мы раскроем программу, предназначенную для создания набора последовательных огней, которые движутся вперед, а затем в обратном направлении. Мы заметили, что это произошло ранее, когда мы исследовали функцию исключающего ИЛИ, в которой мы объединили порты с использованием выражения исключающее ИЛИ. До сих пор мы заметили несколько битовых функций при установке портов на PIC, и

Позвольте мне повторить здесь их использование.

BCF

Эта инструкция сотрет немного, что мы оговорили в регистре, который мы назначаем. Синтаксис
является:
BCF,

Мы использовали это ранее для перехода со страницы 1 на страницу 0, удалив бит в регистре STATUS. Мы также можем использовать его для установки бита на 0 в любом другом регистре / месте. Например, если мы хотим установить 3-й бит в 11001101, сохраненном в разделе 0C, на 0, мы могли бы
вставлять:

BCF 0C, 03

BSF

Эта инструкция фиксирует любой установленный нами бит в 1 в любом регистре, который мы указываем. Мы использовали это ранее для перехода со страницы 0 на страницу 1. Синтаксис: BSF ,, и используется точно так же, как BCF выше.

BTFSCUp до сих пор мы могли устанавливать или очищать бит в регистре. Однако представьте, нужно ли нам в основном проверять, является ли бит 1 или 0 в регистре?

Конечно, можно использовать BTFSC. В нем указывается регистр битового теста F и пропустить, если он очищен. Эта инструкция будет анализировать бит, который мы обозначили в регистре. В случае, если бит равен 0, инструкция будет информировать PIC о необходимости пропустить следующую инструкцию.

Мы могли бы использовать эту инструкцию, если хотим проверить флаг, например флаг переноса. Это избавляет нас от необходимости читать регистр STATUS и искать отдельные биты, чтобы узнать, какие флаги зафиксированы. 29 Например, если мы хотим проверить, установлен ли флаг переноса на 1 после того, как мы добавили 2 цифры, мы могли бы ввести следующее:

BTFSC 03h, 0
продолжайте здесь, если установлено в 1
или здесь, если установлено значение 0

В случае, если статус бита равен 1, в этом случае команда, следующая за BTFSC, будет завершена. Если он установлен на 0, в этом случае последующая инструкция пропускается. Следующая часть кода показывает, в чем он может быть использован:

Петля :
:
:
BTFSC 03,0
Goto Loop

В приведенном выше коде PIC просто выйдет из цикла, если бит 0 регистра STATUS (или флаг переноса) установлен в 0. В противном случае будет выполнена команда goto.

BTFSS

В этой инструкции указывается регистр битового теста F и «Пропустить, если установлен». Это можно сравнить с инструкцией BTFSC, кроме того, что PIC пропустит последующую инструкцию, если бит, который мы оценивали, установлен в 1 вместо 0.

CLRF

Эта инструкция зафиксирует все детали регистра в 0. Синтаксис следующий:

CLRF
Мы использовали это ранее, чтобы установить выход портов на 0, применив CLRF 85h. Кроме того, мы использовали его, чтобы исправить порты, чтобы включить все выводы для вывода, используя CLRF.
05ч.

CLRW

Это могло бы напоминать инструкцию CLRF, за исключением очистки регистра W. Синтаксис довольно прост:

CLRW

RLF и RRF

Эти направления будут переносить бит в регистре на один слот влево (RLF) или вправо (RRF) в регистре. Например, если нам нужен 00000001 и мы использовали RLF, в этом случае мы могли бы иметь 00000010. Что происходит в этот момент, если есть 10000000 и мы применили инструкцию RLF? Конечно, 1 будет помещена во флаг переноса. Если бы мы применили инструкцию RLF еще раз, 1 снова появится в начале. То же самое происходит с инструкцией RRF, но наоборот. Пример ниже показывает это для инструкции RLF, в которой мы можем видеть 8 бит регистра, а также флаг переноса:

С 87654321
0 00000001
РЛФ 0 00000010
РЛФ 0 00000100
РЛФ 0 00001000
РЛФ 0 00010000
РЛФ 0 00100000
РЛФ 0 01000000
RLF 0 10000000
RLF 1 00000000
РЛФ 0 00000001

Пример программы

Теперь мы увидим пример кода, который можно скомпилировать и запустить. Он будет генерировать последовательный свет, начиная с бита 0 PortA, переходя к биту 8 PortB и
затем возвращаюсь.
Подключите светодиоды к каждому из контактов порта. У нас будет немного
процедуры, указанные в этом руководстве.

TIME EQU 9FH Переменная для контура задержки.
PORTB EQU 06H Адрес порта B.
TRISB EQU 86H Порт B Трехсторонний адрес.
PORTA EQU 05H Адрес порта A.
TRISA EQU 85H Порт A Трехсторонний адрес.
STATUS EQU 03H Регистр выбора страницы.
COUNT1 EQU 0CH Регистр цикла.
COUNT2 EQU 0DH Регистр цикла.

СТАТУС ЧФ, 5 Перейти на страницу 1
MOVLW 00H и настроить
MOVWF TRISB оба порта A и B
MOVLW 00H для вывода,
MOVWF TRISA затем вернитесь в
СТАТУС BCF, 5 стр. 0.
MOVLW 00H Очистить порт A.
ДВЕРЬ MOVWF

Старт основной программы

RUNMOVLW
01H Установить первый бит MOVWF
PORTB на порту B.CALL
ЗАДЕРЖКА Подождите немного
ЗАДЕРЖИВАТЬ
Переместите бит на порту B влево, затем сделайте паузу.
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRLF
PORTB, 1 Перемещает бит во флаг переноса.
Теперь перейдите в порт A и переместите бит влево.
PORTA, 1 Перемещает бит из нулевого флага в PortACALL.
ЗАДЕРЖКА ВЫЗОВАRLF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
DELAYRLF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
DELAYRLF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
ЗАДЕРЖИВАТЬ
Верните бит на порт ARRF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
DELAYRRF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
DELAYRRF
ДВЕРЬ, 1 ВЫЗОВ
DELAYCALL
DELAYRRF
PORTA, 1 Перемещает бит в нулевой флаг. Теперь переместите бит.
обратно в порт BRRF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL
DELAYRRF
ПОРТБ, 1ЗВ.
DELAYCALL
ЗАДЕРЖКА Теперь мы вернулись к тому, с чего начали, НАЙТИ
БЕГ, пойдем еще раз.

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

Таблица данных - это просто список цитат данных, в котором все просматривается с учетом нескольких соображений.
Например, у вас может быть схема, которая использует PIC, который подсчитывает количество случаев, когда входной вывод становится высоким за 1 секунду. После этого вы можете отобразить число на 7-сегментном дисплее.

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

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

Это облегчает для тех, кто выполнил определенное программирование на BASIC. В противном случае не беспокойтесь, возможно, вы захотите продолжить изучение теории. Envision существует программа BASIC, аналогичная представленной ниже:

10 ЛЕТ K = 0
11 К = К + 1
12 ЕСЛИ K> 10 ТОГДА ПЕРЕХОДИТЕ 20 ИНАЧЕ ПЕРЕХОДИТЕ 11
20 ПЕЧАТЬ K
21 КОНЕЦ

Программа начинается со строки 10. Как только K запланировано на 0, она переходит к строке 11. После того, как мы добавили 1 к K, мы переходим к строке 12.

На этом этапе нам может быть любопытно, больше ли K, чем 10. В таком случае мы переходим к строке 20 или же возвращаемся к строке 11.

Строка 20 документирует букву K, а строка 21 завершает программу. BASIC использует линейную статистику, чтобы помочь программисту вести учет проблем, поскольку лейблы не авторизованы. PIC использует метки для перехода между пунктами назначения - или действительно так?

Мы используем ярлыки, чтобы быть в курсе проблем, а также чтобы мы могли простым способом сообщить PIC, где искать.

Происходит именно то, что PIC использует счетчик внутренней линии, называемый Program Counter. Программный счетчик (сокращенно PC) след места назначения в памяти, где находится настоящая инструкция.

Каждый раз, когда мы сообщаем PIC о посещении выбранной метки, он понимает место в памяти и, следовательно, дополняет ПК, пока не увидит это место назначения. Это точно такой же метод, как мы проверяли программу BASIC выше. Ниже представлен фрагмент кода с областями памяти или элементами ПК рядом с каждой инструкцией:

Инструкция для ПК0000 movlw 03
0001 movwf 0C
0002 Шлейф decfsc 0C
0003 goto Loop
0004 конец

В приведенной выше демонстрации мы установили для ПК значение 0000. На этом этапе у нас есть инструкция movlw 03. Когда PIC реализовал эти данные, он увеличивает ПК на единицу, чтобы сканировать последующую инструкцию. На этом этапе PIC просматривает movwf 0C. ПК снова увеличен.

Сейчас ПОС изучает decfsc 0C. В случае, если детали 0C не равны 0, в этом случае ПК увеличивается на 1, а также следующая инструкция goto Loop информирует ПК о возвращении в позицию 0003, которая является упомянутым циклом. В случае, если детали 0C равны 0, тогда ПК рекомендуется увеличить на 2, просто опустите последующую инструкцию.

Понимание таблиц данных

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

PC equ 02
movlw 03
таблица звонков
:
стол addwf PC
retlw 01
retlw 02
retlw 03
retlw 04
retlw 05
retlw 06
retlw 07
вернуть

Первоначальная инструкция присваивает метке PC адрес программного счетчика (02h). Скоро мы внесем значение 03h в регистр w. После этого общаемся со столом. Самая передняя строка в таблице подпрограмм дополняет данные регистра W (03h) счетчика программ.

Это приводит к увеличению счетчика программ на 3 или, другими словами, заставляет счетчик программ двигаться вниз на 3 строки. Пока счетчик переходит на 3 строки ниже, PIC распознает команду retlw. Эта команда отправляет следующее за ней значение в регистр W, после чего возвращается из подпрограммы. RETLW в основном означает Return, буквально для W.

Смотрите, я поставил запятую после слова Return. Поскольку мы находимся в подпрограмме, нам нужна инструкция Return для ее выхода. Поэтому RET в инструкции. После инструкции RETLW идет число, и это именно то, что помещается в регистр W.

В данном случае это цифра 3. Мы могли бы обозначить любую величину в регистре W, пока эта цифра объединена с Program Counter в подпрограмме table, мы собираемся обнаружить инструкцию retlw. В приведенной выше иллюстрации это подразумевает, что мы можем иметь любое число от 1 до 7. В случае, если мы продолжим подпрограмму, мы могли бы завершить выполнение дополнительного раздела программы. По этой причине, как правило, разумным шагом является размещение таблицы данных точно в конце программы PIC, поэтому, если в этом случае мы действительно перескочим, мы все равно придем к завершению программы.

Тема прерываний может оказаться самой длинной и сложной для обсуждения.

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

Что такое прерывание? Конечно, как указывает термин, прерывание - это метод или сигнал, который предотвращает микропроцессор / микроконтроллер от того, что он выполняет, что может произойти что-то другое.

Позвольте мне привести вам ежедневную иллюстрацию. Представьте, что вы отдыхаете в собственном доме, разговариваете с другим человеком. Вдруг звонит телефон.

Вы прекращаете разговор и берете телефон, чтобы поговорить с звонящим. После разговора по телефону вы решаете вернуться к разговору с человеком до того, как зазвонит телефон. Во время разговора с кем-то можно подумать о своей основной рутине: телефонный звонок мешает вам разговаривать, а перерыв - это способ разговора по телефону.

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

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

Понимание прерываний

PIC имеет 4 источника прерывания. Их можно разбить на несколько групп. Два являются источниками прерываний, которые могут использоваться внешне для PIC, а два других - внутренние процессы. Позвольте мне пояснить здесь два внешних типа. Два других будут описаны в разных руководствах, когда мы перейдем к таймерам и хранению данных.

Если вы посмотрите распиновку PIC, вы заметите, что контакт 6 - это RB0 / INT. На этом этапе RB0 явно является битом 0 порта B. INT означает, что он также может быть настроен как внешний вывод прерывания. Кроме того, контакты с 4 по 7 порта B (контакты с 10 по 13) также могут использоваться для прерываний. Прежде чем мы сможем использовать INT или другие контакты порта B, мы должны выполнить две задачи. Прежде всего мы должны сообщить PIC, что мы будем использовать прерывания.

Затем мы должны указать, какой вывод порта B мы будем использовать как прерывание, а не как вывод ввода-вывода. Внутри PIC вы можете найти регистр, известный как INTCON, по адресу 0Bh. В этом регистре вы обнаружите 8 бит, которые могут быть включены или отключены. Бит 7 INTCON известен как GIE. Это Global Interrngupt Enable. Установка этого параметра на 1 сообщает PIC, что мы будем использовать прерывание.

Бит 4 INTCON известен как INTE, INTerrupt Enable. Установка этого бита в 1 сообщает PIC, что RB0 будет выводом прерывания. Конфигурирование бита 3, называемого RBIE, сообщает PIc, что мы собираемся использовать биты с 4 по 7 порта B. На этом этапе PIC понимает, когда этот вывод может быть высоким или низким, должен остановить то, что он выполняет, и продолжить прерывание рутина. На этом этапе мы должны сообщить PIC, будет ли прерывание, вероятно, на восходящем фронте (от 0 В до + 5 В) или на спадающем фронте (от + 5 В до 0 В) преобразования сигнала.

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

«Запуск» фронта планируется в дополнительном регистре, называемом регистром OPTION, по адресу 81h. Бит, который нам нравится, - это бит 6, который часто называют INTEDG.

Установка этого значения в 1 запускает PIC для прерывания на монтажной кромке (состояние по умолчанию), а установка в 0 стимулирует PIC для прерывания на скользящей кромке. Если вы хотите, чтобы PIC активировался на переднем фронте, вам, конечно, не нужно ничего делать с этим битом.

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

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

Это информирует внутренний процессор PIC о том, что произошло прерывание. Затем счетчик программ (о котором я говорил в предыдущем руководстве) указывает конкретный адрес в PIC. Давайте быстро рассмотрим все это по отдельности. Флаг прерывания В нашем регистре INTCON бит 1 - это флаг прерывания, называемый INTF. На этом этапе всякий раз, когда возникает какое-либо прерывание, этот флаг, вероятно, будет установлен на 1.

Когда нет прерывания, флаг устанавливается в 0. И это почти все, что нужно. В этот момент вы, возможно, думаете: «В чем смысл?» Конечно, даже если этот флаг установлен на 1, PIC не может и не будет реагировать на другое прерывание. Поэтому, скажем так, мы вызываем прерывание. Флаг, вероятно, будет установлен на 1, и PIC может перейти к нашей программе для обработки прерывания.

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

Рекомендуется завершить один диалог, а затем снова взять телефон, чтобы поговорить с последующим человеком. Вы можете найти небольшую проблему с этим флагом. Хотя PIC быстро устанавливает этот флаг в 1, он не устанавливает его снова 0! Эту деятельность должен выполнять программист, то есть вы. Это может быть выполнено без особых усилий, как я уверен, и должно быть выполнено после того, как PIC выполнит процедуру прерывания.

Расположение в памяти При первом включении PIC или в случае сброса счетчик программ указывает адрес 0000h, который может быть сразу же в начале памяти программ. Но в случае прерывания счетчик программ укажет адрес 0004h.

Следовательно, пока мы составляем нашу программу, которая будет иметь прерывания, мы сначала должны сообщить PIC, что нужно переключиться на адрес 0004h, и поддерживать процедуру обработки прерывания, которая начинается с адреса 0004h, отличного от остальной части программы.

Это может быть легко выполнить. Первоначально мы начинаем нашу программу с команды, известной как ORG. Эта команда указывает исходную точку или начало. Мы придерживаемся адреса. Поскольку PIC начинается с адреса 0000h, мы вводим ORG 0000h. После этого мы должны обойти адрес 0004h. Мы достигаем этого, помещая инструкцию GOTO вместе с меткой, указывающей на нашу основную программу.

Мы после этого придерживаемся этой команды GOTO с еще одной ORG, на этот момент с адресом 0004h. После этой команды мы вставим нашу процедуру прерывания. На этом этапе мы могли бы, возможно, ввести нашу процедуру прерывания сразу после второй команды ORG, или мы можем разместить оператор GOTO, который указывает на процедуру прерывания.

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

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

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

Если вы не осторожны, регистр w будет включать последнее значение, которое он получил, когда был в программе прерывания, поэтому, когда вы вернетесь из прерывания, эта информация будет доставлена ​​в порт A, а не то значение, которое вы имели ранее. произошло прерывание.

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

Независимо от частоты этого тактового сигнала, PIC делит его на 4, после чего использует его для внутреннего отсчета времени. Например, если у вас есть кристалл 4 МГц, связанный с вашим PIC, в этом случае PIC будет выполнять инструкции на 1 МГц. Это внутреннее время известно как цикл инструкций. На данный момент в таблице данных утверждается (несомненно, уменьшенным шрифтом), что вам необходимо разрешить от 3 до 4 циклов команд между прерываниями.

Я бы включил 4 раунда. Причина задержки в том, что PIC требуется время, чтобы перейти к адресу прерывания, флагу, и вернуться из подпрограммы прерывания. Поэтому имейте это в виду, если вы работаете с альтернативной схемой, чтобы активировать прерывание для PIC.

Здесь важно то, что если вы используете биты с 4 по 7 порта B в качестве прерывания. Вы не можете выбрать определенные контакты порта B для работы в качестве прерывания.

Следовательно, если вы разрешите эти контакты, скорее всего, все они будут доступны. Поэтому, например, вы не можете просто иметь биты 4 и 5 - биты 6 и 7, скорее всего, будут задействованы одновременно. Какова именно цель получения четырех битов для представления прерывания? Конечно, у вас может быть цепь, подключенная к PIC, на случай, если какая-либо из четырех линий станет высокой, в этом случае это может быть проблемой, на которую вам потребуется, чтобы PIC немедленно повлиял.

Одной иллюстрацией этого может быть сигнализация домашней безопасности, в которой четыре датчика подключены к контактам 4-7 порта B. Любой конкретный датчик может побудить PIC инициировать сигнал тревоги, а процедура подачи сигналов тревоги - это процедура прерывания. Это избавляет от постоянной проверки портов и позволяет PIC продолжать решать различные вопросы. В следующем уроке мы собираемся составить программу для управления прерыванием.

В прошлом уроке мы рассмотрели множество основ, поэтому я чувствую, что пришло время составить нашу первую программу.

Программа, которую мы напишем, будет подсчитывать количество раз, когда мы включаем выключатель, а затем отображать это количество.

Программа будет считать от 0 до 9, отображаемую на 4 светодиодах в двоичной форме, вместе с входом или прерыванием, вероятно, будет на RB0.

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

Вы заметите, что мы используем уникальный метод отображения шестнадцатеричных чисел. Раньше я применил F9h, в котором h означает шестнадцатеричный. Мы могли бы записать это как 0xF9, и это структура, которую мы собираемся использовать с этого момента.

Теперь нам нужно сообщить PIC, что мы собираемся использовать прерывания, и мы используем вывод 6 RB0 в качестве вывода прерывания:

bsf INTCON, 7GIE - Глобальное разрешение прерывания (1 = разрешено)
bsf INTCON, 4INTE - разрешение прерывания RB0 (1 = разрешено)
Я на всякий случай сброшу флаг прерывания (я ничему не доверяю!)
bcf INTCON, 1INTF - Очистить бит флага на всякий случай

В настоящее время мы должны установить наши 2 порта. Имейте в виду, что, поскольку сейчас мы используем RB0 в качестве вывода прерывания, его необходимо установить как вход:

Мы собираемся использовать переменную COUNT для хранения количества переключений. Мы могли бы просто увеличить значение порта A, но вы поймете, почему я использую переменную, когда мы пишем нашу процедуру прерывания.

Следовательно, наша основная программа составлена, и на этом этапе мы должны сообщить PIC, как действовать, когда происходит прерывание. В этом примере наше прерывание, вероятно, будет переключателем. Как раз то, что мы хотели бы, чтобы PIC был один для регулируемого COUNT каждый раз, когда переключатель ограничен.

Тем не менее, мы просто хотим показать, сколько раз переключатель отключается с 0 до 9. Выше я говорил, что мы могли бы просто увеличивать значение порта A каждый раз, когда возникает прерывание. Однако порт A имеет 5 битов, в случае, если мы просто увеличиваем порт, у нас будет максимальное значение 31. Есть несколько объяснений, почему я решил не увеличивать значение до 31.

Первоначально мы будем использовать 7-сегментный экран, который может изменяться от 0 до 15 (от 0 до F в шестнадцатеричной системе). Затем я дополнительно хочу показать вам несколько арифметических команд, на которые вы наткнулись на последних нескольких уроках.

Поэтому мы продолжим нашу процедуру прерывания. В настоящее время первое, что мы должны сделать, это кратко сохранить детали нашего регистра w, так как мы применяли это для сдвига содержимого COUNT в PORTA. Если мы не сохраним его, в этом случае мы сможем предоставить совершенно другое число из-за нашей арифметики. Поэтому давайте сначала займемся этим:

На этом этапе мы понимаем, равно ли значение COUNT 9 или больше. Теперь нам нужно сделать следующее: если COUNT больше 9, вернуть его к 0 или вернуться в основную программу, чтобы убедиться, что мы можем доставить его в порт A. Команда BTFSS, поскольку вы понимаете, будет ли последующая
инструкция в случае, если запланирован флаг переноса, т.е. COUNT = 10:

Единственное, что осталось сделать сейчас, это ввести коллективно, а также определить значения наших констант, которые мы можем выполнить прямо в начале нашей программы.

Каждый раз, когда вы активируете переключатель, светодиоды будут считать в двоичном формате от 0000 до 1010, а затем обратно до 0000.

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

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

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




Предыдущая статья: Программируемая двунаправленная схема таймера двигателя Далее: Как работают схемы понижающего повышения