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

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


Скачать 3.49 Mb.
НазваниеСистема команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
АнкорСамоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008).pdf
Дата30.01.2017
Размер3.49 Mb.
Формат файлаpdf
Имя файлаСамоучитель по программированию PIC контроллеров для начинающих .pdf
ТипПрограмма
#1195
КатегорияПромышленность. Энергетика
страница40 из 57
1   ...   36   37   38   39   40   41   42   43   ...   57
TimerM.
btfsc Status,C
;
Флаг
С
поднят
?
incf TimerH,F
; Если да, то инкремент содержимого регистра ; TimerH с сохранением результата в
нем же.

movf RegH,W
; Если нетто скопировать содержимое ; регистра RegH в регистр W.
addwf TimerH,F
; Сложить содержимое регистров W и TimerH с ; сохранением результата в
регистре
TimerH.
goto YES
; Безусловный переход в
ПП
YES.
;-------------------------------------------------------------------------------- Проект под них создавать ненужно Просто откройте их в (
File
Open
). Вы видите перед собой подпрограмму, которая реализует трехбайтное
, суммирующее устройство
В
данном случае, осуществляется суммирование 3- хбайтного результата измерения частоты и 3- хбайтной поправки (константы, которая представляет собой значение установленной пользователем (или по умолчанию) промежуточной частоты (пример взят из программы частотомера- цифровой шкалы. Вспомните первый случай вычисляемого перехода, который был рассмотрен ранее
Одной из команд этого вычисляемого перехода является команда Таким образом, при наличии определенного состояния клавиатуры, происходит безусловный переход в
ПП
PLUS
, в
которой и
осуществляется указанное выше суммирование
Теперь нужно кое- что пояснить
Микроконтроллер работает только с
двоичными числами
То
, что в
тексте программы, форма представления чисел может быть иной, это всего- лишь "элемент " удобства (спасибо разработчикам.
В
конечном итоге, все сведётся к
той или иной разновидности двоичных чисел, с
которыми и
будет происходить работа
Пример
Предположим
, что возникла необходимость в
отображении символов десятичной системы исчисления
Например
, в
линейке индикаторов или в
жидкокристаллическом модуле
Для того чтобы "провернуть это дельце ", сначала нужно произвести соответствующие операции с
классическими
, двоичными числами, вплоть дополучения двоичного числа результата
После этого, нужно перевести классическое, двоичное число результата, в
двоично
- десятичную форму (разновидность двоичной формы чисел. После этого, нужно осуществить перекодировку двоично- десятичных чисел под те индикаторы, которые применяются (еще одна разновидность двоичной формы чисел. После этого, результат такого перекодирования можно вывести на индикацию
В
любом из этих случаев, происходит работа с
двоичными числами
Вернее
, с
теми или иными их разновидностями
Как осуществляется перекодирование, было рассмотрено ранее (второй пример вычисляемого перехода, а
как осуществляется перевод двоичных чисел в
двоично
- десятичные, будет рассмотрено позднее
Сейчас же, я
покажу
, как формируется трехбайтное двоичное число, предназначенное для дальнейшего отображения в
линейке из 7- ми 7- сегментных индикаторов частотомера - цифровой шкалы (работа в
подрежиме суммирования результата измерения и
значения промежуточной частоты.
Подпрограмма
PLUS_1
находится внутри подпрограммы
PLUS
Следовательно
, если речь идет о
ПП
PLUS
, то имеются ввиду все команды подпрограммы, включая и
команды
, входящие в
состав
ПП
PLUS_1
Вспомните то, о
чем говорилось в
разделе
, посвященному работе с
EEPROM
памятью данных
В
ее ячейки, предварительно, можно записывать какие- нибудь числа, которые затем используются в
работе программы
В
рассматриваемом случаев ячейки
EEPROM
памяти данных, с
учетом порядка старшинства, записывается, предварительно вычисленное программистом, трехбайтное
, двоичное число, которое задает значение промежуточной частоты
После включения питания, числа из этих ячеек, с
соблюдением порядка старшинства, копируются в
регистры
RegH, RegM, RegL
(см текст программы.
В
регистрах
TimerH, TimerM, TimerL
, на момент начала исполнения
ПП
PLUS
, находится трехбайтное
, двоичное число результата измерения частоты
В
ПП
PLUS
, c уммирование происходит побайтно
, начиная с
младших байтов слагаемых
То есть, сначала производится суммирование содержимого регистров и TimerL
, затем и TimerM
, а
затем
RegH и После выполнения команд сложения, производится опрос состояния флага
С
, по результатам которого делается вывод о
наличии или отсутствии необходимости переноса в
более старший разряд (инкремента содержимого, следующего по разрядности, регистра. Критерий прост превышение или нет, числовым значением суммы, "границы " числового

205 диапазона байта (числа .255). Если это превышение есть, то флаг
С
поднимается
, и
по факту этого, далее, осуществляется инкремент (+1) содержимого следующего, по старшинству, регистра "
С
другого бока ": если такой инкремент происходит, то это означает то, что осуществлен перенос в
следующий
, по старшинству, разряд трехбайтного регистра
TimerH/TimerM/TimerL
При наличии этого переноса, значение байта следующего, по старшинству, регистра, сначала увеличивается на 1, а
затем
, получившийся результат, суммируется с
содержимым регистра. Если после суммирования, переноса нет (Сто инкремента содержимого следующего, по старшинству, регистра не происходит (команда инкремента обходится. После исполнения команд сложения, их результаты сохраняются все в
тех же регистрах (c "привязкой " к
соответствующим разрядам, M, H
).
Обращаю
Ваше внимание на то, что инкремента содержимого младшего байта (переноса в
младший байт, находящегося в
регистре
TimerL
, никогда не происходит
По той причине, что он младший и
переносить в
него нечего
Таким образом, в
данном случае, перенос может происходить только из младшего разряда, в
средний разряди из среднего разряда
M,
в старший разряд
H
Так как перенос из самого старшего разряда осуществлять некуда, то программист должен рассчитать количество разрядов многобайтного регистра таким образом, чтобы исключить переполнение регистра самого старшего разряда
(
того
, в
котором сохраняется результат суммирования. То есть, в
части касающейся суммирования чисел самого старшего разряда, арифметический результат суммирования не должен превышать .255.
В
противном случае, произойдет "выход на второй виток счета " (неверный результат суммирования. Например, 3-
хбайтный регистр сможет безошибочно отобразить числа от
0
до
256
х
256
х
256-1=
16777215
Если нужно отобразить результат суммирования больший, чем 16777215, то нужно организовывать 4- байтный регистр (добавить регистры
RegHH
и
TimerHH
) и
соответственно
, добавить, в
подпрограмму
PLUS,
команды
, организующие суммирование содержимого регистров
RegHH
и
TimerHH
, а
также и
перенос из разряда в
разряд
HH
Снизу от директивы
end,
Вы видите "арифметические примеры суммирований ". Пример случай отсутствия переносов
В
этом случае, связи между байтами не работают (так как переносов нет, и
просто осуществляется последовательные, побайтные суммирования, в
пределах пары одноименных байтов (
L+L, M+M, H+H
) регистров
Reg
и
Timer
, начиная с
младших байтов. Результаты анализов состояний битов
C
и
Z
будут нулевыми
По этой причине, рабочая точка программы будет "обходить стороной " все команды инкрементов
Пример

случай наличия переносов в
разряды
M
и
H,
при отсутствии нулевого результата операций суммирования
Побайтное суммирование начинается с
младших байтов (
L
) регистров
Reg
и
Timer
В
результате этого суммирования, происходит "выход " на второе кольцо 8- битного
, полного цикла чисел (переполнение, и
флаг
С
поднимается
(сигнал " переноса в
следующий разряд. После опроса состояния флага
С
, рабочая точка программы уходит в
сценарий "инкремент содержимого регистра, что и
есть практическое осуществление переноса
После этого, происходит суммирование байтов средних разрядов (
M
) регистров
Reg
и
Timer
В
результате этого суммирования, также происходит "выход " на второе кольцо 8- битного
, полного цикла чисел (с учетом предшествующего инкремента содержимого регистра, и
флаг
С
снова поднимается
После этого, рабочая точка программы уходит в
сценарий "инкремент содержимого регистра, что также есть практическое осуществление переноса
После этого, происходит суммирование байтов старших разрядов (
H
) регистров
Reg
и
Timer
В
этом случае, переноса быть не должно (мотивация - см выше.
Всё
Процесс суммирования завершен

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

случай наличия переносов в
разряды
M
и
H,
при наличии нулевого результата операции суммирования байтов (слагаемые - ненулевые. Его разница с
примером
№ 2 заключается в
том
, что при суммировании чисел, "лежащих " в "средних " байтах (
M
) регистров
Reg
и
Timer
, "выход " на второе кольцо 8- битного полного цикла чисел происходит на число равное нулю
В
этом случае, поднимается флаг нулевого результата
Z,
и перенос в
старший разряд (то есть, инкремент содержимого регистра) осуществляется после опроса состояния не флага
С
, а
флага
Z
Сразу возникает вопрос "
А
какова надобность задействования, для переноса, флага нулевого результата, ведь казалось бы, можно обойтись только флагом
С
"
? Существуют такое понятие, как "наихудший вариант ", на который всегда (а не только в
этом случае) нужно ориентироваться
В
данном случае, он выглядит так в
регистре "лежит " число .255, а
из более младшего разряда, осуществлен перенос
В
этом случае, перенос (выход на самое начало 2- го "витка "). То есть, должен быть осуществлен инкремент содержимого следующего, по старшинству, байта
Давайте разбираться
Для данной программы, при суммировании разрядов (
addwf TimerL,F
), флаг
С
работает
, так как применяется команда (
addwf
), влияющая на его состояние (см распечатку команд. По этой причине, перенос в
разряд
M
(при его наличии) будет безошибочно осуществлен
А
вот при организации переноса, из разряда, в
разряд
H
, в
рассматриваемом случае, анализ состояния флага
С
просто бесполезен, так как флаг
С
не "реагирует " на команду см распечатку команд. То есть, после инкремента числа .255, флаг
С
как был опущенным, так он такими, инкремента содержимого регистра
TimerH
произведено не будет, что есть ошибка суммирования
Значит нужно "искать заменитель ". На числовой результат исполнения команды
incf
реагирует только флаг (см распечатку команд, и
состояние этого флага обязательно нужно опросить
Соответственно
, при организации переноса, из разряда
M,
в разряд, для "нейтрализации вышеобозначенной бяки ", организована группа команд анализа состояния флага
Z
Общий принцип
:
при наличии переноса, к содержимому регистра следующего, по старшинству разряда, тем или иным способом, нужно прибавить единицу. При отсутствии переноса, единица не прибавляется. Наихудший вариант " выглядит так (один из примеров
150 255 255
0 0 1
151 0 0
С
суммированием младших байтов (
L
), нет никаких проблем
.255+.01=.256=.00 плюс перенос (инкремент) в регистр разряда. После инкремента содержимого регистра разряда, флаг
Z
поднимется
, после чего содержимое регистра разряда
H
будет увеличено на единицу переноса Этот способ организации переносов, внутри многобайтного регистра, и
реализован в
предлагаемой
Вашему вниманию
ПП
PLUS
Предоставляется прекрасный повод для тренировки в
составлении блок- схемы подпрограммы, и
я советую
Вам это сделать
В
дальнейшем
, проще будет "ориентироваться ".
ПП
PLUS
является типичным образцом подпрограммы с
достаточно "развитой " системой

207 ветвлений
Кто ее "осилит ", тот существенно "продвинется вперед ".
Эту
ПП
(заготовку "), в
дальнейшем
, можно использовать при разработке программ, в
которых нужно производить суммирования чисел
С
непривычки
, алгоритм этой подпрограммы может показаться достаточно сложными, но если разобраться, то ничего особо сложного в
нем нет
Нужно просто некоторое время "
повариться в
этом соку ". Именно по этой причине, а
также по причине того, что стандартная подпрограмма вычитания сложнее стандартной подпрограммы сложения, я
пока не считаю целесообразным производить "разборки " с
подпрограммой вычитания
Перед "штурмом этой вершины ", нужно основательно разобраться с
суммированием
, причем, разобраться так, чтобы неясных вопросов не было
Это обусловлено тем, что вычитание является специфической формой суммирования и
программист
, хорошо представляющий себе процесс суммирования многобайтных двоичных чисел, при "разборках " с
вычитанием
, не встретит особых трудностей
Так что, всему свое время
Дойдет дело и
до вычитания
Теперь можно разобраться с
парой очень востребованных операций, имеющих непосредственное отношение к
флагу
С
, но сначала подведем промежуточный итог
Итак
, рабочие части текстов "неполноценных " программ, c_dc.asm, flag.asm
(и им подобных, можно "врезать " в
какую
- нибудь простенькую, "полноценную " программу и
от души "погонять все это добро " в
симуляторе
, выяснив при этом все, что нужно
Естественно
, что при этом необходимо "скорректировать шапку " программы и
создать необходимые условия для работы этих "врезок ". Лучше всего, специально под это дело, создать, например, из программы
Multi.asm,
программу
- заготовку, в "шапке " которой "оптом прописать " наиболее востребованные регистры специального назначения, определить место сохранения результатов операций и
присвоить названия наиболее востребованным битам регистров специального назначения
Например
,
C
equ 0,
DC
equ 1,
Z
equ 2,
RP0
equ 5,
GIE
equ 7 и
т д
Даже если часть из этого использоваться не будет, то ничего страшного
Это не является ошибкой
Примечание
:
если воспользоваться соответствующей директивой, которая "оптом прописывает всё
, что шевелится ", можно обойтись без этого
Эта директива комфортна
, нона мой взгляд, изначально вредна
Так как расхолаживает
Это вовсе не говорит о
том
, что ее вообще ненужно применять
Нужно
Но позднее
Когда произойдет "
вживание
/
вживление в
шапку ". Итак, после такой корректировки, нужно только "прописать " использующиеся регистры общего назначения, после чего можно переходить к
рабочей части программы
В
ней нужно создать условия для работы "врезки " (если это нужно, после чего с
ней можно работать (выяснять интересующие
Вас детали и
/
или видоизменять под свои задумки. Ив этом случае, и
во многих других случаях, речь идет о "раскрутках логических цепочек ", начиная с
первых ее "звеньев " и
далее
, по порядку
В
ходе этих "раскруток ", можно получить качественные ответы на бОльшую часть вопросов, связанные с
работой как составных частей программы, таки всей программы
Кроме того, такая работа развивает аналитические способности, а
по своей обучающей эффективности ей вообще нет равных
Эти "страшилки " я
рассказываю
Вам вовсе не для того чтобы
Вы испугались объема предстоящей работы (если есть "
упёртость ", то это не помеха, а
если ее нетто тогда выгоднее испугаться, а
для того чтобы чётче обозначить наиболее эффективное ее направление
Эта работа не для лентяев (пусть даже самых одаренных, так как, особенно на первых порах, она связана с
достаточно большими трудозатратами и
повышенным количеством неудач
А
как же иначе Дети рождаются в
муках
, но и
радости имеются, ведь самостоятельно составленная программа - своеобразный "ребенок ".
Очччень дорогой, любимый и
приносящий много радости "Родами " займемся позднее, а
пока продолжим "курс молодого бойца ".

208 Циклический сдвиг
Циклическим сдвигом "рулят " две команды
RLF
(циклический сдвиг влево) и
RRF
(
циклический сдвиг вправо. Обе эти команды байт- ориентированные
Это означает то, что циклический сдвиг происходит внутри байта
Посмотрите в
распечатку команд
В
ней
, в
строках команд
RLF
и
RRF
, Вы найдете блок- схему циклического сдвига влево и
вправо
Механизм сдвига - кольцевой
Старший или младший бит байта (в зависимости от направления сдвига) как бы "изымается " и "переносится ", через бит флага переноса- заёма
С
,
на противоположный "конец " байта
В
данном случае, работа флага
С
сводится к
работе простейшего, однобитного
(не путайте с
однобайтным
) регистра, в
который
, после исполнении команды циклического сдвига, копируется значение старшего или младшего бита (в зависимости от направления сдвига) байта регистра, к
которому обращается команда
1   ...   36   37   38   39   40   41   42   43   ...   57


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