Главная страница

Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.


Скачать 3.49 Mb.
НазваниеСистема команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
АнкорСамоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
Дата30.01.2017
Размер3.49 Mb.
Формат файлаpdf
Имя файлаСамоучитель по программированию PIC контроллеров для начинающих .pdf
ТипПрограмма
#1195
КатегорияПромышленность. Энергетика
страница18 из 57
1   ...   14   15   16   17   18   19   20   21   ...   57
START
, либо "закольцовывается " в
ПП
PRD
(в обеих случаях "уход в
вечное кольцо ", с
выходом из него по внешнему воздействию, либо она "движется далее " по тексту программы (сценарий типа "программа исполняется далее "). Первый случай был описан выше
Это самая простая "
закольцовка ". Во втором случае, при условии, что режим тонального вызова выключена передача включена, рабочая точка программы "уходит в
вечное кольцо "
ПП
PRD
После выключения с
передачи
, рабочая точка программы должна "прыгнуть " в
ПП
START
, в
которой должна "уйти в
еще одно вечное кольцо ", выход из которого происходит в
момент переключения с
приема на передачу
В
третьем случае, рабочая точка программы должна продолжить свое "движение " вниз по тексту программы
Смотрим в
блок
- схему программы
Теперь необходимо сформировать один период сигнала тонального вызова, соответствующий частоте 1450
Гц
То есть, сначала нужно сформировать первую половину периода (полупериода затем, вторую (форма сигнала – "меандр ").
В
конечном итоге, задача сводится к
изменениям уровней сигнала на выводе
RB2
и фиксации (задержке) этих уровней на время полупериода
Вывод
RB2
работает "на выход " (см подготовительные операции, а
это означает то, что к
этому выводу подключен выход защелки, которая управляется вторым битом регистра
PortB
Таким образом, устанавливая бит регистра
PortB
в
0 или 1 и
задерживая момент следующей смены состояний этого бита, можно сформировать нужный период
Зависимость простая если бит регистра
PortB
установить в 0, тона выходе соответствующей защелки, а
следовательно и
на выводе
RB2,
установится
0, а
если
1, то установится 1. Напоминаю, что защелка это триггер, и
если он установлен управляющим импульсом
(
командой
, которая его формирует) в
какое
- то одно из двух своих состояний, то он будет находиться в
этом состоянии вплоть до поступления следующего управляющего импульса
(
формируется другой командой. Таким образом, единожды сформировав, на выходе защелки, например, нулевой уровень, в
дальнейшем
(в интервале времени его фиксации, подтверждать, в
каждом машинном цикле, этот уровень, ненужно Вплоть до смены нулевого уровня на единичный
Из этого следует то, что после установки, на выводе, например, того же нулевого уровня, рабочая точка программы может "скакать " по каким- то другим командам, производя при этом действия, несвязанные с
управлением защелками порта
В
Следовательно
, после смены уровней на выводе, можно, на определенное время, закольцевать " рабочую точку программы в
подпрограммах задержки, и
за счет этого, сформировать интервалы времени полупериодов
А
значит и
период
Этим сейчас и
займемся
Сначала нужно определиться, с
какого уровня начинать формирование полупериода с
нулевого или с
единичного
?
В
данном случае, ничего синхронизировать ненужно Значит, формирование периода можно начать с
любого уровня
Начнем
, например, с
нулевого
Для того чтобы начать формирование нулевого уровня на выводе, необходимо установить в
ноль бит регистра
PortB
Делаем это при помощи бит- ориентированной команды (
bcf PortB,2
).
Далее
Вы видите три
NOP
а
При составлении программы с "чистого листа ", изначально, их нет
Это "элементы " точной установки (подгонки ") интервала времени отрицательного полупериода под заданное значение
Они "врезаются " в
текст программы после "прогонки " подпрограммы задержки через секундомера (об этом, позднее. Теперь нужно "закольцевать " рабочую точку программы в
подпрограмме задержки, которая

97 ранее названа
PAUSE_1
Ее "конструкция " должна быть
Вам понятна
Эта подпрограмма задержки построена "по образу и
подобию ", рассмотренной ранее, подпрограммы задержки программы
Multi.asm
Следовательно
, необходимо, в
качестве счетчика, назначить регистр (регистры) общего назначения
Количество этих регистров зависит от величины времени задержки
Чем большее время задержки нужно обеспечить, тем большее количество регистров требуется
Расчет их количества и "грубое " определение величины константы
/
констант
: Период сигнала с
частотой
1450 Гц. = 689,6 мкс, а
полупериод
344,8
мкс
Так как в
данном случае, время отработки одного машинного цикла равно 1 мкс, то округляем величину интервала времени полупериода до 345
мкс
Именно такую величину задержки и
нужно сформировать
Полный цикл рассматриваемой подпрограммы задержки составляет 3 м
ц
. (3 мкс, плюс м
ц
. (2 мкс) на последнем "витке ". Если применить конструкцию
ПП
задержки программы, то одним регистром можно обеспечить задержку дох мкс
Полупериод равен 345 мкс, следовательно, достаточно одного регистра общего назначения
Если речь идет о
задержках
, то уместно вспомнить о
том
, что не мешало бы сбросить
WDT
(
вспомните
, походу выполнения программы, его нужно периодически сбрасывать.
Команду
clrwdt
можно поставить следующей, после команды PortB,2

c сохранением- хмикросекундного
, полного цикла
ПП
задержки
, а
можно и "врезать " команду
clrwdt
в полный цикл
ПП
задержки
, увеличив тем самым полный цикл
ПП
задержки c 3 мкс до 4 мкс
(
команда
clrwdt
выполняется за 1 м
ц
.).
В
обоих случаях,
ПП
задержки будет работать, но естественно, что при формировании ими одинакового времени задержки, величины их констант не будут равны
По большому счету, выгоднее "
врЕзать " команду
clrwdt
в цикл
ПП
задержки
, чем размещать ее после команды PortB,2
В
этом случае, сброс
WDT
будет происходить чаще (1 раз за 4 мкс, вместо 1 раза за 690 мкс.
В
тексте программы, Вы видите именно такой вариант построения
ПП
задержки
(с "врезкой "), который я
применил не столько по причине необходимости столь частого сброса (такой необходимости нет, сколько в
обучающих целях
Дело в
том
, что "врезая " в
нее другие команды (по образу и
подобию " указанной выше "врезки "), время отработки цикла
ПП
задержки можно сделать гораздо бОльшим
, чем 3 м
ц
В
этом случае, и
производится полезное действие, и
увеличивается время отработки цикла подпрограммы задержки
А
ведь вместо одной команды можно "врезать " и
несколько
С
прибавлением каждой такой команды, время отработки цикла
ПП
задержки будет увеличиваться
И
чем "массивнее врезка ", тем бОльшим будет это увеличение
Если в
интервале времени отработки
ПП
задержки
, ненужно производить никаких действий
(
нужно просто увеличить время отработки
ПП
задержки
), то "врезается "
NOP
(ы. Таким же образом, в
подпрограмму задержки, можно "врезать " группу команд, производящих действия, подпрограмму (в том числе и
циклическую
), группу подпрограмма также и
все это в
комплексе ив любой комбинации (
оценИте открывшуюся перспективу …).
В
качестве примера, можно привести любую программу частотомера
В
любой из них, за время формирования измерительного интервала времени, выполняется несколько подпрограмм иного, чем задержка, функционального предназначения
Всё
, что касается такого рода "врезок ", очень важно, и
на это обязательно нужно обратить самое пристальное внимание
Для того чтобы "закрыть " эту тему, приведу практический пример Предположим, что используется классическая конструкция
ПП
задержки
(как в
программе
Multi.asm
), обеспечивающая максимальное время задержки 767 мкс, а
нужно сформировать задержку в 1000 мкс
Можно задействовать второй регистр общего назначения, а
можно обойтись и
одним
, встроив " в
ПП
задержки всего один

98
В
этом случае, полный цикл
ПП
задержки увеличивается с 3- х
до
4- хм ц, и
при помощи такой
ПП
задержки можно сформировать задержки дох м
ц
. (1023 мкс) Задержка в 1000 мкс попадает в
этот интервал, следовательно, можно обойтись одним регистром общего назначения
Если в
ПП
задержки "врезается " группа команд, то с
целью обеспечения "правильной закольцовки ", название
ПП
задержки должно приходиться на первую команду этой группы команда после последней команды этой группы, должна следовать команда ветвления
Двигаемся дальше
Ранее было выяснено, что для того чтобы обеспечить задержку в 345 мкс, достаточно одного регистра общего назначения (даже без "врезки "). Если, при 4- х
машинных циклах полного цикла
ПП
PAUSE_1
(с "врезкой " clrwdt
), обеспечивается максимальная задержка в 1023 мкс. (что соответствует максимальному значению константы .255), то значению времени задержки 345 мкс будет соответствовать значение константы х. Округляем до 86- ти
При написании программы "с чистого листа ", значение этой константы (.86) и
нужно "прописать " в
тексте программы
В
тексте программы, Вы видите другое значение константы (.85) и
три
NOP
а
Такого рода числовая коррекция произойдет позднее, при отладке временных характеристик программы в
симуляторе
(я расскажу об этом подробно, а
пока используем результат "грубой прикидки " (.86). Теперь остается только придумать название этого регистра (назовем его) и "прописать " его в "шапке " программы (прописываем "его по адресу 0Ch, но можно назначить и
другой
). Вот вами ответ на вопрос "Откуда, в "шапке " программы, взялся регистр
Sec
и каков механизм его возникновения ". После этого, константа .86, обычным образом (за 2 приема, через регистр, записывается в "новорожденный " регистр
Sec
Эту запись нужно произвести до первой команды подпрограммы (или, в
которой используется этот регистр
Далее располагаются 3 команды
ПП
PAUSE_1
, комментарии к
которым
Вы найдете в
тексте программы и
к которым мне добавить нечего
Идем дальше
Теперь необходимо сформировать положительный полупериод
По своей конструкции,
ПП
PAUSE_2 такая же, как и
ПП
PAUSE_1
, только, перед ее началом, в
бит

2
регистра
PortB
, записывается 1, и
безусловный переход осуществляется на начало
ПП
PAUSE_2
Регистр
Sec
уже имеется в
наличии
, так что ничего "назначать и
прописывать " ненужно На момент перехода рабочей точки программы на команду PortB,2

, в
регистре
Sec
будет "лежать " ноль (конечный результат декремента содержимого регистра
Sec
в
ПП
PAUSE_1
). Поэтому, перед "
влётом " в
ПП
PAUSE_2
, в
регистр
Sec,
нужно записать "новую " константу
Она будет определять продолжительность положительного полупериода
При написании программы "с чистого листа ", в
качестве этой константы, с
расчетом на осуществление дальнейшей коррекции числового значения константы, можно использовать всё
то же число .86. Изначально,
NOP
ов также нет
Все это оставляется "на потом ". Почему, в
тексте программы, Вы видите число .83, узнаете позже
Примечание
: классическая подпрограмма задержки (такая, как в
программе
Multi.asm
), иона же, нос "врезкой " (такая, как в
программе
cus
), по своей сути, есть вычитающий счетчик импульсов, то есть, абсолютно необходимое, в
цифровой технике, устройство
Восприятию этого факта мешает то, что импульсов, которые нужно считать, как- будто бы и
нет
, а
есть команды, что на первый взгляд, не одно и
то же
Но на самом деле, импульсы есть, и
считаются именно они, так как результатом исполнения команды (например, такой как) является активный перепад (строб, аппаратно формируемый внутри микроконтроллера (его прохождение нельзя проконтролировать с
помощью приборов, который и
уменьшает
(или увеличивает, если применяется команда) на единицу содержимое регистра- счетчика (в данном случае,
Sec
). Также следует иметь ввиду, что в
части касающейся м
/
контроллеров
, счетчик реализуется не одними только аппаратными средствами (например, как в 555
ИЕ
2), но и
программными средствами (в комплексе.

99 Ив самом деле, для того чтобы создать счетчик, необходимо не только задействовать
(
назначить
), в
качестве счетчика, регистр
/
регистры общего назначения (все регистры области оперативной памяти реализованы аппаратно, но и "встроить " его
/
их в
циклическую
ПП
задержки
, в
состав которой должны входить байт- ориентированные команды ветвления
incfsz
и
/
или
decfsz
(они управляют регистром
/
регистрами
).
В
первом случае, получается суммирующий, а
во втором случае, вычитающий счетчик
Практический вывод из этого следующий
Для создания однобайтного счетчика, необходимо назначить, в качестве счетчика, регистр общего назначения, определить его начальную установку,
предварительно
(
до входа в
цикл счета) записав в
этот регистр константу, и программно организовать циклическую подпрограмму задержки, с использованием команд
incfsz
(
суммирующий счетчик
)
или
decfsz вычитающий счетчик
).
Если речь идет о
многобайтном счетчике, то все тоже самое, только во множественном числе
Примите к
сведению
: если счетчик, например, двухбайтный
(используются 2 регистра общего назначения, то он необязательно должен быть только суммирующим или только вычитающим
Он может быть еще и
комбинированным
: один его разряд может работать на суммирование, а
другой
, на вычитание (или наоборот. Такие счетчики используются редко
Пример реализации двухразрядного
, вычитающего счетчика будет рассмотрен ниже
ПП
задержки не должна отрабатываться все время
Если такое произойдет, то рабочая точка программы просто "зависнет " в
этой подпрограмме
Счетчик должен считать, от предварительно записанного в
него числа (так называемая предустановка
), до момента установки в
нем нуля (очищение "), после чего рабочая точка программы должна выйти из
ПП
задержки по сценарию "программа исполняется далее ". Даже в
случае "ухода " рабочей точки программы в "вечное кольцо " (специфическая разновидность счетчика без предустановки
. "Ловушка рабочей точки "), она все- равно рано или поздно из него выходит
По внешнему воздействию (например, после нажатия кнопки. Понятия "счетчики "задержка " - два "сиамских близнеца " и
их нельзя отделить друг от друга
И
в самом деле, счетчик, при условии, что он когда- то "остановится ", всегда обеспечивает какую- то задержку, а
задержка какого- то процесса на время, кратное машинному циклу, предполагает их подсчет, то есть, применение счетчика
Таким образом,
ПП
PAUSE_1
или
PAUSE_2
можно описать так циклическая подпрограмма задержки с "врезкой" из одной команды, на основе однобайтного
, вычитающего счетчика, с предустановкой и
выходом из полного цикла подпрограммы после его очистки
(
после окончания счета
)
Если "привязаться к
понятию "
закольцовка ", тов части касающейся стандартных
ПП
задержек
, можно сказать так
"
закольцовка
" рабочей точки программы в
ПП
задержки
, создает задержку выполнения следующей,
после
ПП
задержки
, команды.
Суть
"
закольцовки
" - многократная отработка цикла
ПП
задержки
, вплоть до очищения регистра общего назначения, выполняющего функцию счетчика
.
В
этом случае, речь идет о
калиброванном времени задержки
Пример
:
ПП
PAUSE_1
и
PAUSE_2
Если речь идет о "вечном кольце ", то такие "
закольцовки " есть в
ПП
START
и
PRD.
Если кто- то из
Вас не до конца понял правила функционирования этих "механизмов ", то вернитесь назад
В
идеале
(пусть не сейчас, а
в будущему Вас должно сложиться свое индивидуальное, образное восприятие подобного рода процессов, которое очень помогает при составлении текстов программ
Обращаю
Ваше внимание наследующее такого рода общие рассуждения следует рассматривать не как мешающее отвлечение от "разборок " с
текстом программы, а
как насущную необходимость, связанную с
капитальным осознанием смысла того, о
чем идет речь
Без этого осознания, работа конструктора напоминает езду на машине в
условиях густого тумана
Прошу отнестись к
этим общим рассуждениям
/
выводам со всей серьезностью
Если
Вы прислушаетесь к
этому доброму совету, тов дальнейшему Вас не будет проблем с
пониманием текстов следующих программ, так как при описании их работы, я
буду исходить из того, что
Вы усвоили предыдущую информацию

100
А
вот теперь, со спокойной совестью, можно перейти к
дальнейшим "разборкам " с
программой
cus
Мы остановились на том, что сформировали оба полупериода (то есть, один период) тонального сигнала вызова
Естественно
, что этого маловато
Нужно последовательно сформировать несколько тысяч таких периодов, и
причем так, чтобы обеспечить заданную скважность (меандр ". Полупериоды равны друг другу. Так как интервал времени "выдачи " сигнала тонального вызова в
эфир вовсе необязательно в
точности делать равным 3 секундам, то задачу можно сформулировать так сигнал тонального вызова должен "выдаваться " в
эфир в
течение приблизительно 3- х
секунд
Не трудно догадаться, что после окончания формирования одного периода, нужно сразу же начать формирование следующего периода, и
т д
До тех пор, пока не сформируется трехсекундный интервал времени "выдачи " сигнала тонального вызова в
эфир
Теперь переходим к
устранению всех неопределенностей
, а
иначе
ПИК
"не поймет, что он должен сделать и
будет с
Вами конфликтовать ". Предположим, что мы работаем "с чистого листа ". На данный момент составления текста программы, известно, что при переходе с
приема на передачу (на выводе
1   ...   14   15   16   17   18   19   20   21   ...   57


написать администратору сайта