Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Samouchitel

.pdf
Скачиваний:
16
Добавлен:
13.02.2015
Размер:
3.65 Mб
Скачать

10. Как отследить выполнение программы

Важность этой работы очевидна.

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

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

То есть, речь идет о сборе данных для последующего анализа причин "перекосяка", с целью его устранения.

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

Отследить перемещение рабочей точки программы, по тексту программы, можно в текстовом редакторе MPLAB или в окне Program Memory Window (вызывается кнопкой

ROM).

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

Вбольшинстве случаев, отслеживание движения рабочей точки производится в текстовом редакторе MPLAB, так как это гораздо более комфортно, а окно Program Memory Window "вызывается" тогда, когда нужно узнать порядковый номер той или иной команды или ее адрес в памяти программ, а также разложение (на команды) директив/макросов.

Вокне Program Memory Window можно назначить точки остановки.

Технология этого назначения такая же, как и при назначении точек остановки в текстовом редакторе: щелчок правой кнопкой мыши по строке с командой и выбор (щелчок левой кнопкой мыши) из списка строки Break.

После этого, выбранная строка (в окне Program Memory Window) окрашивается в красный цвет, и в текстовом редакторе, Вы увидите то же самое (как будто бы Вы назначили точку остановки в текстовом редакторе).

Окно Special Function Register Window (кнопка SFR).

Это окно бывает полезным при работе с программами, которые управляются внешними сигналами.

Если Вы заранее не предприняли мер по установке необходимых Вам уровней этих внешних, управляющих сигналов (функции стимула не задействованы), то MPLAB, на момент начала исполнения программы, "тупо" выставит на этих выводах "свои" уровни (по умолчанию). Откройте программу cus (сбрасывать ее на начало и исполнять не нужно, просто откройте и все).

Щелкните по кнопке SFR.

Откроется окно Special Function Register Window, в котором Вы увидите эту настройку по умолчанию.

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

Во всех битах регистра TrisB записаны единицы, следовательно, на момент начала исполнения программы, все выводы порта B "виртуального" ПИКа работают на вход. Если эти состояния не изменить программными средствами (имеется ввиду и программа, с которой происходит работа, и MPLAB), то они такими и останутся.

То же самое относится и к регистру TrisA.

С поправкой на то, что в трех его старших битах, по умолчанию, выставлены нули.

Врегистре Option выставлены все единицы.

Чем руководствовались при этом разработчики MPLAB, остается только гадать. Это просто нужно "принять как данность".

В регистре Status, биты №3 и 4 установлены в 1, что соответствует, якобы, прохождению сброса по включению питания ("якобы" потому, что ПИК "виртуальный").

Если сбросить программу на начало, то в окне Special Function Register Window ничего не изменится, за исключением того, что красное выделение пропадет.

121

Из оставшихся настроек "по умолчанию", прежде всего, необходимо обратить внимание на нули в регистрах PortA и PortB.

Ранее мы уже сталкивались с тем, что из-за этого возникали затруднения (переход в "ненужный" сценарий работы программы) при отладке программы cus.

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

Вывод из этого простой: если в результате исполнении команд, обращающихся к регистрам PortA или PortB, возникнут затруднения с переходом в нужный сценарий работы программы, то необходимо открыть окно Srecial Function Register Window,

посмотреть на содержимое этих регистров (на момент исполнения команды) и сделать соответствующие выводы.

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

Примечание: это не относится к регистру PCL, так как его содержимое, по ходу исполнения программы, постоянно изменяется.

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

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

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

Так как содержимое регистров специального назначения удобнее всего воспринимать в бинарном виде, то окно Special Function Register Window может оказаться весьма полезным.

Но основным, "рабочим" окном является окно File Register Window (кнопка RAM).

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

Если Вы сравните содержимое регистров специального назначения, расположенных в этом окне, с содержимым регистров специального назначения, расположенных в окне Special Function Register Window (с учетом перевода чисел из одной системы исчисления в другую), то обнаружите полное соответствие, причем, в интервале времени от открытия проекта и до сброса программы на начало, содержимое указанных выше, 4-х регистров специального назначения, будет также выделено красным цветом (после сброса программы на начало, красное выделение снимается).

Это полное соответствие наблюдается и по ходу исполнения программы.

Обычно, в течение основной части времени отслеживания работы программы, пользуются окном File Register Window (оно более информативно), а окно Special Function Register Window открывают по мере необходимости (а можно открыть оба, и не закрывать их до конца работы).

Неудобство применения окна File Register Window связано с тем, что названия регистров специального назначения в нем не указываются (указываются адреса), и это, на первых порах, может вызвать затруднения в ориентации, что совсем не "смертельно".

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

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

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

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

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

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

122

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

Так как в PIC16F84A, содержимое регистров общего назначения нулевого банка дублируется (отображается) в первом банке, то на последние 4 строки таблицы окна File Register Window можно не обращать внимания, а оставить только 1-ю строку 1-го банка (с регистрами специального назначения).

Лично я, изменяю размер этого окна таким образом, чтобы нижняя граница окна MPLAB "наехала" на эти 4 строки окна File Register Window и закрыла их.

Так оно занимает меньше места.

Что касается кнопки с очками, то "жать" на нее имеет смысл только в том случае, если необходимо отследить содержимое регистра W (в других окнах, содержимое регистра W не отслеживается).

В этом окне, конечно же, можно отследить содержимое и всех остальных регистров, но удобнее это сделать в окне File Register Window.

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

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

Если возникает потребность в отслеживании содержимого регистра W, то он заносится в окно Watch (как это делается, описывалось ранее).

Если предельно уменьшить размеры этого окна, то оно получается очень компактным и "малогабаритным".

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

А теперь, на практике, отследим выполнение "учебно-тренировочной" программы cus.

Откройте любой из проектов cus_1 или cus_2.

Сначала будем работать с отлаженной программой (команда goto PRD на nop не заменялась).

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

-Program Memory Window на ROM,

-File Register Window на RAM,

-Special Function Register Window на SFR,

-Watch - без изменения.

"Наводим порядок на рабочем месте".

Если "лист" текстового редактора раскрыт полностью, то уменьшите его размеры, отодвинув к центру правый и нижний срезы этого "листа" на 1 - 2 см.

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

Открываем окно RAM и перемещаем его в правый нижний угол окна MPLAB.

"Цепляемся" за верхний срез окна RAM и двигаем его вниз до тех пор, пока нижние 4 строки таблицы перестанут быть видны.

Создаем окно Watch, "заложив" в него регистр W.

Размещаем это окно выше окна RAM (нижний срез окна Watch - "впритык" к верхнему срезу окна RAM), и правый срез окна Watch "двигаем вправо до упора".

"Цепляемся" за верхний левый угол окна Watch и уменьшаем его размер до минимально возможного.

Получилось так:

123

А можно и так:

Или так:

124

"Прожиточный минимум" выставлен.

Остальные окна можно открывать по мере необходимости.

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

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

Поэтому щелкаем по кнопке со следами или жмем F7 (сброс программы на начало). Для краткости, "привяжемся" к кнопке F7 клавиатуры.

Итак, жмем на F7 и переходим на первую команду ПП START.

То, что рабочая точка программы "встала" на команду clrf IntCon, означает то, что исполнилась не эта команда, а предшествующая, то есть, команда goto START (та, что в "шапке" программы).

Смотрим в окна RAM и Watch.

Изменилось только содержимое регистра с адресом 02h (содержимое выделилось красным цветом).

Смотрим в распечатку области оперативной памяти: по этому адресу расположен счетчик команд (регистр PCL), и его содержимое изменилось с 00h на 01h, то есть, произошел переход рабочей точки программы на вторую команду программы, а предшествующая (первая) команда была исполнена.

По причине того, что по ходу исполнения программы, содержимое регистра PCL последовательно изменяется, я не буду "заострять" Ваше внимание на его содержимом. Регистр PCL задействуется всегда (при выполнении любой программы), и его содержимое всегда окрашено в красный цвет (сами ответьте на вопрос: почему?).

Итак, исполнилась команда goto START.

Смотрим в распечатку команд: команда goto выполняется за 2 м.ц. (можете вызвать секундомер и проверить) и при этом, никаких операций с содержимым регистров не производится (эта команда не меняет их содержимого и на состояния флагов не влияет). Поэтому не удивительно, что кроме изменения показаний счетчика команд, никаких других изменений, в открытых нами окнах, не произошло.

Нажимая F7, выполняем команду clrf IntCon.

Рабочая точка программы "перескочила" на команду clrwdt, и содержимое регистра, с

125

адресом 03h, окрасилось в красный цвет (изменение с 18h на 1Ch). Смотрим в распечатку области оперативной памяти.

Этот адрес имеет регистр Status. Смотрим в распечатку команд.

При исполнении команды clrf должен установиться флаг нулевого результата (Z), что и произошло.

Проверяем: 18h=00011000, 1Ch=00011100.

Все правильно: 2-й бит (или бит № 2) регистра Status, с названием Z, установился в 1. Вопрос: "Почему содержимое регистра IntCon (адрес 0Bh) не окрасилось в красный цвет, ведь с его содержимым производилась операция?

Ответ: потому, что в результате инициализации "виртуального" ПИКа (по умолчанию), в этом регистре "выставлен" 0, а при сбросе нуля в ноль получается ноль.

Это называется подтверждением ранее установленного состояния.

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

Нажимая на F7, выполняем команду clrwdt.

Ничего не изменилось, кроме показания счетчика команд.

Эта команда управляет аппаратной "начинкой" ПИКа, а если конкретно, то сторожевым таймером, и устанавливает (в единицы) биты (флаги) регистра Status с названиями -TO и -PD (см. распечатку команд).

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

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

Выполняем команду (далее, это словосочетание означает нажатие/отжатие F7) bsf Status,RP0.

Содержимое регистра Status изменилось с 1Ch (00011100) на 3Ch (00111100).

Все правильно: в 5-м бите регистра Status (выбор банка) установилась 1 (выбор 1-го банка). Выполняем команду movlw .65

Теперь "покраснела" строка в окне Watch.

То есть, произошла запись числа .65 в аккумулятор (в регистр W). Переводим десятичное число .65 в 16-ричное и получаем 41h.

Сверяемся: это число и записалось (правда, буквы h нет, но она подразумевается). Выполняем команду movwf TrisB.

"Покраснело" содержимое регистра TrisB, и в него, из регистра W, скопировалось (именно скопировалось, а не вырезалось см. регистр W) число 41h.

Переводим число 41h в бинарную форму. Получается 01000001.

Все правильно: 0-й и 6-й биты установлены в 1 (выводы RB0 и RB6 работают "на вход", а остальные, "на выход").

Следующие две команды выполняются аналогично, только число .143 копируется, из регистра W, в регистр OptionR.

Убедитесь в правильности их выполнения самостоятельно.

Так же самостоятельно убедитесь в том, что после исполнения команды bcf Status,RP0, в 5-м бите регистра Status, 1 сменилась на 0 (выбор 0-го банка).

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

Разница только в том, что константы (через W) записываются не в регистры специального назначения, а в регистры общего назначения (SecH и SecL), адреса которых (0Dh и 0Eh) Вы найдете в "шапке" программы.

Входе исполнения этой группы команд, Вы увидите, что содержимое регистра TMR0 (адрес 01h) изменится, и далее, по ходу исполнения программы, в нем будет что-то подсчитываться. Хотя, в данном случае, то что он считает, "по барабану" (TMR0 в программе не задействован), но с познавательной точки зрения, разобраться с этим стОит.

Настройки TMR0 производятся с помощью битов регистра OptionR.

Внего мы записали число .143 (10001111).

5-й бит этого регистра установлен в 0, следовательно, на вход TMR0 подан внутренний тактовый сигнал (называется CLKOUT).

То есть, TMR0 будет считать количество машинных циклов.

На работу программы cus это никоим образом не влияет, но если кому-то из Вас не нравится "лишняя точка отвлечения внимания", то от входа TMR0, можно отключить сигнал внутреннего такта и подключить вход TMR0 к внешнему такту, то есть, к выводу RA4/TOCKI.

126

Вданном случае, к выводу RA4/TOCKI, источник внешнего такта не подключен. А раз это так, то в регистре TMR0 зафиксируются нули, и его содержимое, по ходу исполнения программы, меняться не будет (можете проверить).

Для того чтобы это сделать, в команде movlw .143, нужно заменить константу .143 на константу .175 Почему .175 ? Ответьте на этот вопрос самостоятельно.

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

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

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

Такого рода "хождения по мукам" полезны тем, что помогают понять следующее:

настройкой "виртуального" ПИКа, по умолчанию, является настройка MPLAB на момент открытия проекта, а не настройка по сбросу программы на начало, после того, как рабочая точка программы "погуляла" по программе.

Работаем дальше.

"Упираемся" в команду btfsc PortB,0.

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

То есть, нужно посмотреть, в каком состоянии, перед исполнением этой команды, находится бит №0 регистра PortB.

Для этого нужно открыть окно SFR, найти в нем регистр PortB и посмотреть на состояние этого бита.

Вданном случае, по умолчанию, он установлен в 0 (функции стимула не используются). После этого, окно SFR можно закрыть (а можно и оставить. Это кому как нравится). Вывод: после исполнения команды btfsc PortB,0, "ухода в вечное кольцо" ПП START не произойдет.

То есть, после исполнения команды btfsc PortB,0, будет исполнена команда btfss PortB,6.

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

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

То есть, ноль, в нулевом бите регистра PortB, который MPLAB выставила по умолчанию, в данном случае, устраивает.

Выполняем команду btfsc PortB,0.

Рабочая точка программы переместилась на команду btfss PortB,6 Смотрим в окно RAM.

Изменений нет (кроме PCL), так как значение нулевого бита считывалось, а не

записывалось.

Перед выполнением команды ветвления btfss PortB,6, необходимо произвести проверку, аналогичную описанной выше.

После этого, выясняется следующее: с учетом текущего значения 6-го бита регистра PortB, = 0 (выставлен MPLAB по умолчанию), после исполнения команды btfss PortB,6, будет исполнена команда goto PRD и рабочая точка программы "улетит" в ПП PRD. Предположим, что отслеживание выполнения этого сценария предполагается отложить "на потом", а сейчас необходимо отследить выполнение другого сценария.

Для реализации этого, прибегаем к "уловке" (о ней говорилось ранее): меняем goto PRD на nop.

Так как в текст программы внесены изменения, то его нужно проассемблировать и выполнить программу, с самого начала и до команды btfss PortB,6.

Исполняем команду btfss PortB,6.

Смотрим в окно RAM: "картина" такая же, как и при выполнении команды btfsc PortB,0 (и по той же причине).

127

Выполняем команду nop.

Вокне RAM опять ничего не меняется (кроме PCL), так как эта команда не производит никаких действий.

Итак, рабочая точка программы "вышла на оперативный простор" и "стоит" на команде bcf PortB,2.

Исполняем эту команду.

Вокне RAM опять ничего не изменилось (кроме PCL).

Почему, ведь команда bcf PortB,2 является командой, влияющей на содержимое регистра? Объяснение: по умолчанию, 2-й бит регистра PortB установлен в 0.

То есть, имеет место быть подтверждение ранее установленного состояния ("краснеть" не от чего).

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

Вокне RAM, по указанной выше причине, опять не произойдет никаких изменений (кроме

PCL).

Рабочая точка программы "встала" на команду movlw .85.

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

Убедитесь, что из регистра W, в регистр Sec, скопировалось число .85 (55h).

Итак, рабочая точка программы установилась на первой команде (clrwdt) ПП задержки

PAUSE_1.

Ранее, мы уже отслеживали выполнение этой команды, так что сделайте это самостоятельно.

Рабочая точка "встала" на команду decfsz Sec,F.

На момент ее исполнения, в регистре Sec (адрес 0Ch) находится число .85 (55h). Посмотрите в окно RAM и убедитесь в этом.

Выполняем команду decfsz Sec,F. Смотрим в окно RAM.

Изменение имеется: содержимое регистра Sec, в полном соответствии с алгоритмом выполненной команды, уменьшилось с 55h до 54h, то есть, на единицу (произошел декремент).

Так как число 54h (результат операции, сохраненный в том же регистре Sec) отлично от нуля, то следующей исполняемой командой должна быть команда goto PAUSE_1.

Проверяем. И в самом деле, рабочая точка программы "стоИт" именно на этой команде. Выполняем команду goto PAUSE_1.

Вокне RAM никаких изменений (кроме PCL) не происходит (аналогично выполнению команды goto START).

Смотрим в текстовый редактор. Произошел безусловный переход рабочей точки программы на первую команду ПП PAUSE_1 (clrwdt).

Снова выполняем команду clrwdt. Снова выполняем команду decfsz Sec,F.

Смотрим в окно RAM. Содержимое регистра Sec еще раз уменьшилось на 1 (с 54h до 53h). Число 53h не равно 0, значит далее, снова будет осуществлен безусловный переход в ПП PAUSE_1 и так далее.

До тех пор, пока регистр Sec не очистится (00h).

Таким образом, рабочая точка программы "закольцевалась" в ПП PAUSE_1.

Если пытаться "добраться" до конца этой "закольцовки" (00h по адресу 0Ch) пошагово, то это займет достаточно много времени (особенно, если счетчик - многобайтный).

Есть 2 способа уменьшения этого времени: либо назначить точкой остановки команду bsf PortB,2 и "дойти" до нее в "автомате", либо поступить следующим образом: нажать на кнопку F7 и не отпускать ее, одновременно контролируя содержимое регистра Sec в окне

RAM.

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

При приближении к нулю (например, где-то в районе чисел 01h - 04h), нужно остановить счет, отжав кнопку F7, и "добраться" до состояния 00h, пошагово исполняя программу (с помощью всё той же кнопки F7).

128

Всоответствии с алгоритмом работы команды decfsz, после исполнения команды последнего декремента (переход от 01h к 00h), рабочая точка программы перейдет на команду

bsf PortB,2

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

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

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

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

Итак, рабочая точка программы находится на команде bsf PortB,2.

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

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

После формирования интервала времени положительного полупериода, рабочая точка программы установится на команде decfsz SecL,F.

Посмотрите в окно RAM.

На момент исполнения этой команды, регистр Sec очищен (в нем "лежит" 00h), а в регистры SecH (адрес 0Dh) и SecL (адрес 0Eh) ранее записаны константы .15 (0Fh) и .255 (FFh) соответственно.

Выполняем команду decfsz SecL,F. Смотрим в окно RAM.

Содержимое регистра младшего разряда SecL уменьшилось с FFh (.255) до FEh (.254), то есть на 1, что соответствует алгоритму работы команды decfsz (что при условии сохранения результата операции в этом же регистре).

Результат выполнения операции (FEh) не равен нулю, следовательно, следующей исполняемой командой будет команда goto CYCLE.

Выполняем команду goto CYCLE.

После этого, рабочая точка программы "встаёт" на первую команду ПП CYCLE (btfsc PortB,0), что соответствует задуманному.

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

Вплоть до обнуления двухбайтного счетчика (то есть, до окончания трехсекундного интервала времени).

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

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

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

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

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

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

Для этого необходимо назначить точку остановки на следующей, после decfsz SecH,F, команде, то есть, на команде goto CYCLE.

Итак, назначаем точкой остановки команду goto CYCLE. Сбрасываем программу на начало.

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

Щелкаем по кнопке с зеленым светофором ("автомат") и дожидаемся конца процесса счета

129

(придется подождать достаточно продолжительное время).

Через 175,71 мс. счет закончится и рабочая точка программы установится на команде goto CYCLE, следовательно, команда decfsz SecH,F "штатно" исполнена.

Смотрим в окно RAM.

Содержимое регистра SecL (младший разряд счетчика, адрес 0Eh) очистилось (00h), а содержимое регистра SecH (старший разряд счетчика, адрес 0Dh) уменьшилось на 1, с 0Fh (.15) до 0Eh (.14), в чем и требовалось убедиться.

После этого, можно еще раз "запустить автомат": содержимое старшего разряда счетчика еще раз уменьшится на 1 0Eh до 0Dh), а потом еще и еще..., пока счетчик старшего разряда не очистится.

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

Вопрос: "Каким образом "выйти" на сценарий "программа исполняется далее", не тратя массу времени на очистку содержимого регистра старшего разряда SecH"?

Ответ: нужно сделать то, что мы уже делали ранее заменить следующую, после decfsz SecH,F, команду (goto CYCLE), на команду nop.

Делаем это.

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

Но удалять старую точку остановки не нужно, так как она уже удалена при ассемблировании

(при ассемблировании, все точки остановки удаляются), значит нужно только назначить новую точку остановки на команде bcf PortB,2.

Делаем это.

Запускаем "автомат" и дожидаемся его отработки.

После этого, рабочая точка программы установится на команде bcf PortB,2.

Таким образом, мы "коварно проскочили" 2-хразрядный счетчик и перешли в сценарий "программа исполняется далее", что и требовалось.

Если после этого, Вы посмотрите на показания секундомера и в окно RAM, то увидите ту же самую "картину", что и в случае одного декремента содержимого SecH : 175,71 мс. и число 0Eh по адресу 0Dh.

То есть, в случае использования "уловки", SecH не очищается, и это естественно, так как при помощи одного декремента, SecH очистить нельзя.

Хотя и программа и не исполнена в полном объеме (00h в SecH нет), но тем не менее, мы можем, как говориться, с чистой совестью двигаться дальше, так как убедились, что счетчик работает по задуманному алгоритму, и получили гарантию "нормальной" его работы после замены "подставы" (NOPа) на "штатную" команду goto CYCLE.

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

Вэтом случае, goto CYCLE на nop менять не нужно.

Итак, мы находимся на команде bcf PortB,2. Выполняем ее.

Смотрим в окно RAM.

2-й бит регистра PortB изменил свое состояние с 1 на 0 (содержимое PortB изменилось с 04h

на 00h).

С учетом того, что перед исполнением команды bcf PortB,2, на выводе RB2 присутствует единичный уровень, это соответствует задуманному.

Рабочая точка программы перешла на первую команду ("врезку") ПП PRD (clrwdt). Выполняем команду clrwdt.

Рабочая точка программы установилась на команде ветвления btfss PortB,0 Следовательно, необходимо определиться, по какому из двух сценариев ее направить. Предположим, необходимо отследить исполнение сценария "программа исполняется далее". Смотрим в окно RAM (или в окно SFR).

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

goto PRD, после чего рабочая точка программы "закольцуется" в ПП PRD, а это нас не устраивает (это не сценарий "программа исполняется далее").

130

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]