Файл: Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 16.06.2025

Просмотров: 3603

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

И сразу же все "становится на свои места": если 0-й и 6-й биты регистра PortB равны 0, то рабочая точка программы должна "проскочить" первую проверку (передача вкл/выкл), не "закольцевавшись" в ПП START, но в результате следующей проверки, она обязательно "уйдет в вечное кольцо" ПП PRD, где и будет "гонять по кольцу до скончания века", что мы и наблюдали.

Напрашивается естественный вывод: необходимо каким-то образом, в 6-м бите регистра PortB, выставить единицу, и тогда все будет в порядке.

ВMPLAB это вполне можно сделать, если задействовать так называемые функции стимула (асинхронный стимул, стимул порта ввода-вывода и стимул регистра. На выбор).

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

Поступлю проще и эффективнее.

Помните, я ранее говорил о том, что при работе в симуляторе, существуют некоторые

"уловки"?

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

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

На практике, это делается так. Проблемы создает команда goto PRD.

Именно она направляет рабочую точку программы в "вечное кольцо". Заменяем эту команду на команду nop.

Так как позднее, команду goto PRD нужно будет опять "вернуть на свое место" (а nop, соответственно, убрать), то удобнее это сделать так: непосредственно перед командой goto PRD, нужно поставить точку с запятой (после этого MPLAB перестает "видеть" эту команду) и пробелами сместить всю строку вправо (в "район" комментария), освободив "место" для команды nop, после чего, в том "месте", где ранее "дислоцировалась" команда goto PRD, нужно "настучать" команду nop:

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

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

Внимание: после ассемблирования, точки остановки снимаются и их нужно переназначить (назначить по-новой).

Что получилось?

А получилось то, что после выполнения команды btfss PortB,6, рабочая точка программы, через nop , "встанет" на команду bcf PortB,2, и ее "ухода, в вечное кольцо" ПП PRD, не

112


произойдет.

А раз это так, то можно без проблем "добраться" до назначенной точки остановки. Далее, возникает вопрос: "Если команда goto исключена из текста программы, то не отразится ли это на значениях калиброванных интервалов времени полупериодов?" Ответ: в данном случае, не отразится.

Объяснение: не смотря на то, что 6-й бит регистра PortB установлен в 0, реально исполняется (имитируется) сценарий работы, для случая установки 6-го бита регистра PortB в 1. И в самом деле, рабочая точка программы переходит на команду bcf PortB,2 через nop, но только этот nop не "виртуальный" (см. объяснение работы команд ветвления, которое было дано ранее), а реальный.

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

Например, в "автомате": сбросьте программу на начало и щелкните по кнопке с зеленым светофором.

После отработки "автомата", Вы увидите, что рабочая точка программы "встала" на назначенную точку остановки (bcf PortB,2), что и требуется:

Итак, мы "вышли" на начало замера. Посмотрите на показания секундомера.

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

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

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

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

Это указывает на то, что точки остановки работают только в "автомате".

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

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

113


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

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

Такого рода "тренировка извилины" исключительно полезна.

Еще раз напоминаю: на команду, назначенную точкой остановки, можно "выйти" 2-мя способами:

Первый: в режиме пошагового исполнения программы.

При этом, точка остановки не назначается (какой смысл? Она не работает).

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

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

Второй: в "автомате".

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

Итак, мы "стоИм" на верхней точке остановки (bcf PortB,2), то есть, на той команде, после исполнения которой начинается формирование отрицательного полупериода.

Обращаю Ваше внимание на следующий общий принцип: то, что рабочая точка

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

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

Рассуждаем дальше: начальная точка замера имеется, а конечной точки замера нет. Вывод: значит, ее нужно назначить (диалектика …).

Ей должна быть команда, после исполнения которой, 0 меняется на 1 (bsf PortB,2). Правой кнопкой мыши, щелкаем по строке с этой командой и выбираем Break.

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

114


А теперь все просто: в окне секундомера, щелкаем по кнопке Zero (сбрасываем показания секундомера в ноль) и далее, по кнопке с зеленым светофором.

Дожидаемся установки рабочей точки программы на назначенную ранее точку остановки bsf PortB,2 и снимаем показания секундомера:

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

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

Но, как говорится, "легких путей нам не нужно" (в обучающих и тренировочных целях), и поэтому еще раз проделаем то же самое, но со снятием точек остановок (Debug Clear All Points).

Устанавливаем точку остановки на команде bsf PortB,2

В"автомате", переходим на эту точку остановки.

Устанавливаем точку остановки на команде bcf PortB,2 Сбрасываем секундомер на ноль (Zero).

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

115

Смотрим на показания секундомера.

Величина интервала времени формирования положительного полупериода равна 344 мкс. (замер производится в окончательно отработанном тексте программы).

Почему не 345 ?

Адля разнообразия. В обучающе-тренировочных целях (для стимуляции мыслительной деятельности).

Если требуется выставить 345 мкс., то нужно либо добавить еще один nop, например, после команды bsf PortB,2 (или перед командой movlw .83), либо вообще убрать все три NOPа и увеличить числовое значение константы с .83 до .84 (напоминаю, что один цикла ПП PAUSE_2 отрабатывается за 4 мкс.).

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

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

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

Уберите все NOPы (6 штук), которые находятся после команд bcf PortB,2 и bsf PortB,2 (можно или поставить перед ними точки с запятыми, или вообще убрать их из текста программы: первое удобнее, а последнее нагляднее).

В группах команд записи констант, замените .85 на .86 и .83 на .86 (напоминаю, что .86 это рассчитанное ранее значение).

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

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

Перед нами текст программы "с чистого листа".

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

Задача: необходимо установить интервалы времени формирования отрицательного полупериода равным 345 мкс., а положительного - 344 мкс.

Все начинается с проверки фактических величин этих интервалов времени. Это будут как бы "начальные точки отсчета".

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

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

После сброса программы на начало, "дойдите" до команды bcf PortB,2 либо в режиме пошагового исполнения программы, либо в "автомате" (описано выше, и про "уловку" не забудьте). Лучше в "автомате" (быстрее).

Итак, рабочая точка программы находится на команде bcf PortB,2 (начало формирования отрицательного полупериода).

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

Назначаем точкой остановки команду bsf PotrB,2 (начало формирования положительного полупериода).

Щелкаем по кнопке с зеленым светофором и ждем окончания процесса подсчета. Смотрим на показания секундомера. Они равны 346 мкс. "Перебор".

Значит, значение константы нужно уменьшить.

Если уменьшить ее на 1, то есть, сделать равной .85, то время формирования отрицательного полупериода уменьшится на 4 мкс. и составит 342 мкс.

"Недобор" в 3 мкс. устраняем добавлением трех NOPов, либо сразу же после команды bcf PortB,2, либо сразу же после команды goto PAUSE_1.

Можно также "врезать" эти NOPы после команды movwf Sec или между командами movlw .85 и movwf Sec.

Атеперь "вспомните" (склероз выключен) отстроенный текст программы.

116


Вот Вам и ответ на вопрос: откуда что взялось?

Вданном случае, я "врезал" NOPы после команды bcf PortB,2 (на мой взгляд, так симпатичнее).

Получилось то, что нужно: 345 мкс. (ранее проверено по секундомеру). Измеряем время положительного полупериода.

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

Примечание: если Вы "добирались" до команды bcf PortB,2 в режиме пошагового исполнения программы (вспомните, что в этом случае, точку остановки устанавливать не обязательно), то сделайте ее точкой остановки.

Если Вы "добирались" до команды bcf PortB,2 в "автомате", то она уже является точкой остановки (а иначе, в "автомате", Вы бы до нее не "добрались") и делать ничего не нужно. Сбрасываем секундомер на ноль.

Щелкаем по кнопке с зеленым светофором и ждем окончания подсчета. Получаем 353 мкс.

А нужно 344 мкс. "Перебор" в 9 мкс.

Если уменьшить величину константы на 2 (минус 4х2=8 мкс.), то опять будет "перебор". Следовательно, необходимо уменьшить величину константы на 3, а "недобор" скомпенсировать добавлением трех NOPов, что Вы и видите в тексте отлаженной программы.

Из этого следует общий принцип: если существует "перебор" и нет возможности

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

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

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

Теперь нужно убрать "обманный" nop и "вернуть на свое бывшее место" команду goto PRD. Остается только проассемблировать текст программы (так как были внесены изменения), и после этого, как говорится, "со спокойной совестью", можно открыть, созданный при этом ассемблировании, HEX-файл программы, в программе, обслуживающей Ваш программатор, и произвести "прошивку" ПИКа.

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

А если ПП задержки имеет в своем составе "мощную врезку", и даже "грубый" расчет времени отработки такой задержки вызывает существенные затруднения?

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

Что нужно делать в этом случае?

Встаршем и среднем разрядах счетчика выставляем значения констант, из расчета формирования малого интервала времени.

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

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

Для младшего разряда счетчика (он "шустёр), выставляем константу "от балды", но не максимальную.

Например, .10 ("привязка к круглой цифре". Для удобства).

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

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

Вмладшем разряде счетчика, увеличиваем значение константы с .10 до .11 .

Делаем те же "манипуляции". Получилось, например, 1353 мкс. Вычисляем разницу: 1373-1250=123 мкс.

117