Самоучитель по программированию PIC контроллеров для начинающих (Е.А. Корабельников,2008). Самоучитель по программированию PIC контроллеров для начинающих. Система команд pic16F84A 26 Что такое программа иправила ее составленияПример создания программы автоколебательного мультивибратораДирективы.
![]()
|
00000110 11010010 ; результат го суммирования. В младшем байте – число 16+194=210. Инкремента содержимого старшего байта нет. 1940 00000111 10010100 ; результат го суммирования. В младшем байте – число 210+194=404-256=148. Инкремент содержимого старшего байта (увеличение числа .06 на 1). Итог 194 х 8+194+194=194 х 10=.1940, что и требовалось получить Вместо .194, можете использовать любое другое значение множимого (из числового диапазона байта. Вы получите произведение, враз большее, чем множимое Вопрос : "Можно ли реализовать ПП умножения без использования циклических сдвигов влево, а только на основе последовательных суммирований множимого, количество раз, равное множителю "? Ответ : конечно же можно, нов этом случае, объем подпрограммы увеличится, и при прочих, равных условиях, она будет отрабатываться медленнее Каков может быть диапазон используемых множителей В рассматриваемом случае ( двухбайтный регистр, он такой же, как и диапазон используемых множимых (.00 ... .255), с учетом того, что редко когда возникает практическая необходимость умножать на 0 или 1. Если нужно умножить на .10, например, число .10000 (результат умножения больше чем, то необходимо "ввести в эксплуатацию " еще один (третий) регистр, причем число предварительно будет записываться в два регистра (и, а байт регистра H и биты 6 и 7 регистра M предварительно нужно сбросить в 0. В этом случаев связи с необходимостью обслуживания работы дополнительного регистра, в группе команд умножения на 2, количество команд увеличится Из сказанного можно сделать следующий практический вывод : если есть готовая подпрограмма, то ее можно "выпотрошить " в симуляторе , но если речь идет о создании подпрограммы, тов ходе ее составления, особо надеяться на помощь симулятора не стОит Такого рода работа делается, в основном , "в мозгах и на бумаге ". Только после того, как "родится " подпрограмма или какая- то функционально завершенная ее часть (пусть даже и "корявая "), для оценки ее "жизнеспособности ", можно (и нужно) задействовать симулятор Вывод : "на симулятор надейся, асам не плошай ". Примерно тоже самое можно сказать и о "бесплатном сыре " в виде "готовых к употреблению " программ и подпрограмм На практике часто возникает потребность в их "модернизациях " под свои задумки, и если перед этим, как следует не "погонять " нули с единицами в стандартных (классических) подпрограммах (в первую очередь, в голове и на бумаге, а затем ив симуляторе ), то можно банально "попасть в мышеловку " своей некомпетентности В принципе , программирование это такая же работа, как и любая другая, только связанная с переработкой большого массива информации, изначально "сваленной " в большую и привлекательную "кучу ". Кто сумеет "расчленить " этот массивна функционально законченные части, разобраться с каждой из них и "разложить их по полочкам " так, чтобы они не "наезжали " друг на друга и чтобы было понятно "что где лежит ", тот в этой "битве " и будет победителем Отследить процесс циклических сдвигов, с задействованием бита C регистра STATUS , водно, двух, трех и четырехбайтном регистрах, можно в программе , разработанной Николаем Маровым Она называется shift_c.exe и находится в папке " Программы " . 218 Дополнительно Пример поиска и устранения ошибки в программе . Пришло время объяснить / показать , что такое "бесплатный сыри каковы последствия его "употребления ". Речь пойдет об ошибках Они допускаются при составлении программ Даже самые многоопытные программисты, хотя и не часто, но все- таки их допускают Ошибки могут быть ив "чужих " программах Часть ошибок можно устранить с помощью симулятора , но самыми сложными ошибками являются ошибки функционального характера ассемблирование прошло успешно, но программа или не работает вообще, или работает не так, как нужно Это встречается сплошь и рядом , и составление редко какой, более или менее сложной программы, обходится без ошибок Начинающие программисты, по определению, будут "плодить " их в больших количествах Если относиться к ним трагически, тона своем занятии программированием можно смело ставить большой и жирный крест Таким образом, для психологической защиты от этой неизбежной "беды ", нужно присвоить ей статус "полезности ". И это сделать достаточно просто, так как любая ошибка учит Такой довод настолько " железобетонен ", что с ним трудно спорить Если ошибка обнаружена и исправлена своими силами, то положительный эффект от этого, колоссальный Эффективная работа над ошибками, как это не странно звучит, - одна из главных составляющих успеха Этому тоже нужно учиться Исходя из "вышележащих " соображений, при работе над этим разделом, я сознательно "заложил " в текст программы Rlf.asm ошибку функционального характера и как рыбак, стал ждать, когда же кто- нибудь "клюнет " (прошу не считать меня "садистом ". Примерно по той же причине, по которой нельзя считать "садистом " хирурга. Эту ошибку не только обнаружил, но и исправил Марсель Валеев из г Глазов Думаю , что Марсель не будет наменяв обиде, если я опубликую выдержки из его писем Как человек упертый и настойчивый , я тщательно изучаю каждую главу Вашего учебника и, как правило, разрабатываю уже свои программы под свои разработки, опираясь на знания, полученные от вас В главе 14 вы привели пример использования команды сдвига в программе rlf.asm : умножение на 10 числа от 0 до 255. Я встроил ее в, вставил передней пару команд закладки множимого и начал обкатывать, так, любопытства ради При умножении выборочных чисел от 2 до 127 проблем не возникло Результаты сходились она также умножает без ошибок Получается 2550. Приумножении на 8, получилось 784. Далее я попробовал умножить на 8 число 200 и получил 832. В результате я выяснил , что сбой происходит при третьем умножении на 2. Число 800 на 2 умножается неправильно Сдвиг влево, в старшем байте, не происходит Вот Вам и практический пример эффективности использования методики "врезки " подпрограммы в другую "полноценную " программу, о которой говорилось ранее Ошибка обнаружена и "локализована ". Далее, как это и положено , идет "раскрутка ": нужно позаботиться о сдвиге в регистре RegH В начале я стал вставлять различные подпрограммки ветвления, но это, в конечном итоге, привело к громоздкости 219 В конце концов меня "осенило ", и я выкинул изначального текста все команды ветвления, которые опрашивают флаг С в трех последовательных умножениях на 2, и получилась красивая подпрограмма, которая великолепно умножает все числа в промежутке от 0 до Нет вопросов Оценка "отлично ". А теперь давайте детально разберемся, почему, приумножении числа .194 или .200 на 8, ошибка происходит именно при третьем умножении на 2, и почему наличие команд ветвления в операциях умножения на 2, является функциональной ошибкой В соответствии с описанным выше алгоритмом операции умножения на 10, в пределах одной операции умножения на 2, должны последовательно происходить два циклических сдвига влево, в порядке : - сдвиг содержимого регистра младшего разряда, - сдвиг содержимого регистра старшего разряда, вне зависимости от величины содержимого этих регистров Сдвиг содержимого регистра RegL происходит всегда, а наличие сдвига содержимого регистра RegH поставлено в зависимость от состояния флага переноса С ( btfsc Status,C ). Это означает то, что в зависимости от значения старшего бита регистра младшего разряда RegL на момент начала сдвига содержимого регистра (после отработки команды Status,C ), сдвиг содержимого регистра RegH может происходить, а может и не происходить (два сценария. Детализируем Если после исполнения циклического сдвига содержимого регистра, в бит С "уходит " единица (из старшего бита байта регистра, тов дальнейшем, произойдет сдвиг содержимого регистра (см логику работы команды, а если в бит С "уйдет " ноль, то сдвига содержимого регистра RegH произведено не будет, так как в соответствии с логикой работы команды, команда будет проигнорирована (вместо нее, будет исполнен "виртуальный " NOP ). Это полностью объясняет все то, что наблюдал Марсель при "прогонке ", в симуляторе , подпрограммы умножения на 10. Почему ошибка возникла только на третьем умножении на 2, а два предшествующих умножения были выполнены верно Переводим число .194 и .200 в бинарный вид 11000010 и 11001000 соответственно Смотрим набиты и 7. Ив одном, ив другом, по единице, которые, при первых двух умножениях , будут "переходить " в бит С , состояние которого анализируется командой Status,C В этих случаях, последующий сдвиг содержимого регистра RegH производиться будет А вот бит 5 (третий слева) имеет значение 0 и именно он (ноль) "перейдет " в бит С на третьей операции умножения на 2, и заблокирует сдвиг содержимого регистра RegH ( содержимое регистра RegL сдвинется , а сдвига содержимого регистра RegH не произойдет, что и имеет место быть Для числа .194. Биты 6 и 7 числа .194 равны 1, следовательно, первые две операции умножения на 2 пройдут без ошибок получается 194 х 2 х 2=776. Бит 5 числа .194 равен 0, следовательно, произойдет сдвиг только содержимого регистра, а сдвиг содержимого регистра RegH будет заблокирован Вот как это выглядит - результат 2- й операции х 00000011 00001000 - число .776. - результат 3- й операции х 00000011 00010000 - число .784 вместо х см выдержку из письма Марселя ). Тоже самое можно "проделать " и с числом .200. Получится .832 вместо х. В случаях умножения, на 8, этих чисел (.194 или .200), еще "повезло ", так как ошибка происходит только на третьем умножении на 2, а если умножить на 8, например, число .131 ( 10000011 ), то ошибочным будет уже второе (а также и третье ) умножение на 2. Таким образом, наличие в программе описанной выше функциональной ошибки, приводит к тому , что числовой диапазон байта (.0 … .255) как бы "разбивается на зоны ", в пределах которых, умножение на 8 может происходить безошибочно или с ошибками 220 Зоны" безошибочной работы До .31 включительно биты 7,6,5 равны 000 В течение всех 3- х операций умножения на 2, для получения верного результата умножения на 8, достаточно сдвигов в пределах младшего байта ( RegL ), которые гарантированно происходят, и переносов в старший байт ( RegH ) не требуется 2. От .32 до .63 включительно биты 7,6,5 равны 001 Первые 2 сдвига происходят в пределах младшего байта ( RegL ). То есть, для получения верного результата, переносов в старший байт ( RegH ) не требуется После этого, на 3- м сдвиге , происходит безошибочный перенос из старшего бита байта регистра RegL в младший бит байта регистра (через бит С регистра Status ). От .96 до .127 включительно биты 7,6,5 равны 011 Первый сдвиг происходит в пределах RegL , а при 2- ми 3- м сдвигах , происходят безошибочные переносы 4. От .224 до .255 включительно биты 7,6,5 равны 111 При всех трех сдвигах, происходят безошибочные переносы " Зоны " работы с ошибками : От .64 до .95 включительно биты 7,6,5 равны 010 При 1- м сдвиге , ошибки не будет, так как переноса вне требуется, при 2- м сдвиге , произойдет безошибочный перенос, так как бит 6 равен 1, а при 3- м сдвиге произойдет ошибка, так как бит 6, равный нулю, заблокирует сдвиг содержимого регистра RegH 2. От .128 до .159 включительно биты 7,6,5 равны 100 При 1- м сдвиге , произойдет безошибочный перенос, прими- м сдвигах , произойдут ошибки, так как биты 6 и 5, равные нулю, заблокируют оба сдвига содержимого регистра RegH 3. От .160 до .191 включительно биты 7,6,5 равны 101 Здесь ошибочной будет 2- я операция х. От .192 до .223 включительно биты 7,6,5 равны 110 Здесь ошибочной будет 3- я операция х. Таким образом, программа Rlf.asm является как бы "частично рабочей ". Для того чтобы сделать ее полностью рабочей, нужно изъять из ее текста все три команды Status,C В этом случае, будет происходить гарантированный сдвиг содержимого регистра, независящий от состояния флага С Это вовсе не означает то, что при создании других алгоритмов умножения, команды ветвления вообще можно "выкинуть на помойку ". Они могут быть необходимы в тех случаях, когда числа из различных "числовых зон ", необходимо умножить на различные множители, но это уже более сложная задача, которой лучше заняться только после приобретения достаточных знаний и опыта Итак , после детального разбирательства, выяснилось, что приумножении на 8, - в "зоне " чисел до .127 могут происходить ошибки (от .64 до .95), - в "зоне " чисел от .128 до .255 может происходить безошибочная работа (от .224 до .255). Что дает такое "копание "? Кроме очень эффективного усвоения информации и приобретения практических навыков, оно дает, подкрепленную реальными делами, уверенность в своих силах, причем эта уверенность относится к самой высокой, "бойцовской " категории Если попытаться, в общем виде, сформулировать методику поиска и устранения функциональных ошибок в программах , то это будет выглядеть примерно так При отладке программы в симуляторе выясняется, что она работает не так как нужно В нем же (в симуляторе ) необходимо "локализовать " участок программы, на котором эта ошибка проявляется (максимально сузить "сектор поиска "). Далее, фиксируется несоответствие между тем, что должно быть и реальным результатом ( например , как в нашем случае ха получилось .784). Всё Симулятор в сторону "Принимаем позу мыслителя ", готовим литр кофе и пачку сигарет, "включаем мозги " и пытаемся понять, почему получен именно такой результат Если походу разбирательств, возникает необходимость в дополнительной информации, то опять задействуется симулятор , который, таким образом, является всего- лишь 221 поставщиком " необходимой для анализа, исходной информации, ноне "панацеей от всех бед ". Все основные "дела " должны "делаться " в мозгах Лентяи сразу же "выпадают в осадок ", а "выживают " только упертые и въедливые , к которым , вне всякого сомнения, относятся такие люди как Марсель В идеале , программист вообще должен обходиться без помощи симулятора , работая только с текстом программы Примечание : никаких исправлений в текст программы Rlf.asm и в ее описание я вносить не буду, а иначе уничтожается предмет разбирательств " Самоучитель по программированию PIC контроллеров для начинающих" http://ikarab.narod.ru E-mail: karabea@lipetsk.ru 222 15. Введение в принцип построения подпрограммы динамической индикации Косвенная адресация А теперь , имея некоторый опыт и навыки , давайте разберемся, как осуществить вывод данных на индикацию, используя принцип динамической индикации Совершенно понятно, что устройство, в котором реализовано только это, практической ценности не представляет Оно представляет ценность только тогда, когда "вмонтировано " в более сложное устройство Функция – визуальное отображение результата / результатов работы всего устройства Динамическая индикация организуется тогда, когда линейка состоит из нескольких- сегментных индикаторов (знакомест. Почему, когда речь идет о м / контроллерах , к которым нужно "пристегнуть " несколько- сегментных индикаторов, выбирается именно динамический способ индикации, а не "статический ", который применялся "на заре " цифровой техники (вспомните про индикаторы, с "кучей " подключенных к ним проводов и "кучей " микросхем, обслуживающих их работу У меня такая "каракатица " есть В кладовке лежит Выбрасывать жалко Объяснение простое на эту "старушку ", не хватит выводов портов даже достаточно "крутого " м / контроллера А если и хватит , то "овчинка выделки не стоит ", ведь перейдя на динамическую индикацию, можно получить тот же результат, но гораздо более дешевым способом- выводной порт (порты, которым "укомплектована " значительная часть ПИКов (ноне все типы, вполне подходит для управления 7- сегментными индикаторами |