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

7/10. Работа с несколькими источниками аналогового сигнала.

Цифровой
измеритель абсолютной разницы уровней двух напряжений, с выводом на
индикацию ее значения (разрешение 5 мв.) и знака результата вычитания, а
также с переводом числового значения абсолютной разницы в форму
ШИМ-сигнала.
Теперь давайте разберемся с каналами АЦП, а заодно и с другими "полезностями".
В PIC16F873A, имеется 5 каналов АЦП.
Следовательно, можно "оцифровать" уровни до 5-ти аналоговых сигналов, поступающих
от различных, внешних источников.
Так как модуль АЦП не может одновременно работать более чем с одним внешним
источником аналогового сигнала, то нужно организовать последовательную работу
(опрос каналов).
Для чего все это нужно?
Можно последовательно "оцифровать" уровни нескольких аналоговых сигналов,
например, с целью контроля числовых значений этих уровней, с целью использования
этой "цифири" в качестве констант и т.п.
Но гораздо больший интерес представляет собой "оцифровка" уровней аналоговых
сигналов, с дальнейшей, математической обработкой результатов нескольких АЦП.
Результаты этой обработки можно использовать для достижения очень "аппетитных и
вожделенных" целей.
В самом "ходовом" случае, речь идет о математическом вычислении степени
расхождения уровней двух аналоговых сигналов типа "вычисление абсолютной
разницы".
Абсолютная разница есть беззнаковое (имеется ввиду "+"/"-") числовое значение
операции вычитания.
Если результат вычисления абсолютной разницы "укомплектовать" знаком результата
вычитания, то … (далее "телега ставится впереди лошади". Стоп-машина).
Сначала нужно разобраться с тем, как это делается и что за результат получается, а
только потом "ломать голову" над тем, "к какой стенке его прислонить".
В противном случае, получается "дележ шкуры не убитого медведя".
Житейский вывод: нужно "выйти на охоту, завалить медведя и содрать с него шкуру".
Да … И опасно, и хлопотно. А куда деваться?
Так что, "пулемет в руки" и "айн, цвай, драй" в "дремучий лесок".

1
Выше Вы видите принципиальную схему "учебно – тренировочного" устройства, с
помощью которого можно отследить все числовые "телодвижения", происходящие при
переводе абсолютной разницы аналоговых уровней, присутствующих на двух
аналоговых входах (AN0 и AN1), в ШИМ-сигнал.
Эти "телодвижения", с точностью до одной "квантовки", можно отследить в линейке из
трех 7-сегментных индикаторов, в "связке" с осциллографом.
О скважности ШИМ-сигнала можно также судить по интенсивности "горения" светодиода
"Контроль ШИМ" (это для людей, которые не имеют осциллографа).
В зависимости от величины расхождения уровней напряжений U1 и U2, будет меняться
- и значение "цифири", выведенной на индикацию
(числовое значение абсолютной разницы),
- и интенсивность "горения" светодиода "Контроль ШИМ"
(числовое значение абсолютной разницы, переведенное в форму ШИМ-сигнала),
- и состояния ("горит"/"погашен") светодиода "Знак результата"
(знак результата вычитания).
Вне зависимости от значений U1 и U2, но при соблюдении равенства U1 = U2, на
индикацию будет выведен символ "0".
При этом,
- светодиод "Контроль ШИМ" будет погашен
(на выходе 2 уровень логического нуля. Импульсов нет),
- светодиод "Знак результата" также будет "погашен"
(нулевой результат вычитания считается положительным).
Если, например, зафиксировать значение U1 и менять значения U2, то, по мере
удаления от "точки равенства" (в любую сторону), значение индицируемого числа
(абсолютной разницы) будет увеличиваться, и светодиод "Контроль ШИМ" будет
"наращивать" яркость своего "горения".
То же самое будет происходить, если зафиксировать U2, а менять U1.
В случае наличия отрицательного результата операции вычитания, светодиод "Знак
результата" "загорается" при переходе с символа "0" на символ "1" и продолжает
"гореть" при дальнейшем увеличении значения абсолютной разницы (см. ниже.
Выделено красным цветом).
Погашен (+) Горит (-)
… 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5 …
Все остальные результаты операции вычитания, располагающиеся с другой стороны от
символа "0" (включая и его), находятся в области положительных результатов
операции вычитания (выделено синим цветом).
В этом случае, светодиод "Знак результата" "погашен".
При условии подключения, к выходу 2, фильтра нижних частот (выделение аналоговой
составляющей ШИМ-сигнала), и с учетом того, что имеет место быть управляющий
сигнал знака результата (выход 1), получается что-то типа цифрового аналога
дифференциального (разностного) усилителя, с возможностью визуального, точного
контроля числовых значений абсолютной разницы и знака результата операции
вычитания.
Увидев своими глазами результат "верчения" движков переменных резисторов этой
"учебно – тренировочной штуковины" и как следует вдумавшись в происходящее (а как
же без этого?), за один вечер, можно понять больше, чем за месяц плотной работы с
"оторванной от жизни" информацией.
Это устройство достаточно легко можно "превратить" в нечто более изящное, полезное
и востребованное (позже "обкарнаю"), а пока, "куча органов всяческого контроля"
совсем не помешает (как говорится, все для фронта, все для победы).
Вот что у меня получилось:

;********************************************************************************
; Minus_U1.asm Цифровой измеритель разницы уровней напряжения
; (вариант с правым выравниванием результата АЦП)
;--------------------------------------------------------------------------------
; Задействуется модуль АЦП и модуль ССP, работающий в режиме ШИМ.
; Осуществляется вычисление и перевод абсолютной разницы двух напряжений

2
; в длительность импульса, с отображением числового значения абсолютной разницы
; в линейке из 3-х 7-сегментных индикаторов.
; Знак результата вычитания индицируется светодиодом.
; Незначащие нули гасятся в двух десятичных разрядах (кроме младшего).
; Индикация - динамическая.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах"
; (http://ikarab.narod.ru)
; Корабельников Евгений Александрович karabea@lipetsk.ru
;********************************************************************************
; Функции выводов порта А:
; RA0 - вход 1-го канала АЦП,
; RA1 - вход 2-го канала АЦП,
; остальные выводы порта А не задействованы.
; Функции выводов порта В:
; RB0...RB7 - управление секторами A,B,C,D,E,F,H,G.
; Функции выводов порта С:
; RC2 - выход модуля CCP (выход ШИМ),
; RC0, RC1, RC3 - выходы дешифратора,
; RC4 - сигнал знака результата вычитания,
; остальные выводы порта C не задействованы.
; Кварц 4000 Кгц (1 м.ц.= 1 мкс.).
; Опорное напряжение -> Uпит. ПИКа.
; Частота импульсов -> 1000 Гц.
; Используется PIC16F873A.
;----------------------------------------------
; Объем программы: 172 слова в памяти программ.
;================================================================================
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).
;-------------------------------------
; Регистры, обеспечивающие АЦП.
;-------------------------------------
AdresL equ 1Eh ; Регистр младшего байта результата АЦП
; (банк 1).
Adcon0 equ 1Fh ; Регистр настройки модуля АЦП.
Adcon1 equ 1Fh ; Регистр настройки модуля АЦП (банк 1).
;-------------------------------------
; Регистры, обеспечивающие ШИМ.
;-------------------------------------
PIR1 equ 0Ch ; Регистр флагов прерываний
; от периферийных модулей.
T2CON equ 12h ; Регистр управления модулем таймера TMR2.
CCP1CON equ 17h ; Регистр управления модулем CCP.
CCPR1L equ 15h ; Регистр младшего байта CCP.
PR2 equ 12h ; Регистр периода (банк 1).
;================================================================================
; Регистры общего назачения.
;================================================================================
LED0 equ 20h ; Регистр хранения результатов преобразований
; 1-го двоично-десятичного разряда.
LED1 equ 21h ; ------- 2-го -------------------------
LED2 equ 22h ; ------- 3-го -------------------------
3
Index equ 23h ; Счетчик количества малых колец индикации.
Temp equ 24h ; Многофункциональный регистр.
Mem equ 25h ; Регистр оперативной памяти 2/10
; преобразования.
Count equ 26h ; Регистр счетчика.
Temp_1 equ 27h ; Регистр результата 1-го АЦП.
Temp_2 equ 28h ; Регистр результата 2-го АЦП.
Flag equ 29h ; Указатель каналов.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присвоение битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
Z equ 2 ; Флаг нулевого результата.
RP0 equ 5 ; Бит выбора банка.
GO equ 2 ; Бит статуса модуля АЦП.
TMR2IF equ 1 ; Флаг прерывания по переполнению TMR2.
;================================================================================
org 0 ; Начать выполнение программы
; с 0-го адреса PC.
;********************************************************************************

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ.
;********************************************************************************
; Подготовительные операции.
;================================================================================
; Перевод в пассивное состояние всех выходов дешифратора
; (для исключения "мелькания" при включении питания).
;-------------------------------------------------------
bsf PortC,0 ; Предустановка состояний
bsf PortC,1 ; выходов дешифратора
bsf PortC,3 ; RC0, RC1, RC3.
clrf Flag ; Подготовка указателя каналов.
;-------------------------------------------
; Задание длительности периода сигнала ШИМ
; и настройка направлений работы.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisC ; Все выводы порта С работают на выход.
clrf TrisB ; Все выводы порта В работают на выход.
movlw .62 ; Задание длительности
movwf PR2 ; периода (.62).
;-------------------------------------------
; Работа с регистром Adcon1.
;-------------------------------------------
movlw b'10000100' ; Диапазон квантования напряжения от -Vss до
movwf Adcon1 ; + Vdd, AN0,AN1,AN3-аналоговые входы,
; AN2,AN4-цифровые каналы ввода/вывода,
; правое выравнивание.
bcf Status,RP0 ; Переход в 0-й банк.
;------------------------------------------
; Настройка модуля CCP.
;------------------------------------------
movlw b'00001111' ; Включение
movwf CCP1CON ; режима ШИМ.
;------------------------------------------
; Настройка модуля TMR2.
;------------------------------------------
movlw b'00000111' ; TMR2 включен, Кдел.предделителя = 16,
movwf T2CON ; Кдел.выходного делителя = 1.
4
;################################################################################
; Циклическая подпрограмма "оцифровки" уровней аналоговых сигналов,
; присутствующих на выводах RA0, RA1, и перевода результатов этой "оцифровки" в
; длительность импульса.
;################################################################################
; Сначала производится "оцифровка" (задействуется модуль АЦП).
;********************************************************************************
; Работа с регистром Adcon0.
;-------------------------------------------
; 1-й сценарий АЦП.
;-------------------
SNOVA_1 movlw b'01000001' ; Включение модуля АЦП, выбор канала AN0
movwf Adcon0 ; (RA0), источник тактового сигнала Fosc/8,
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.
goto PAUSE ; Обход сценария 2-го АЦП.
;-------------------
; 2-й сценарий АЦП.
;-------------------
SNOVA_2 incf Flag,F ; Flag+1=нечетное число (Flag,0=1).
bsf Adcon0,3 ; Выбор канала AN1 (RA1). Остальные
; настройки Adcon0 не меняются.
;------------------------------------------------
; Задержка для перезаряда конденсатора.
;------------------------------------------------
PAUSE movlw .6 ; Стандартный,
movwf Count ; вычитающий,
decfsz Count,F ; однобайтный
goto $-1 ; счетчик.
;-------------------------------------------
; Начало аналого-цифрового преобразования.
;-------------------------------------------
bsf Adcon0,GO ; Включение преобразования. Конденсатор
; отключается от аналогового входа на время
; преобразования.
;-------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;-------------------------------------------
btfsc Adcon0,GO ; Ожидание окончания аналого-цифрового
goto $-1 ; преобразования.
;----------------------------------------------
; АЦП закончено. Результат - в AdresH/AdresL.
; AdresH не задействуется, т.к. "битность" = 8.
;----------------------------------------------
; Выбор сценария копирования результата.
;-------------------------------------------
btfsc Flag,0 ; Если Flag,0 = 0, то результат 1-го АЦП
goto OBHOD ; копируется в Temp_1, а если = 1, то
; результат 2-го АЦП копируется в Temp_2.
;-------------------------------------------
; Копирование результата в Temp_1.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_1 ; W --> Temp_1.

goto SNOVA_2 ; Переход на начало 2-го АЦП.


;-------------------------------------------
; Копирование результата в Temp_2.
;-------------------------------------------
OBHOD bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
5
movwf Temp_2 ; W --> Temp_2.
;-------------------------------------------
; Теперь модуль АЦП можно выключить.
;-------------------------------------------
clrf Adcon0 ; Для снижения потребляемого устройством тока,
; модуль АЦП выключается до конца отработки
; текущего полного цикла программы.
;---------------------------------------------------------
; ИТОГ: в Temp_1 "лежит" результат 1-го АЦП,
; в Temp_2 "лежит" результат 2-го АЦП.
;================================================================================
; Вычисление абсолютной разницы и определение знака.
;================================================================================
bcf PortC,4 ; "Знаковый" светодиод гасится.
;------------------------------------------
; Temp_2 больше Temp_1 или наоборот ?
;------------------------------------------
movf Temp_1,W ; Temp_2 - Temp_1 = ...
subwf Temp_2,W ; Результат - в W.
btfsc Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "+" или =0.
goto $+3 ; Если "-".
;------------------------
; Temp_2 больше Temp_1
;------------------------
movwf Temp_2 ; Результат вычитания записывается в Temp_2,
goto CCP ; после чего - выход из процедуры вычисления с
; погашенным "знаковым" светодиодом
; (результат "+").
;------------------------
; Temp_1 больше Temp_2
;------------------------
bsf PortC,4 ; "Загорание" светодиода ("-" результат).
movf Temp_2,W ; Temp_1 - Temp_2 = ...
subwf Temp_1,W ; Результат - в W.
movwf Temp_2 ; W --> Temp_2.
;------------------------------------------------------------------------------
; ИТОГ: в обеих случаях, числовое значение абсолютной разницы "лежит" в Temp_2.
;------------------------------------------------------------------------------

;********************************************************************************
; Далее производится перевод абсолютной разницы в длительность импульса
; (задействуется модуль CCP, работающий в режиме ШИМ).
;********************************************************************************
; "Загрузка" результата АЦП, из Temp_2, в CCPR1L/CCP1CON,5,4.
;================================================================================
; Определение момента начала "загрузки" в CCPR1L/CCP1CON,5,4.
;------------------------------------------------------------
CCP bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

btfss PIR1,TMR2IF ; Проверка состояния флага


goto $-1 ; прерывания по переполнению TMR2.
;------------------------------------------------------------
; Сохранение содержимого Temp_2 в Temp (для ПП Bin2_10).
;------------------------------------------------------------
movf Temp_2,W ; Temp_2 --> Temp.
movwf Temp ;
;------------------------------------------------------------
; "Загрузка" Temp_2,1,0 в CCP1CON,5,4 (1-->5, 0-->4).
;------------------------------------------------------------
btfsc Temp_2,1 ;
goto $+3 ; Бит №1 регистра Temp_2
bcf CCP1CON,5 ; копируется в бит №5
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,5 ;

6
btfsc Temp_2,0 ;
goto $+3 ; Бит №0 регистра Temp_2
bcf CCP1CON,4 ; копируется в бит №4
goto $+2 ; регистра CCP1CON.
bsf CCP1CON,4 ;
;------------------------------------------------------------
; "Загрузка" Temp_2,7...2 в CCPR1L,5...0.
;------------------------------------------------------------
rrf Temp_2,F ; Содержимое Temp_2 сдвигается
rrf Temp_2,F ; вправо на 2 бита.

movf Temp_2,W ; Содержимое Temp_2


movwf CCPR1L ; "загружается" в CCPR1L.
;------------------------------------------------------------
; Сброс CCPR1L,7,6.
;------------------------------------------------------------
bcf CCPR1L,6 ; В двух старших разрядах (9 и 10)
bcf CCPR1L,7 ; устанавливаются нули.

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

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

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


clrf LED1 ; -------"------ LED1.
clrf Flag ; -------"------ Flag ("обманный").
;================================================================================
; Циклический сдвиг влево.
;================================================================================
Loop16 rlf Temp,F ; Побитная
rlf Flag,F ; "переправка"
rlf LED0,F ; содержимого
rlf LED1,F ; Flag/Temp
; в LED1/LED0.
decfsz Count,F ; Анализ числа проходов
goto adjDEC ; преобразования.
;================================================================================
; Поразрядное распределение полубайтов регистров LED1 и LED0
; по младшим полубайтам регистров LED2, LED1, LED0.
;================================================================================
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 - после возврата по стеку.
7
;================================================================================
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
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 ;

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

CYCLE bsf PortC,0 ; Предустановка состояний


bsf PortC,1 ; выходов дешифратора
bsf PortC,3 ; RC0, RC1, RC3.
;--------------------------------------------------------------------------------
; Подготовка к косвенной адресации: запись в регистр 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 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,3 ; Сценарий №3. На выводе RC3 выставляется 0.
goto $+4 ; Завершение дешифровки.
D_0 bcf PortC,0 ; На выводе RC0 выставляется 0.
goto $+2 ; Завершение дешифровки.
D_1 bcf PortC,1 ; На выводе RC1 выставляется 0.
;--------------------------------------------------------------------------------
; Группа команд задержки, определяющей время нахождения одного 7-сегментного
; индикатора в активном состоянии (определяющей время прохождения малого кольца
; индикации).
;--------------------------------------------------------------------------------
9
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.
;--------------------------------------------------------------------------------
; Уменьшение на 1 содержимого счетчика количества больших колец индикации Count.
;--------------------------------------------------------------------------------
decfsz Count,F ; Декремент содержимого счетчика количества
; больших колец индикации Count с сохранением
; результата в нем же.
goto CYCLE ; Если результат декремента не=0, то переход
; на новое большое кольцо индикации.
; Если результат декремента =0, то программа
; исполняется далее (переход на новый полный
; цикл динамической индикации).
;--------------------------------------------------------------------------------
; Выход из ПП динамической индикации.
;--------------------------------------------------------------------------------
clrf PortB ; "Гашение" всех сегментов.
goto SNOVA_1 ; Переход на новый цикл преобразования.
;********************************************************************************
end ; Конец программы.

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


Красным цветом выделены "нововведения" (в процедуру АЦП).
Фиолетовым цветом выделено то, что относится к вычислению абсолютной разницы и
определению знака результата вычитания.
Синим цветом выделено то, что относится к формированию ШИМ-сигнала.
Темно – синим цветом выделен "стандартный набор" ПП (2/10 преобразования,
гашения незначащих нулей и динамической индикации).

Подготовка.
С целью обеспечения максимального упрощения программы, я выбрал правое
выравнивание результата АЦП, так как при этом существенно упрощается программная
"конструкция" группы команд вычисления абсолютной разницы и определения знака
результата вычитания.
В случае применения левого выравнивания, эта "конструкция", в части касающейся
вычисления абсолютной разницы, сложнее.
Кроме того, я "привязался" не к 10-битному результату АЦП, а к 8-битному.
В этом случае, можно работать только с AdresL, а про AdresH "забыть", что я и
сделал (даже "прописки лишил и разжаловал в рядовые").

10
С одним байтом гораздо проще работать, чем со "связкой" типа "байт + довесок".
Правда при этом количество градаций сокращается, но во многих случаях, такая
"10-битная страсть" просто не нужна и можно ограничиться количеством градаций в 4
раза меньшим (потеря каждого бита равноценна делению на 2).
Так как я ранее "привязался" к Fшим. = 1000 Гц., то так тому и быть.
С учетом сказанного, использую не верхнюю, а нижнюю строку расчета
(см. PIC – калькулятор: расчет для Fшим = 1 Кгц.).
Значит,
- в регистр периода PR2 записываю число .62
- и выставляю Кдел. предделителя модуля TMR2 = 16.
Количество градаций равно 250 штук.
Ну и ладненько.
Это вполне приличное количество для решения многих, не слишком мудреных, задач.
Fшим, по сравнению с заданной (1000 Гц), уменьшится всего на 8 Гц. (992 Гц).
В данном случае, это не существенно.
Теперь нужно определиться с опросом каналов.
Так как каналов всего два, то и нечего, со стандартным, однобайтным счетчиком,
"огород городить".
Достаточно инкремента (или декремента, или даже операции с битом №0) содержимого
какого-нибудь регистра общего назначения, с последующей проверкой состояния бита
№0 (проверка на четность) и соответствующим, двухсценарным ветвлением.
Под это немудреное дело, "прописываю" регистр с названием Flag.
Теперь нужно определиться с принципом вычисления абсолютной разницы.
Он очень прост.
В начале этой процедуры, производится вычитание, например, типа X – Y = …
Если, после этого, бит С регистра Status установился в 1 (результат положительный
или =0), то результат этого вычитания и будет абсолютной разницей.
Если бит С регистра Status установился в 0 (результат отрицательный), то
производится вычитание типа Y – X = … (то есть, наоборот), и абсолютной разницей
будет результат этого вычитания.
Так как имеется две разновидности вычитания (2 сценария. "Царь" - заем), то
светодиод "Знак результата", на выбор, можно "зажечь" в любом из этих сценариев
(на входе в процедуру, он должен быть погашен).
У меня он "загорается" по факту наличия отрицательного результата, а по факту
наличия положительного результата - не "загорается", но ничто не мешает сделать и
наоборот.
Это кому как нравится.
По этому же принципу, можно вычислить абсолютную разницу двух N-байтных чисел.
И именно этот немудреный принцип лежит в основе работы со знаковыми числами.
Отрицательное число идентифицируется по числовому значению абсолютной
разницы, в "комплекте" с наличием знака отрицательного результата.
Положительное число идентифицируется по числовому значению абсолютной
разницы, в "комплекте" с отсутствием знака отрицательного результата.
Вот и вся премудрость.
По-моему, в этом случае (операции с 8-битными словами), и про "мычание коровы" не
грех упомянуть.
Работа программы.
Работа основной части этой программы "расписана" в предыдущих подразделах.
Остановлюсь на "нововведениях".
1. В состав группы команд "подготовительных операций" добавлена команда clrf Flag.
Она нужна для того чтобы 1-й "виток" полного цикла программы начался с опроса 1-го
канала АЦП, то есть, "для порядка".
Если ее убрать, то ничего плохого не случится, так как, начиная со 2-го "витка" и
далее, эта команда не работает, а сброс содержимого регистра Flag производится в
ПП Bin2_10 (в ней, этот сброс выделен красным цветом).
Это "экзотическое место" я выбрал из соображений рациональности.
Дело в том, что я "нагрузил" на регистр Flag еще и функцию "обманного" регистра (о
необходимости наличия "обманного" регистра говорилось ранее).
Вот так, за один прием, и "убивается 2 зайца" (совмещение двух функций).
11
Какой-никакой, а выигрыш в одну команду имеется.

2. Выбор каналов АЦП производится последовательно, начиная с 1-го (1-й сценарий


АЦП).
……………………………
;################################################################################
; Сначала производится "оцифровка" (задействуется модуль АЦП).
;********************************************************************************
; Работа с регистром Adcon0.
;-------------------------------------------
; 1-й сценарий АЦП.
;-------------------
SNOVA_1 movlw b'01000001' ; Включение модуля АЦП, выбор канала AN0
movwf Adcon0 ; (RA0), источник тактового сигнала Fosc/8,
; состояние ожидания, конденсатор подключен к
; выбранному аналоговому входу и начал
; перезаряжаться.
goto PAUSE ; Обход сценария 2-го АЦП.
;-------------------
; 2-й сценарий АЦП.
;-------------------
SNOVA_2 incf Flag,F ; Flag+1=нечетное число (Flag,0=1).
bsf Adcon0,3 ; Выбор канала AN1 (RA1). Остальные
; настройки Adcon0 не меняются.

А можно и так (см. ниже: выделено серым цветом), но зачем нужна лишняя
команда?
;-------------------
; 2-й сценарий АЦП.
;-------------------
SNOVA_2 incf Flag,F ;
movlw b'01001001' ; То же самое, но для
movwf Adcon0 ; канала AN1 (RA1).

;------------------------------------------------
; Задержка для перезаряда конденсатора.
;------------------------------------------------
PAUSE ------ ------
;------------------------------------------------
; Начало аналого-цифрового преобразования.
;------------------------------------------------
; Ожидание окончания АЦП ("плавающая" задержка).
;------------------------------------------------
; Выбор сценария копирования результата.
;------------------------------------------------
btfsc Flag,0 ; Если Flag,0 = 0, то результат 1-го АЦП
goto OBHOD ; копируется в Temp_1, а если = 1, то
; результат 2-го АЦП копируется в Temp_2.
;-------------------------------------------
; Копирование результата в Temp_1.
;-------------------------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_1 ; W --> Temp_1.

goto SNOVA_2 ; Переход на начало 2-го АЦП.


;-------------------------------------------
; Копирование результата в Temp_2.
;-------------------------------------------
OBHOD bsf Status,RP0 ; Переход в 1-й банк.
movf AdresL,W ; AdresL --> W.
bcf Status,RP0 ; Переход в 0-й банк.
movwf Temp_2 ; W --> Temp_2.

12
;-------------------------------------------
; Выключение модуля АЦП.
;================================================================================
; Вычисление абсолютной разницы и определение знака.
;================================================================================
……………………………
На момент начала полного цикла программы, содержимое регистра Flag всегда
сброшено в ноль (см. команду clrf Flag в ПП Bin2_10).
В начале каждого полного цикла программы, всегда исполняется 1-й сценарий АЦП.
После отработки ПП SNOVA_1, осуществляется обход группы команд 2-го сценария
АЦП (goto PAUSE), после чего отрабатываются "штатная" группа команд.
После выхода из "плавающей" задержки, производится анализ состояния бита №0
регистра Flag.
Естественно, он будет в нуле, так как Flag=0 и обращений к этому регистру не было.
А раз это так, то будет осуществлено копирование результата 1-го АЦП из регистра
AdresL в регистр Temp_1.
Половина дела сделано.
После этого, осуществляется переход на начало исполнения 2-го сценария АЦП
(goto SNOVA_2), и он начинает отрабатываться.
В начале ПП SNOVA_2, с помощью команды incf Flag,F (а можно и decf Flag,F, или
bsf Flag,0) четное число (бит №0=0) "превращается" в нечетное (бит №0=1).
Это необходимо для обеспечения дальнейшего копирования результата 2-го АЦП, из
регистра AdresL, в регистр Temp_2 (а не в Temp_1).
После выхода из "плавающей" задержки, производится анализ состояния бита №0
регистра Flag.
Так как, в этом случае, Flag,0 = 1, то произойдет копирование результата 2-го АЦП из
регистра AdresL в регистр Temp_2.
ИТОГ: в Temp_1 "лежит" результат 1-го АЦП,
в Temp_2 "лежит" результат 2-го АЦП.

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


определение знака результата вычитания.
……………………………
;================================================================================
; Вычисление абсолютной разницы и определение знака.
;================================================================================
bcf PortC,4 ; "Знаковый" светодиод гасится.
;------------------------------------------
; Temp_2 больше Temp_1 или наоборот ?
;------------------------------------------
movf Temp_1,W ; Temp_2 - Temp_1 = ...
subwf Temp_2,W ; Результат - в W.
btfsc Status,C ; Результат "+" или "-" ?
goto $+2 ; Если "+" или =0.
goto $+3 ; Если "-".
;------------------------
; Temp_2 больше Temp_1
;------------------------
movwf Temp_2 ; Результат вычитания записывается в Temp_2,
goto CCP ; после чего - выход из процедуры вычисления с
; погашенным "знаковым" светодиодом
; (результат "+").
;------------------------
; Temp_1 больше Temp_2
;------------------------
bsf PortC,4 ; "Загорание" светодиода ("-" результат).
movf Temp_2,W ; Temp_1 - Temp_2 = ...
subwf Temp_1,W ; Результат - в W.
movwf Temp_2 ; W --> Temp_2.

А можно и так (см. ниже: выделено серым цветом)


bsf PortC,4 ; "Загорание" светодиода ("-" результат).
13
movwf Temp_2 ; Результат вычитания Temp_2 – Temp_1 (лежит
comf Temp_2,F ; в W) "превращается" в результат вычитания
incf Temp_2,F ; Temp_1 – Temp_2 (сохранен в Temp_2).

;------------------------------------------------------------------------------
; ИТОГ: в обеих случаях, числовое значение абсолютной разницы "лежит" в Temp_2.
;********************************************************************************
; Далее производится перевод абсолютной разницы в длительность импульса
; (задействуется модуль CCP, работающий в режиме ШИМ).
;********************************************************************************
CCP ------ ------
……………………………
"Знаковый" светодиод "гасится" (подготовка к работе).
Далее, с целью обеспечения выбора одного из двух сценариев, результат
математической операции Temp_2 – Temp_1 = … , с помощью флага С регистра Status,
анализируется на предмет наличия или отсутствия заема.
Это эквивалентно ответу на вопрос: "Какое из двух чисел больше"? или "Каков
знаковый результат операции вычитания"?
- Если Temp_2 больше Temp_1, то нужно просто скопировать результат ранее
произведенного вычитания, из W (в нем "лежит" абсолютная разница) в Temp_2, и
выйти из процедуры с погашенным "знаковым" светодиодом (он погашен ранее), что и
сделано (goto CCP).
- Если Temp_1 больше Temp_2, то это соответствует отрицательному результату
произведенного ранее вычитания (Temp_2 – Temp_1).
Значит, нужно "зажечь" светодиод, что и сделано (bsf PortC,4).
После этого производится вычитание меньшего числа из большего
(Temp_1 – Temp_2 = абсолютная разница), а результат сохраняется в регистре Temp_2.
В итоге, в любом случае, числовое значение абсолютной разницы "осядет" в регистре
Temp_2.
Примечание: результат абсолютной разницы можно сохранить и в регистре Temp_1, но
после этого нужно скорректировать "нижележащий" текст программы (заменить Temp_2
на Temp_1).

4. Так как имеет место быть 8-битный результат абсолютной разницы, то в


CCPR1L,7,6 "загружать" нечего.
Поэтому соответствующая группа команд "убита".
……………………………
movf Temp_2,W ; Содержимое Temp_2
movwf CCPR1L ; "загружается" в CCPR1L.
;------------------------------------------------------------
; Сброс CCPR1L,7,6.
;------------------------------------------------------------
bcf CCPR1L,6 ; В двух старших разрядах (9 и 10)
bcf CCPR1L,7 ; устанавливаются нули.

bcf PIR1,TMR2IF ; Сброс флага прерывания по переполнению TMR2.

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ГРУППА ПОДПРОГРАММ ПРЕОБРАЗОВАНИЯ 2-БАЙТНЫХ ДВОИЧНЫХ ЧИСЕЛ
; В 3-РАЗРЯДНЫЕ ДЕСЯТИЧНЫЕ ЧИСЛА
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
……………………………
Во избежание "бяк" (а они есть), биты №№7 и 6 регистра CCPR1L сбрасываются в
ноль на каждом "витке" полного цикла программы.

5. А это то, о чем говорилось ранее:


……………………………
;================================================================================
14
Bin2_10 bcf Status,C ; Сброс флага переноса-заема.
movlw .16 ; "Закладка" в регистр Count числа
movwf Count ; проходов преобразования.

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


clrf LED1 ; -------"------ LED1.
clrf Flag ; -------"------ Flag ("обманный").
;================================================================================
; Циклический сдвиг влево.
;================================================================================
Loop16 rlf Temp,F ; Побитная
rlf Flag,F ; "переправка"
rlf LED0,F ; содержимого
rlf LED1,F ; Flag/Temp
; в LED1/LED0.
decfsz Count,F ; Анализ числа проходов
goto adjDEC ; преобразования.
;================================================================================
……………………………
Командой clrf Flag "убиваются 2 зайца" (см. выше), а в регистре Temp сохранено
числовое значение абсолютной разницы.
Оно скопировано в Temp из Temp_2 (см. ПП CCP).

Что получилось?
В данном случае, -Uref = 0 в. (GND), а +Uref = Uпит. ПИКа (см. настройку Adcon1).
В принципе, Uпит. ПИКа может отличаться от 5,12 в., но, "для порядка" ("привязка" к
"шагу квантовки" = 5 мв.), пусть будет 5,12 в.
"Закоротите" R3.
Это обеспечит диапазон регулировки напряжений U1 и U2 от 0 в. до Uпит.
Резисторами R1 и R2 установите U1 = U2 = 0 в.
После этого, на индикацию выведется число "0".
Теперь, внимательно наблюдая за происходящим (спешка не нужна),
- при U1 = 0 в., постепенно увеличьте значение U2 c 0 в. до Uпит. ПИКа,
- и при U2 = 0 в., постепенно увеличьте значение U1 с 0 в. до Uпит. ПИКа.
Вы увидите то, что я постарался отобразить на рис. 2.

В пределах каждой из указанных выше "манипуляций", существует 4 сектора, в


которых, в части касающейся светодиода "Контроль ШИМ" и показаний индикатора,
происходит одно и то же: значения чисел, выводимых на индикацию, увеличиваются от
"0" до "255", и по мере этого увеличения, яркость свечения светодиода "Контроль
ШИМ" также увеличивается.
После числа "255", "наступает катаклизм" (сброс в ноль), после чего все повторяется
снова.
И так ровно 4 раза.
Это Вам ничего не напоминает?

15
Правильно, работа по кольцу "в чистом виде".
Откуда взялось число 4?
А Вы умножьте 256 на 4 и получите "волшебную" цифру 1024.
А теперь "с другого конца".
В данном случае, битность равна 8-ми. Байт способен отобразить 256 состояний.
Количество квантовок 10-разрядного АЦП = 1024.
1024 / 256 = 4.
Это подтверждает ранее сделанный вывод: вне зависимости от чего-либо,
количество квантовок 10-разрядного АЦП всегда равно 1024.
Разбираемся с "чего-либо".
Оно состоит из двух частей.
1. Опорное напряжение.
Любой диапазон опорного напряжения (от -Uref до +Uref) будет "разбит" на те же 1024
части ("проквантован").
Не больше и не меньше. Это "железное" правило.
2. В данном случае, результат АЦП 8-разрядный, но это вовсе не свидетельствует о
том, что само АЦП "превратилось" из 10-разрядного в 8-разрядное.
Оно как было 10-разрядным, так и останется им "до гробовой доски".
Подтверждение этого вывода Вы и видите на рис. 2 (см. "клонирование"/"размножение").
Если результат АЦП будет 7-разрядный, то это "клонирование" (работа по кольцу)
повторится 8 раз, если 9-разрядный, то 2 раза, а если 10-разрядный, то 1 раз.
В последнем случае, "клонирование" отсутствует.
Обращаю Ваше внимание на то, что только что сказанное применимо к любому
значению диапазона опорного напряжения.
Вопрос: "Почему"?
Ответ: см. пункт 1.
А раз это так, то, при разрядности результата АЦП менее 10-ти, и нечего даже
пытаться "бороться с этим клонированием".
От него можно избавиться только в единственном случае - если результат АЦП
10-разрядный.
Не исключено то, что в каких-то случаях, это "клонирование" может даже оказаться
полезным, так что иметь об этом представление нужно (а вдруг пригодится?).
Вопрос: "10-разрядный результат АЦП это конечно прекрасно, но как быть в данном
случае, когда результат АЦП 8-разрядный, и три "клона" нужны так же, "как козе
баян""?
"Расшифровка козы и баяна": с точки зрения обеспечения элементарного порядка в
мыслях, при первичном "въезде", нужно концентрировать внимание исключительно на
"матери" (на 1-м секторе), а не на сопровождающих ее "родственниках". Может быть и
"родственники на что-то сгодятся" (совсем мертвыми их делать не нужно. Дать
снотворное и пусть спят. А чуть что - нашатырь под нос), но это уже вторично.
Ответ: смириться с потерей трех четвертей диапазона Uоп. и использовать ту
четверть, которая "одним своим концом прислонилась" к -Uref.
В данном случае, -Uref = 0 в. (GND, земля, корпус).
Вывод: для того чтобы, при разрядности результата АЦП меньшей 10-ти, обеспечить
максимальный диапазон изменения уровней аналоговых сигналов (в пределах 1-го
сектора), нужно выбрать -Uref = 0 в. и +Uref = Uпит. ПИКа, что и имеет место быть.
В данном случае, речь идет о диапазоне напряжений от 0 в. до 5,12 / 4 = 1,28 в.
Вопрос: "Как на практике провернуть такое дельце"?
Ответ: очень просто. Нужно "загасить" три четверти того, что не нужно ("убить" 3
"клона").
Это же есть ответ на вопрос: "Зачем нужен резистор R3"?
Снимите с него перемычку.
Примечание: с учетом сказанного, номинал R3 нужно
подобрать (на схеме отмечено звездочкой).
Тогда получается то, что Вы видите слева.
Это уже гораздо проще и понятнее.
Имея в наличии такую "точнейшую проверялку истины",
грех не "разогнать муть", связанную с количеством
градаций.
16
Эта "муть" связана с тем, что число 255 больше числа расчетного количества
градаций, которое равно 250.
В связи с этим, возникает вопрос: "Что происходит в диапазоне квантовок от 250 до
255 включительно? А то ведь какой-то черный ящик получается".
Подключив к этой "точнейшей (в буквальном смысле) проверялке истины" осциллограф
(к выводу RC2), можно, с абсолютной точностью, выяснить следующее.
Импульсы максимальной скважности (минимальный коэффициент заполнения)
формируются при выводе на индикацию числа "1".
Импульсы минимальной скважности (максимальный коэффициент заполнения)
формируются при выводе на индикацию числа "251".
Во всех остальных случаях ("0" и от "252" до "255" включительно), импульсы
отсутствуют, и имеет место быть либо уровень логического нуля (показание "0".
Кзаполн. = 0%), либо уровень логической единицы (показание от "252" до "255"
включительно. Кзаполн. = 100%).
Из этого следует то, что серединой диапазона изменения скважности будет квантовка
с номером "где-то в районе" 126.
Это соответствует напряжению Uкв.х126 = 0,005 в. х 126 = 0,63 в. ("грубая прикидка". Это
для того, чтобы была конкретная настройка, от которой можно "плясать").
Напоминание: Uкв. – "шаг" квантования по уровню. В данном случае (Uпит. = 5,12 в.), он
равен 0,005 в.
А теперь выставите U1 = 0,63 в. и U2 = 0 в.
Ввероятнее всего, высветится цифра или "126", или "127".
Немного изменив значение U1, добейтесь того, чтобы высветилась цифра "128".
Теперь "оставьте R1 в покое".
Изменяя сопротивление переменного резистора R2 (увеличивая U2), добейтесь того,
чтобы высветился "0".
Это есть "исходное положение".
В этом положении, на выходе модуля CCP (вывод RC2), импульсов нет (уровень
логического нуля), светодиод "Знак результата" погашен и U1 = U2 = 0,63 в.
Теперь постепенно уменьшайте значение U2.
Как только будет иметь место быть показание "1", зажгется светодиод "Знак
результата", что является признаком отрицательного результата операции U2 – U1.
Он будет гореть от "1" и далее, вплоть до "коротыша с корпусом" (до U2 = 0 в.).
По мере уменьшения U2, значение абсолютной разницы будет увеличиваться.
Соответственно, интенсивность свечения светодиода "Контроль ШИМ" будет также
увеличиваться.
При наличии "коротыша с корпусом" (U2 = 0 в.), высветится число "128" (это то число,
которое было установлено ранее, см. выше).
Теперь, в этом положении, оцените соотношение периода и длительности импульса
(нужен осциллограф). "Подозрительно напоминает меандр".
Вернитесь назад, в "исходное положение" (см. выше).
Теперь постепенно увеличивайте значение U2.
При этом, светодиод "Знак результата" гореть не будет, что является признаком
положительного результата операции U2 – U1.
По мере увеличения U2, значение абсолютной разницы будет увеличиваться.
Соответственно, интенсивность свечения светодиода "Контроль ШИМ" будет также
увеличиваться.
На цифре "127", будет иметь место быть такое же, как и отмеченное ранее,
соотношение периода и длительности импульса ("меандр").
На цифре "128", произойдет выход на следующий "виток" счета, о чем будет
свидетельствовать загорание светодиода "Знак результата".
Это есть не что иное, как начало "подлого клонирования", которое, в данном случае,
совсем не нужно (вспомните про "козу и баян").
Вывод: "Не влезай! Убьет!".
Еще один вывод: в "рабочем секторе" имеет место быть 256 уровней квантования.
"Ба… знакомые все лица" (байт "замаскировался").
А как "состыковать" с этим расчетные 250 градаций?
"Собака здесь порылась в том", что "импульсогубительные квантовки" с номерами
252 … 255 "не востребованы".
17
То есть, в данном случае, "до них просто дело не доходит", ведь востребованы
"квантовки" с номерами от 0 до 128, и не более того.
Это подтверждает и наличие "меандра" (см. выше).
Если замерить напряжение U1 (а оно, в ходе "разборок", скорректировано, см. выше),
то его значение будет немногим более 0,63 вольт.
Почему? Потому, что Uкв.х128 = 0,005 в. х 126 = 0,64 в.
Это уже более точный, чем ранее, расчет.
Реально, с поправкой на погрешность измерительного прибора и шунтирование, так
оно и есть.
Естественно, что можно зафиксировать и уровень напряжения отличный от 0,64 в., но
при этом, в той или иной степени, "нарушится числовая симметрия".
В этом случае, "рабочая область" будет "разбита на 2 зоны" не по "симметричному
принципу", а по "ассиметричному принципу" (возможных вариантов много).
На практике, наиболее востребован "симметричный принцип".
На него и буду ориентироваться.
На рис. 4, Вы видите "разрисовку" сказанного:

Если U2 зафиксировано, а U1 меняется, то получается то, что Вы видите на рис. 5:

18
Разница только в порядке "загорания" светодиода "Знак результата".
Можно ли "модернизировать" это устройство так, чтобы получился "полноценный"
измерительный прибор, измеряющий разницу уровней двух напряжений, с указанием ее
знака?
Вполне можно.
Для этого, после вычисления числового значения абсолютной разницы (перед входом в
ПП Bin2_10), нужно разделить это числовое значение на 2 (один сдвиг вправо), а в
знакоместо младшего, десятичного разряда линейки, выводить либо символ "5" (если,
после сдвига, в бит С "ушла" 1), либо символ "0" (если, после сдвига, в бит С "ушел"
0).
Короче, имеет место быть аналогия с термодатчиками DS… .
В этом случае, трехразрядный результат замера абсолютной разницы будет
индицироваться в милливольтах (запятую выставлять не нужно).
Разрешение будет равно шагу квантования, то есть, 5 мв.
Ширина поддиапазонов измерения (имеются ввиду 2 "разнополярных" поддиапазона)
будет зависеть от значений напряжений.
Если одно из них "симметрично" зафиксировать (см. выше), то можно замерить
положительную и отрицательную разницу напряжений в двух одинаковых (по ширине)
поддиапазонах (от 0 в. до 0,64 в.).
При "асимметричной" фиксации, эта "одинаковость" нарушается, что вовсе не есть
однозначно плохо.
Ответ на вопрос "Что такое хорошо и что такое плохо?" зависит от конкретных
условий и конкретной задачи.
Для того чтобы расширить диапазон замера, можно применить делитель напряжения,
например, с Кдел. = 10, но при этом, разрешение увеличится c 5 мв. до 50 мв. и нужно
будет выставить запятую.

Наиболее сложным для понимания является случай, когда меняются и U1, и U2.
Тем из Вас, кто этим интересуется, рекомендую как следует изучить принцип работы
дифференциального (разностного) усилителя (одна из базовых схем включения
операционного усилителя).
Я же попридержусь "золотого" правила, в соответствии с которым, сначала нужно как
следует разобраться с тем, что попроще.
Можно ли организовать числовую "круговерть" по результатам "оцифровки" уровней,
формируемых тремя, четырьмя или пятью источниками аналоговых сигналов?
А почему бы и нет?
19
"Все в наших мускулистых руках".
В этом случае, при наличии желания, "тренированной извилины" и еще кое-чего,
можно такое "сваять", что от удивления "челюсть отвиснет".
Но такие дела делаются, если в наличии есть конкретная, "жизнеспособная" задумка,
"привязанная" к решению конкретной задачи.
А для того чтобы эта "жизнеспособная" задумка имела место быть, нужно хорошенько
"вьехать" в детали.
Вот такой получается "круговорот воды в природе" или обратная связь, о которой,
кстати, и пойдет речь в следующем подразделе.
Обратная связь это такая "штуковина", качественное "овладение" которой, с моей
точки зрения, образно выражаясь, "превращает ремесленника в мастера".
Ранее, я потихоньку (спешка нужна только при ловле блох, а в таком серьезном и
тонком деле, она совсем не нужна) "капал на мозги" по этому поводу, и буду упорно
"капать" далее, так как повод того стоит.
И еще: модуль АЦП работает "на стыке аналоговой и цифровой техники", обеспечивая
"любовь и согласие между ними".
И это не какой-то "паршивый боярин".
Это целый "царь"!!!
По этой простой причине, любой "правильный" конструктор (кроме конструкторов –
"извращенцев", типа "садомазохистов", "суицидников" и т.п.) не то что должен, а просто
обязан детально "въехать" в работу этого модуля.
Никакого "конкурентоспособного заменителя" модуля АЦП просто нет .
(не отвертишься).
Конечно же, имеют место быть и "дворцовые интриги", и даже "попытки взойти на этот
трон через задние проходы", но при этом всегда нужно помнить о том, что "царь
умен, хитер и крут на расправу": он может и не заметить, и "по головке погладить", и
"на кол посадить".
С такими "субъектами" лучше дружить, и чуть что, так сразу петь "Боже царя храни".
В принципе, он "царь" совсем не плохой (должности соответствует) и этого пения
вполне достоин (без иронии).
Именно по этой причине, лично я, на полном серьезе, отдаю ему дань уважения, и
Вам, во избежание "фатальных мозгозаворотов" и прочих потенциальных
неприятностей, советую сделать то же самое.

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

21