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

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


Скачать 3.49 Mb.
НазваниеСистема команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
АнкорСамоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
Дата30.01.2017
Размер3.49 Mb.
Формат файлаpdf
Имя файлаСамоучитель по программированию PIC контроллеров для начинающих .pdf
ТипПрограмма
#1195
КатегорияПромышленность. Энергетика
страница53 из 57
1   ...   49   50   51   52   53   54   55   56   57
0,1 сек (отсюда и
погрешность в 10 гц
.).
С
учетом сказанного выше, для такой высокой частоты, вариант счета с
использованием "чистого " не подходит
Значит
, необходимо замедлить счет
TMR0
То есть, нужно сделать так, чтобы счетный вход "реагировал " не на каждый импульс, поступающий на вывода например, на каждый 10- й, 20- й, 34- й, ... и
т д. (цифры "взяты с
потолка "). Соответственно, враз увеличится и
время одного цикла переполнения, что и
требуется
(проверки на переполнение не будут очень частыми. Для этого, между выводом (счетным входом
ПИКа
) и
счетным входом

264 необходимо включить делитель на 10, 20, 34, ... . Такой делитель в
ПИКе имеется
Он называется предделителем
Посмотрите в
распечатку регистра
OPTION
Для того чтобы обеспечить требуемый режим работы устройства, до "
влёта " в
цикл счета, нужно установить битв (выбор внешнего такта с
вывода
RA4/TOCKI
), бит, обычно, устанавливают в 0 (приращение по переднему фронту, бит устанавливается в 0 (
предделитель включен переда с
битами
№№
0 ... 2 (коэффициент деления предделителя
) давайте разбираться
Какой коэффициент деления предделителя установить Выбираем максимально возможный
Кделения предделителя
(256). Это соответствует заданию наивысшего, частотного "потолка ". Можно "привязаться " и
к полубайту (128) и
к четверти байта (64), но при этом наживаются никому ненужные проблемы, связанные с
необходимостью работы либо с
полубайтами
, либо с
четвертями байта, со всеми вытекающими, не очень- то "комфортными ", последствиями
Итак
, в
битах
№№
0 ... 2 выставляем единицы (
К
деления предделителя
=
256).
В
этом случае, переполнение будет происходить не после подсчета "пачки ", состоящей из 256- ти импульсов, а
после подсчета "пачки ", состоящей из х- ти импульсов
Таким образом, за время "прохождения " 3 000 000 импульсов, произойдет 45 переполнений по принципу "недопущения перебора ", округлено в
сторону уменьшения. х. Остаток 3000000-2949120=50880. Обратите внимание на то, что число .45 не выходит за "верхнюю границу " числового диапазона байта (не более .255), и
оно "уместится " водном байте
Таким образом, речь идет о
том
, что в
случае организации высокоскоростного счета, можно работать (программно) с
частотами более высокими, чем 30
Мгц
30
Мгц это "официальный, паспортный потолок " Если будет использован более быстродействующий
ПИК
, то программа может обеспечить его работу на частотах более высоких, чем 30
Мгц
Вернемся к
математике
Имеется остаток равный 50880. На 65536 его делить нельзя, так как получится число меньше единицы, значит делим на 256.
С
учетом соблюдения все того же принципа "недопущения перебора ", получится следующее х. Остаток 50880-50688=.192. Еще раз обратите внимание на то, что и
число
.198, и
число
.192 не выходят за пределы числового диапазона байта, и
каждое из них можно отобразить водном байте
Итожим
:
3 000 000=256
х
256
х
45+256
х
198+192
Вы видите математическую форму разложения десятичного числа 3 000 000. Для того чтобы убедиться в
том
, что между этой формой представления числа
(
используемые числа - десятичные) и
двоичной
(бинарной) формой представления этого же числа, имеется однозначное соответствие, в
программке конвертора систем исчислений
, имеющейся у
Вас
, "настучите " число 3000000. Вы увидите, что десятичное число 3000000, в
бинарном виде, выглядит так 11000110 11000000

А
теперь по частям
- старший байт 256
х
256
х
45=
2949120
(
00101101
00000000 00000000
), (
00101101=.
45),
- средний байт х (
00000000
11000110
00000000
), (
11000110=
.198),
- младший байт
192
(
00000000 00000000
11000000
), (
11000000=
.192). Остается только "закрепить "
- за старшим байтом (число .45) регистр,
- за средним байтом (число .198) регистр,
- за младшим байтом (число .192) регистр
TimerL
Каждое из этих трех чисел отображается водном байте- байтное
, двоичное число, записанное в
регистре
TimerH/TimerM/TimerL
, будет

265 соответствовать 7- разрядному, десятичному числу 3 000 000.
Переполнение
TMR0
будет происходить 3000000/65536=45,776367 разв сек (или раз засек, что соответствует числовому значению интервала времени между двумя соседними переполнениями, 2184,5 мкс
В
этом интервале времени можно исполнить сотни команд
И
это с
учетом того, что речь идет об измерении достаточно высокой частоты (30
Мгц
.). Этот интервал времени "прекрасно вписывается " в
малое кольцо динамической индикации
(
процессы счета и
динамической индикации совмещены.
В
данном случае, время отработки одного цикла малого кольца динамической индикации не должно превышать х мкс, так как в
противном случае, возникнет погрешность подсчета (2 переполнения
TMR0
будут считаться заодно. Вывод в
данном случае, проверки на переполнение
TMR0
нужно производить чаще, чем 1 раз за 4369 мкс. Еще один вывод
:
для того чтобы отодвинуть верхнюю, программную границу (она определяет быстродействие программы, а
не
ПИКа
) полосы частот, в
пределах которой производится счет, вверх по оси частот, необходимо уменьшить время полного цикла малого кольца динамической индикации
В
этом случае, нужно не забывать о
том
, что это влияет и
на время отработки цикла динамической индикации, и
на величину интервала времени измерения
После подобного рода "катаклизма " (если он имеет место быть, нужно производить коррекцию временных характеристик программы
Итак
, команды 1- й
проверки
TMR0
на переполнение "врезаются " в
малое кольцо динамической индикации, а
результат этих подсчетов "оседает " в
регистре
TimerH
Вопрос
:
"Каким образом происходит подсчет "?
Ответ
:
каждый раз, при наличии факта переполнения (
флаг
T0IF
поднят
), содержимое регистра инкрементируется
Количество таких инкрементов напрямую зависит от частоты импульсной последовательности, подаваемой на вывод (на вход предделителя
).
В
зависимости от нее (от частоты, переполнения
TMR0
будут происходить не на каждом "витке " малого кольца динамической индикации (такое возможно только при приближении к
верхней границе быстродействия программы, а
например
, 1 раз за 5, 65, 231, 564 и
т д "витка " (цифры "взяты с
потолка "). Если речь идет о 1- й
проверке
TMR0
на переполнение, то должна быть и
вторая
? Так оно и
есть
Дело в
том
, что между группой команд 1- й
проверки
TMR0
на переполнение и
командой окончания счета, располагается группа команд точной "доводки " интервала времени измерения и
группа команд завершения измерения
В
интервале времени их отработки, может произойти переполнение, которое не будет подсчитано
Следовательно
, сразу же после окончания счета, необходимо произвести еще одну проверку на переполнение (
№ 2). Если, за указанный выше промежуток времени, произошло переполнение из- за малой его величины, количество переполнений не может быть больше одного, то содержимое регистра
TimerH
инкрементируется
, а
если не произошло, то содержимое регистра
TimerH
не меняется
Итак
, с
регистром старшего разряда, в
основном
, разобрались
Для удобства, будем считать, что старший байт числа 00000000

(2949120) записан в
регистр
TimerH,
и он "лежит в
оперативных закромах " (ждет своего часа "). Итог по регистру
TimerH
В
ходе исполнения процедур последовательных проверок переполнения проверка 1), числовое значение байта регистра
TimerH
будет увеличиваться
Интенсивность этого увеличения зависит от значения измеряемой частоты
После разрешения счета, на каждом "витке " малого кольца динамической индикации, происходит проверка переполнения 1, за счет которой и
осуществляется основной "прирост " числового значения байта регистра
TimerH
После того как счет запрещается, осуществляется 2- я
проверка переполнения, которая может либо привести, либо не привести к
единственному инкременту содержимого регистра

266 После проверки переполнения 2, в
регистре
TimerH,
будет окончательно сформировано числовое значение старшего байта 3- байтного двоичного числа результата подсчета (измерения. Ранее, для определенности, мы условились, что это число 1101

(.45). Теперь обратим внимание на регистр среднего разряда
TimerM
Итак
, счет закончен, ив регистр
TimerH
записано количество переполнений, произошедших в
интервале времени измерения
Вопрос
:
что нужно записать в
регистр среднего разряда
Ответ
:
в него нужно записать содержимое
TMR0
на момент окончания счета
Эта операция простая содержимое, через регистр, просто копируется в
регистр
TimerM
Таким образом, в
рассматриваемом случаев средний байт 3- байтного двоичного числа) запишется число 0110
(
.
198). В "связке " с
регистром
TimerH
, получилось это
01101101 1100 0110
00000000 Переходим к
регистру младшего разряда Вопрос "на засыпку ": если количество переполнений
TMR0
записалось в
регистр
TimerH
, а
содержимое
TMR0 на момент окончания счета) скопировалось в
регистр
TimerM
, то что же тогда записывать в
регистр
TimerL
?
Ответ
:
если не найти то "место ", в
котором "лежит хвостик " разложения значения подсчитываемого количества импульсов (в нашем случае, число .192), то записывать в
регистр
TimerL
нечего
И
в самом деле,
TMR0
"выжат как мочалка " и "выжимать " из него нечего, но из предделителя кое- что "выжать " можно
Именно в
байте предделителя и "лежит этот хвостик ".
А
вот здесь- то и
начинается самое интересное
Речь идет о
такой "головоломке ", как подпрограмма досчета
Из ее названия понятно, что организуется дополнительная процедура досчета
Именно результат работы этой
ПП
и будет записываться в
регистр
TimerL
Давайте разберемся что это такое
Сначала в
принципе
, а
затем и
более детально
Принцип работы подпрограммы досчета
Досчет это счет с
предустановкой
, в
пределах одного цикла счета
Перед исполнением
ПП
досчета
, содержимое регистра
TimerL
необходимо сбросить в
ноль
(
подготовка к
досчету
). Так как то, что нужно подсчитать, фиксировано, то необходимо организовать "принудительный " счет
Для этого нужно сформировать серию коротких, счетных импульсов
Импульс формируется путем кратковременной установки единичного уровня на выводе блокировки, который электрически соединен с
выводом счетного входа
RA4/TOCKI
То есть, счетный импульс формируется программными средствами
В
нашем случае (
приращение
TMR0
по переднему фронту, в
момент начала формирования счетного импульса, формируется активный перепад (переход от 0 к 1), поступающий на счетный вход
ПИКа
(то есть, на вход предделителя
), который и
будет подсчитан
Возникает вопрос "Ане будут ли, вовремя формирования единичных уровней счетных импульсов, паразитно подсчитываться импульсы от внешнего источника импульсов, ведь это плохо отразится на итоговом результате подсчета "?
Ответ
:
импульсы
, от внешнего источника импульсов, подсчитываться не будут, так как в
интервале времени исполнения
ПП
досчета
, блокировочный вывод
RA3
настроен на работу "на выход ", что соответствует подключению, к
счетному входу
ПИКа
, низкоомного выхода третьей защелки порта
А
В
этом случае, на счетном входе
ПИКа
, амплитуда импульсов, поступающих (через гасящий резистор) от внешнего источника импульсов, за счет шунтирования счетного входа
ПИКа низким выходным сопротивлением третьей защелки порта
А
, будет резко снижена, и
она
(
амплитуда
) окажется существенно ниже порога "срабатывания " счетного входа
ПИКа

267 По этой причине, счетный вход
ПИКа перестанет "реагировать" на импульсы от внешнего источника, но будет "реагировать" на счетные импульсы.

Примечание
:
в процессе основного счета, который происходил до "
влёта " в
процедуру досчета
, такое шунтирующее влияние отсутствует, так как в
интервале времени основного счета, вывод
RA3
настроен на работу "на вход " (выход защелки отключен от вывода. После формирования счетного импульса, может наступить 2 события
- содержимое
TMR0
не инкрементировалось
,
- содержимое
TMR0
инкрементировалось
Пока
, просто примите это к
сведению
До сих поря не обращал
Вашего внимания на байт, "дислоцирующийся " в
предделителе
Пришла пора с
ним разобраться
Байт предделителя
, по отношению к
байту
TMR0
, является младшими этим все сказано
И
в самом деле, где, как не в
байте предделителя
, находиться "хвостику " результата измерения Другого не дано
То есть, для получения десятичного "эквивалента" 3-
байтного двоичного числа, точно равного истинному результату измерения (
подсчета
),
содержимое байта предделителя нужно записать в
регистр
TimerL
Это и
есть та задача, которую нужно решить
Таким образом, в
байте предделителя "лежит " число .192 (условились ранее, и
нужно каким- то образом "переправить " это число, из байта предделителя
, в
байт регистра
TimerL
Задача
, казалось бы, простая, но это не так
Так как предделитель не является регистром, отображаемым в
области оперативной памяти, то при помощи стандартной процедуры записи (через регистр, "переправить " его содержимое, в
регистр
TimerL
, нельзя
Самое разумное, что можно сделать, так это инкрементировать содержимое байта предделителя до тех пор, пока число .255 сменится на число .00.
В
этом случае, произойдет инкремент содержимого регистра, что и
будет являться критерием конца досчета
Факт инкремента содержимого регистра
TMR0
укажет на то, что байт предделителя инкрементирован количество раз, равное разнице между числом 256 и
числом
, находящимся в
байте предделителя на момент окончания счета (то есть, числом, которое нужно "переправить " в
регистр
TimerL
).
Примечание
:
приращение содержимого
TMR0
не будет влиять на результат основного счета, так как оно происходит после того, как этот результат сохранен в
регистрах
TimerH
и
TimerM
Подсчитав количество инкрементов байта предделителя
(от первого инкремента и
до обнаружения факта приращения содержимого регистра) и
осуществив числовое преобразование, можно точно восстановить числовое значение байта предделителя на момент окончания основного счета (хвостик ").
Обращаю
Ваше внимание на то, что в
данном случае, речь идет о
досчете
, а
не о
счете
Счет производится в
интервале времени измерения (основной счет, на момент окончания которого, в
байте предделителя фиксируется некое число
Досчет производится вне интервала времени измерения и "принудительно " (программная "симуляция " счета. Если добавить результат досчета к
результату основного счета, то программная погрешность результата измерения не будет превышать 10- ти герц "Привяжемся " к
рассматриваемому случаю (подсчет 3 000 000 импульсов засек. Итак, в
байте предделителя "лежит " число .192.
Задача
:
нужно "переправить " число .192, из байта предделителя
, в
регистр
TimerL
Математически это выглядит так
1.
256-
192
=.64 (значение результата досчета
). Переводим десятичное число .64 в
бинарную форму Инвертируем все биты числа
01000000
Получаем
:
10111111
, что соответствует числу .191.
4.
инкремент Итог число .192 "переправлено ", из байта предделителя
, в
регистра
TimerL
Для того чтобы
Вы убедились, что ив других случаях, происходит тоже самое, приведу еще один пример
Например
, считается 1 500 000 импульсов засек Делаем разложение 256
х
256
х
22+256
х
227+
96

268
1.
256-
96
=.160 (значение результата досчета
). Переводим десятичное число .160 в
бинарную форму Инвертируем все биты числа
10100000
Получаем
:
01011111
, что соответствует числу .95.
4.
инкремент. Пока хватит (артподготовка ").
С
деталями разберемся позднее
Краткий
, общий итог
Наибольший практический интерес представляет принцип организации высокоскоростного счета. При этом, перед, включается предделитель
, на вход которого
(
предделителя
)
, с выхода внешнего источника импульсов, подается последовательность импульсов, количество которых нужно посчитать в
интервале времени счета. Организуется 3-

байтный
(
в рассматриваемом случае
)
регистр
1   ...   49   50   51   52   53   54   55   56   57


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