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