Вы находитесь на странице: 1из 9

7/4. Программа Analog_2.

asm: "разборки" с возможными "закольцовками" (от 2-го


"витка" и далее). Гашение незначащих нулей (2 варианта).

Актуальный вопрос: "На какую из команд процедуры АЦП "закольцеваться"?


Ответ: это зависит от того, выключается ли модуль АЦП после завершения процедуры
аналого – цифрового преобразования или не выключается.
Значит, происходит "ветвление на 2 сценария".

1. После завершения процедуры АЦП, модуль АЦП выключается.


Это случай, имеющий место быть в программах Analog_1.asm и Analog_2.asm.
В этом случае, можно перейти (см. goto SNOVA) либо на начало работы с
содержимым регистра Adcon1, либо на начало работы с содержимым регистра Adcon0.
На начало работы с содержимым регистра Adcon1 переходить не выгодно прежде
всего потому, что будет происходить "затяжка" полного цикла программы, причем, с
"выкрутасами", так как нужно будет либо менять банк (Adcon1 "лежит" в 1-м банке),
либо осуществлять переход на "вышележащую" команду выбора 1-го банка.
В принципе, такой переход не нужен, так как регистр Adcon1 можно "настроить" только
на 1-м "витке" полного цикла программы, и далее про него "забыть".
Значит нужно перейти на начало работы с содержимым регистра Adcon0.
Ниже (по тексту программы), например, на начало фиксированной задержки, переходить
нельзя по той простой причине, что модуль АЦП нужно сначала включить (он же
выключен).
Из этого следует правило: если, после завершения процедуры АЦП, модуль АЦП, в
целях "энергоэкономии", отключается, то следующее аналого – цифровое
преобразование должно начаться с подтверждения "настройки" содержимого
регистра Adcon0 (включение модуля АЦП и прочее).
В программах Analog_1.asm и Analog_2.asm, это правило выполняется.
На мой взгляд, это самый простой и выгодный вариант "закольцовки".
Что касается фиксированной задержки с расчетным временем Tacq, то в этом случае,
она необходима, так как программы, в части касающейся не относящегося к АЦП,
могут быть различной "массивности" (по времени полного цикла).
В том числе и такой, что к началу следующего цикла АЦП, конденсатор Hold может
основательно подразрядиться (за счет токов утечки и т.д.).

2. После завершения процедуры АЦП, модуль АЦП не выключается.


В этом случае, в принципе, фиксированная задержка нужна только на 1-м "витке"
полного цикла программы.
Почему?
Потому, что ту часть программы, которая отрабатывается после окончания АЦП, можно
воспринимать как задержку, интервал времени которой, в абсолютном большинстве
случаев, гораздо больше интервала времени фиксированной задержки.
А раз это так, то, начиная со 2-го "витка" полного цикла программы, зачем она
(фиксированная задержка) нужна?
Чтобы время полного цикла затягивала?
Вопрос: "Не будет ли плохо от того, что время перезаряда конденсатора Hold будет
значительно превышать время расчетной задержки Tacq"?
Ответ: нет, не будет, так как конденсатор Hold, в течение всего этого времени, просто
будет отслеживать уровень напряжения, и причем, точно.
Ни к чему плохому это не приведет.
Вывод: фиксированную задержку можно обойти ("проигнорировать").
Вот такая получается "красота", но в обмен на "едока", который энергию "кушает".
Если "энергии немеряно" и ее совсем не жалко, то, в данном случае:
- команду clrf Adcon0 нужно "убить",
- метку SNOVA нужно перенести на команду bsf Adcon0,GO (включение
преобразования).
Можно перенести метку SNOVA и на начало фиксированной задержки, и даже на
начало "настройки" содержимого регистра Adcon0 (и выше), но зачем?
От этого только затянется время отработки полного цикла программы, при одном и
том же результате замера.
1
А теперь по поводу точности замера.
Я "прогнал" все указанные выше варианты через "железо" и обнаружил "одинаковость".
Больше к этому добавить нечего.
Примечание: модуль АЦП можно выключить, сбросив в 0 только один бит ADON
(bcf Adcon0,0).

Лично я, являюсь сторонником выключения модуля АЦП тогда, когда он не нужен.


Поэтому и пользуюсь 1-м вариантом.
Кто-то может быть сторонником 2-го варианта. Не возбраняется.
Это личный выбор.
Итак, "база" АЦП, в части касающейся программы Analog_2.asm, "отработана" и теперь
в ней можно погасить незначащие нули.
Получилась программа Analog_3.asm (прилагается):

;********************************************************************************
; Analog_3.asm 3-разрядный измеритель уровней аналогового сигнала
; (с гашением незначащих нулей в двух левых индикаторах).
;--------------------------------------------------------------------------------
; Задействуется модуль АЦП.
; Для индикации показаний применена линейка из трех 7-сегментных индикаторов
; (общий катод).
; Индикация - динамическая.
; Запятая выставлена между 2-м и 3-м (если считать от старшего
; десятичного разряда) десятичными разрядами.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@Lipetsk.ru
;********************************************************************************
; Функции выводов порта А:
; RA0 - активный входной канал АЦП,
; остальные выводы порта А не задействованы.
; Функции выводов порта В:
; RB0...RB7 - управление секторами A,B,C,D,E,F,H,G.
; Функции выводов порта С:
; RC0...RC2 - выходы дешифратора,
; остальные выводы порта C не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Используется PIC16F873A.
;----------------------------------------------
; Объем программы: 128 слов в памяти программ.
;================================================================================
LIST p=16F873A ; Задание типа микроконтроллера.
__CONFIG 3F31H ; XT-генератор, PWRT вкл., защита выкл., сброс
; BOR запрещен, LVP выкл., DEBUG выкл.
;================================================================================
; Регистры специального назначения.
;================================================================================
IndF equ 00h ; Доступ к памяти через FSR.
PCL equ 02h ; Счетчик команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.
PortB equ 06h ; Регистр защелок порта B.
PortC equ 07h ; ----------"---------- C.
TrisB equ 06h ; Регистр выбора направлений работы
; выводов порта В (банк 1).
TrisC equ 07h ; ----------"---------- C (банк 1).
AdresH equ 1Eh ; Регистр старшего байта результата АЦП.
AdresL equ 1Eh ; Регистр младшего байта результата АЦП
; (банк 1).
Adcon0 equ 1Fh ; Регистр настройки модуля АЦП.
Adcon1 equ 1Fh ; Регистр настройки модуля АЦП (банк 1).
;================================================================================
2
; Регистры общего назачения.
;================================================================================
LED0 equ 20h ; Регистр хранения результатов преобразований
; 1-го двоично-десятичного разряда.
LED1 equ 21h ; ------- 2-го -------------------------
LED2 equ 22h ; ------- 3-го -------------------------
Index equ 24h ; Счетчик количества малых колец индикации.
Count equ 25h ; Счетчик количества больших колец индикации.
Temp equ 26h ; Регистр временного хранения данных.
Mem equ 27h ; Регистр оперативной памяти.
Temp_L equ 28h ; Регистр младшего разряда 2-байтного
; двоичного числа.
Temp_H equ 29h ; Регистр старшего разряда 2-байтного
; двоичного числа.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присвоение битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
Z equ 2 ; Флаг нулевого результата.
RP0 equ 5 ; Бит выбора банка.
GO equ 2 ; Бит статуса модуля АЦП.
;================================================================================
org 0 ; Начать выполнение программы с 0-го
; адреса PC.
;********************************************************************************

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Перевод в пассивное состояние всех выходов дешифратора
; (для исключения "мелькания" при включении питания).
;-------------------------------------------------------
movlw b'11111111' ; Предустановка состояний выходов дешифратора
movwf PortC ; RC2...RC0 (RC7..3 устанавливаются в 1
; "за компанию").
;-------------------------------------------
; Настройка направлений работы.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы порта В работают на выход.
clrf TrisC ; Все выводы порта С работают на выход.
;-------------------------------------------
; Работа с регистром Adcon1.
;-------------------------------------------
movlw b'10001110' ; Диапазон квантования напряжения от -Vss до
movwf Adcon1 ; + Vdd, AN0-аналоговый вход,
; AN1...AN4 - цифровые каналы ввода/вывода,
; правое выравнивание.
bcf Status,RP0 ; Переход в 0-й банк.
;================================================================================
; Циклическая подпрограмма измерения уровня аналогового сигнала, присутствующего
; на выводе RA0, обработки результата измерения и его вывода на индикацию.
;================================================================================
; Работа с регистром Adcon0.
;-------------------------------------------
SNOVA movlw b'01000001' ; Включение модуля АЦП, выбор канала AN0
movwf Adcon0 ; (RA0), источник тактового сигнала Fosc/8,
3
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.
;------------------------------------------------
; Задержка для перезаряда конденсатора.
;------------------------------------------------
movlw .6 ; Стандартный,
movwf Count ; вычитающий,
decfsz Count,F ; однобайтный
goto $-1 ; счетчик.
;-------------------------------------------
; Начало аналого-цифрового преобразования.
;-------------------------------------------
bsf Adcon0,GO ; Включение преобразования. Конденсатор
; отключается от аналогового входа на время
; преобразования.
;-------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;-------------------------------------------
btfsc Adcon0,GO ; Ожидание окончания аналого-цифрового
goto $-1 ; преобразования.
;-------------------------------------------
; АЦП закончено. Результат - в AdresH/AdresL.
; Копирование результата в Temp_H/Temp_L.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_L ; W --> Temp_L.

movf AdresH,W ; AdresH --> W.


movwf Temp_H ; W --> Temp_H.
;-------------------------------------------
; В Temp_H/Temp_L "лежит" результат АЦП.
;-------------------------------------------
; Теперь модуль АЦП можно выключить.
;-------------------------------------------
clrf Adcon0 ; Для снижения потребляемого устройством тока,
; модуль АЦП выключается до конца отработки
; текущего полного цикла программы.

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ГРУППА ПОДПРОГРАММ ПРЕОБРАЗОВАНИЯ 2-БАЙТНЫХ ДВОИЧНЫХ ЧИСЕЛ В 3-РАЗРЯДНЫЕ
; ДЕСЯТИЧНЫЕ ЧИСЛА (разрядность двоичного числа - 10).
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Подготовка к преобразованию.
;================================================================================
Bin2_10 bcf Status,C ; Сброс флага переноса-заема.
movlw .16 ; "Закладка" в регистр Count1 числа
movwf Count ; проходов преобразования.

clrf LED0 ; Сброс регистра LED0.


clrf LED1 ; -------"------ LED1.
;================================================================================
; Циклический сдвиг влево.
;================================================================================
Loop16 rlf Temp_L,F ; Побитная
rlf Temp_H,F ; "переправка"
rlf LED0,F ; содержимого
rlf LED1,F ; Temp_H/Temp_L
; в LED1/LED0.
decfsz Count,F ; Анализ числа проходов
goto adjDEC ; преобразования.
;================================================================================
; Поразрядное распределение полубайтов регистров LED1 и LED0
; по младшим полубайтам регистров LED2, LED1, LED0.
4
;================================================================================
movfw LED1 ; Запись младшего полубайта LED1
andlw 0Fh ; в младший полубайт LED2.
movwf LED2 ; --------------------------------

swapf LED0,W ; Запись старшего полубайта LED0


andlw 0Fh ; в младший полубайт LED1.
movwf LED1 ; --------------------------------

movfw LED0 ; Запись младшего полубайта LED0


andlw 0Fh ; в младший полубайт LED0.
movwf LED0 ; --------------------------------

goto GASH ; Переход в ПП гашения незначащих нулей.

;================================================================================
; Запись в регистр FSR адресов регистров LED0...1 для дальнейшей косвенной
; адресации к ним в ПП adjBCD.
; Переход к обработке следующего LED - после возврата по стеку.
;================================================================================
adjDEC movlw LED0 ; Запись в регистр FSR, через регистр W,
movwf FSR ; адреса регистра LED0 с дальнейшим переходом
call adjBCD ; в ПП adjBCD (адрес следующей команды
; закладывается в стек).
;---> Возврат по стеку из ПП adjBCD.
movlw LED1 ; -----------------------------
movwf FSR ; То же самое для регистра LED1.
call adjBCD ; -----------------------------
;---> Возврат по стеку из ПП adjBCD.

goto Loop16 ; Переход в ПП Loop16, то есть, на


; следующее кольцо числовых преобразований.
;--------------------------------------------------------------------------------
; Основные операции преобразования двоичных чисел в двоично-десятичные.
;--------------------------------------------------------------------------------
adjBCD movlw 3 ; Суммирование содержимого текущего LED с
addwf 0,W ; числом 03h, с записью результата операции,
movwf Mem ; через регистр W, в регистр Mem.

btfsc Mem,3 ; Анализ состояния бита №3 регистра Mem.


movwf 0 ; Если бит №3 = 1, то содержимое регистра Mem
; копируется в текущий LED.

movlw 30 ; Если бит №3 = 0, то содержимое текущего LED


addwf 0,W ; складывается с константой 30h, с записью
movwf Mem ; результата операции, через регистр W,
; в регистр Mem.
btfsc Mem,7 ; Анализ состояние бита №7 регистра Mem.
movwf 0 ; Если бит №7 = 1, то содержимое регистра Mem
; копируется в текущий LED.
retlw 0 ; Если бит №7 = 0, то регистр W очищается и
; происходит возврат по стеку в ПП adjDEC.
;================================================================================

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ГРУППА КОМАНД ПРЕОБРАЗОВАНИЯ ДВОИЧНО-ДЕСЯТИЧНОГО КОДА
; В КОД 7-СЕГМЕНТНОГО ИНДИКАТОРА.
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TABLE addwf PCL,F ; Содержимое счетчика команд PC увеличивается
; на величину содержимого W.
retlw b'00111111' ; ..FEDCBA = 0
retlw b'00000110' ; .....CB. = 1
retlw b'01011011' ; .G.ED.BA = 2
retlw b'01001111' ; .G..DCBA = 3
retlw b'01100110' ; .GF..CB. = 4
retlw b'01101101' ; .GF.DC.A = 5
5
retlw b'01111101' ; .GFEDC.A = 6
retlw b'00000111' ; .....CBA = 7
retlw b'01111111' ; .GFEDCBA = 8
retlw b'01101111' ; .GF.DCBA = 9
retlw 0 ; ........ = гашение всех сегментов.
;================================================================================
; Подпрограмма гашения незначащих нулей (в LED0, ноль не гасится).
;================================================================================
GASH movf LED2,W ; Если содержимое LED2=0, то в него
movlw .10 ; записывается число.10
btfss Status,Z ; (сценарий гашения всех сегментов).
goto DINAM ; Если оно не=0, то рабочая точка программы
movwf LED2 ; "улетает" в ПП динамической индикации.

movf LED1,W ;
movlw .10 ; То же самое,
btfss Status,Z ; только для
goto DINAM ; LED1.
movwf LED1 ;
; ПРИМЕЧАНИЕ: запятая не гасится, так как она выставляется позже.

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ПОДПРОГРАММА ДИНАМИЧЕСКОЙ ИНДИКАЦИИ
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; Подготовка счетчика количества малых колец индикации
; Index к началу полного цикла динамической индикации.
;------------------------------------------------------
DINAM clrf Index ; Сброс в 0 содержимого счетчика малых
; колец индикации Index.
;--------------------------------------------------------------------------------
; Запись в регистр Count количества больших колец индикации, которые
; должны быть отработаны за один полный цикл динамической индикации.
;--------------------------------------------------------------------------------
movlw .60 ; .60 --> W.
movwf Count ; W --> Count.

CYCLE movlw b'11111111' ; Предустановка состояний выходов дешифратора


movwf PortC ; RC2...RC0 (RC7..3 устанавливаются в 1
; "за компанию").
;--------------------------------------------------------------------------------
; Подготовка к косвенной адресации: запись в регистр W адреса регистра младшего
; разряда (LED0).
; ("привязка" к 7-сегментному индикатору, с активации которого начинается полный
; цикл 1-го большого кольца индикации).
;--------------------------------------------------------------------------------
movlw LED0 ; Запись в регистр W адреса регистра LED0.
addwf Index,W ; Увеличение адреса регистра LED0 на величину
; числа, записанного в регистре счетчика
; количества малых колец индикации Index,
; c сохранением результата в регистре W.
;--------------------------------------------------------------------------------
; Косвенная адресация.
;--------------------------------------------------------------------------------
movwf FSR ; Копирование содержимого регистра W
; в регистр FSR.
movf IndF,W ; Копирование содержимого регистра с адресом,
; записанным в регистре FSR, в регистр W.
call TABLE ; Условный переход в ПП TABLE.
;---> Возврат по стеку из ПП TABLE.
;--------------------------------------------------------------------------------
; Группа команд установки запятой.
;--------------------------------------------------------------------------------
movwf Temp ; Копирование содержимого регистра W (7-
; сегментные коды индицируемых двоично-
; десятичных чисел) в регистр Temp.
movlw 1 ; Задание места "дислокации" запятой
6
; (во 2-м знакоместе справа).
bsf Status,Z ; Поднятие флага нулевого результата Z.
subwf Index,W ; Вычитание содержимого регистра W из
; содержимого регистра Index.
btfss Status,Z ; Проверка состояния флага Z.
goto NO_DOT ; Если флаг Z опущен (результат операции
; не=0), то переход на метку NO_DOT
; (запятая не выставляется).
bsf Temp,7 ; Если флаг Z поднят (результат операции=0),
; то установка в единицу 7-го бита
; (установка запятой) регистра Temp.
;--------------------------------------------------------------------------------
; Группа команд вывода десятичной цифры на индикацию.
;--------------------------------------------------------------------------------
NO_DOT movf Temp,W ; Копирование содержимого регистра Temp
; (7-сегментные коды индицируемых двоично-
; десятичных чисел, плюс запятая) в регистр W
movwf PortB ; Вывод содержимого регистра W в порт В.
;================================================================================
; ДЕШИФРАТОР: программная реализация аналога 555ИД7 (для количества выходов = 3).
;================================================================================
movf Index,W ; Index --> W.
;-------------------------------------
; 3-сценарный вычисляемый переход.
;-------------------------------------
addwf PCL,F ; Содержимое счетчика команд PC увеличивается
; на величину содержимого W.
goto D_0 ; Сценарий №1.
goto D_1 ; Сценарий №2.
bcf PortC,2 ; Сценарий №3. На выводе RC2 выставляется 0.
goto $+4 ; Завершение дешифровки.
D_0 bcf PortC,0 ; На выводе RC0 выставляется 0.
goto $+2 ; Завершение дешифровки.
D_1 bcf PortC,1 ; На выводе RC1 выставляется 0.
;--------------------------------------------------------------------------------
; Группа команд задержки, определяющей время нахождения одного 7-сегментного
; индикатора в активном состоянии (определяющей время прохождения малого
; кольца индикации).
;--------------------------------------------------------------------------------
movlw .67 ; Запись в регистр Temp
movwf Temp ; времязадающей константы.

decfsz Temp,F ; 1-байтный, вычитающий


goto $-1 ; счетчик (задержка).
;--------------------------------------------------------------------------------
; Увеличение на 1 содержимого счетчика количества малых колец индикации Index
; с последующей проверкой результата инкремента на равенство (или нет) числу .3.
;--------------------------------------------------------------------------------
incf Index,F ; Увеличение на 1 содержимого регистра Index
; с сохранением результата в нем же.
movlw 3 ; Запись в регистр W константы .3.
bcf Status,Z ; Сброс флага нулевого результата Z.
subwf Index,W ; Index - W = ... (результат --> W).
btfss Status,Z ; Результат операции вычитания равен
; или нет нулю?
goto CYCLE ; Если не =0 (в регистре Index - число не
; равное 3), то переход на новое малое кольцо
; индикации.
; Если =0 (в регистре Index - число равное
; 3), то программа исполняется далее.
;--------------------------------------------------------------------------------
; После того, как последовательно активизируются все 3 7-сегментных индикатора
; линейки, - подготовка к переходу на новое большое кольцо индикации.
;--------------------------------------------------------------------------------
clrf Index ; Сброс в 0 содержимого регистра Index.
;--------------------------------------------------------------------------------
7
; Уменьшение на 1 содержимого счетчика количества больших колец индикации Count.
;--------------------------------------------------------------------------------
decfsz Count,F ; Декремент содержимого счетчика количества
; больших колец индикации Count с сохранением
; результата в нем же.
goto CYCLE ; Если результат декремента не=0, то переход
; на новое большое кольцо индикации.
; Если результат декремента =0, то программа
; исполняется далее (переход на новый полный
; цикл динамической индикации).
;--------------------------------------------------------------------------------
; Выход из ПП динамической индикации.
;--------------------------------------------------------------------------------
clrf PortB ; "Гашение" всех сегментов.
goto SNOVA ; Переход на следующий цикл программы.
;********************************************************************************
end ; Конец программы.

В ходе работы с "черновиком" этой программы, выяснилось, что при наличии


процедуры гашения незначащих нулей, в момент включения питания, кратковременно
высвечиваются все секторы индикаторов (после этого, все в норме).
Когда незначащие нули не гасились, это "маскировалось".
Причина: по умолчанию, на выходах защелок порта С, устанавливаются нулевые
уровни.
Эта "бяка убивается" дополнительной предустановкой состояний выводов порта С в
единицы, произведенной в самом начале 1-го "витка" полного цикла программы.
Она в точности такая же, как и предустановка состояний выводов порта С в единицы,
произведенная в начале ПП CYCLE.
Последнее "убивать" нельзя по причине функциональной нужности (объяснено ранее).
"Новорожденную" предустановку я "окрасил" в такой же цвет, в который "окрашены"
команды ПП динамической индикации (чтобы обозначить "родившую ее мать").
То, что относится к процедуре гашения незначащих нулей, выделено фиолетовым
цветом.
В данном случае, незначащие нули гасятся в старшем и среднем десятичных
разрядах.
Ноль младшего десятичного разряда не гасится, хотя, при желании, его можно
погасить.
ПП гашения взята из "заготовки" Gash.asm (см. "Самоучитель").
Объяснение ее работы было дано ранее. Повторяться не буду.
При такой малой разрядности гашения (2), выгодно применить именно ее.
Соответственно, в ПП TABLE, нужно "прописать" (в любом случае) сценарий гашения
всех сегментов.
Ниже Вы видите еще один вариант гашения, с использованием косвенной адресации.

;================================================================================
; Подпрограмма гашения незначащих нулей c использованием косвенной адресации.
; В данном случае, нули гасятся в первых двух (слева) индикаторах.
;================================================================================
GASH movlw .2 ; Запись количества проверяемых разрядов
movwf Count ; в указатель разрядов Count.
;----------------------------------------------------------
; Косвенная адресация к содержимому текущих LED... .
;----------------------------------------------------------
movlw LED2 ; Стандартная процедура косвенной адресации
movwf FSR ; с "переправкой" содержимого, сначала, LED2,
; а затем и LED1, в регистр W.
POVTOR movf IndF,W ; Содержимое текущего LED копируется в W с
; целью дальнейшего ответа на вопрос:
; "Содержимое текущего LED равно или
; не равно 0"?
; ПРИМЕЧАНИЕ: команда movf воздействует на флаг Z.
;-------------------------------------
; 1-я проверка на нулевой результат.
8
;-------------------------------------
btfss Status,Z ; Проверка состояния флага Z.
goto DINAM ; Если содержимое текущего LED не=0,
; то выход из процедуры.
movlw .10 ; Если содержимое текущего LED=0, то в текущий
movwf IndF ; LED записывается число .10
; (гашение всех сегментов).
;-------------------------------------
; Переход на следующий, текущий LED.
;-------------------------------------
decf FSR,F ; Уменьшение адреса текущего LED на 1.
decf Count,F ; Уменьшение содержимого указателя разрядов
; на 1.
;-------------------------------------
; 2-я проверка на нулевой результат.
;-------------------------------------
btfss Status,Z ; Проверка состояния флага Z.
goto POVTOR ; Если содержимое Count не=0, то переход на
; повторную проверку на незначащие нули
; (goto POVTOR).
;================================================================================

Такой вариант выгодно применять при разрядности гашения от 4-х и более.


Эта ПП, по сравнению с аналогичными ПП, применяемыми ранее, максимально
упрощена, так как, в данном случае, не требуется каких-то дополнительных
"наворотов".
Работа этой ПП проверена в "железе". Можно смело использовать.
Она "адаптирована" под динамическую индикацию и хороша тем, что переход на
любую разрядность гашения прост: нужно только сменить числовое значение константы
на нужное и "прописать" LEDы с соблюдением порядка старшинства.
Примечание: не смотря на то, что вместе со всеми сегментами гасится и запятая, она
"возрождается из пепла" позднее, и это "возрождение" не зависит от того, есть ли
незначащий ноль в среднем (в данном случае) десятичном разряде или его нет.
Запятая выставляется в любом случае.
При наличии незначащего нуля в среднем (или младшем) десятичном разряде, можно
загасить и запятую, но я, честно говоря, не вижу в этом практической необходимости.

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru

Оценить