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

5/7.

Переход с 3-проводной физической линии на 2-проводную или о том, что


слово “паразит” не всегда является гнусным.

На этом “чудеса” не заканчиваются.


Оказывается, что DS1820 (и другие DS…) могут работать не только по 3-проводной, но
и по 2-проводной линии.
“Шкурный” интерес совершенно очевиден, и особенно в случаях применения длинной
линии.
Хотя я и ругал разработчиков (ангелы есть только на небесах), но нужно отдать им
должное: в этом направлении, ребята сработали на славу (сдается мне, что к 1-Wire
устройствам “приложили руку” и братья славяне).
В состав датчика они ввели накопительный конденсатор, который “похищает” энергию
из линии DQ в то время, пока на ней выставлена единица (то есть, уровень, величина
которого близка к Uпит.).
Решение поистине талантливо: задача решена при помощи диодной развязки, и
никаких “заумных” коммутаторов.
Так как нормальная работа DS1820 обеспечивается в диапазоне питающих напряжений
от 3 до 5,5 в, то имеет место быть достаточно большое “поле для безошибочного
маневра”, гарантирующее (в пределах этого “поля”) надежную работу “связки мастер –
помощник”.
Такой режим работы (по питанию) называется “паразитным”.
Слово, конечно, гнусное, но в данном случае - со знаком плюс.
Чтобы перейти на “паразитное” питание (на 2-проводную линию), нужно физически
соединить между собой 1-й и 3-й вывод DS1820.
Отвод от этой точки соединения будет “земляной проволочиной”.
Отвод от 2-го вывода DS1820 будет “сигнальной проволочиной”.
Вот как это выглядит в приложении к одному датчику:

Еще раз напоминаю (см. “Самоучитель…”), что полярность подключения


питания у других типов ЖКИ может быть противоположна.

После этого, нужно скорректировать текст программы.


Разговор об этом будет ниже, а пока расскажу о “базе”.
В соответствии со сказанным выше, заряд накопительного конденсатора будет
происходить через внешний подтягивающий резистор всякий раз, когда на линии DQ
будет “стоять” единица.

1
Когда DS1820 принимает или передает единицу, то это не приводит к сколь-либо
существенному влиянию на “штатные” процессы заряда или разряда накопительного
конденсатора, так как, в этих случаях, с обеих сторон, линия DQ нагружена на
высокие сопротивления соответствующих выводов “мастера” и “помощника”.
Конечно же, какое-то влияние есть, но оно настолько мизерно, что им можно
пренебречь.
С учетом этого, постоянная времени заряда накопительного конденсатора будет
определяться его емкостью и номиналом внешнего подтягивающего резистора.
Емкость накопительного конденсатора можно считать фиксированной (ее не изменишь),
а вот с номиналом внешнего, подтягивающего резистора “поиграть” можно.
Далее возникает закономерный вопрос: “Что нужно сделать для того чтобы, в процессе
работы устройства, напряжение на накопительном конденсаторе не опускалось ниже
3 вольт”?
Примитивный ответ: периодически его подзаряжать и не допускать “глубокого” разряда.
Вопрос: “Что сие означает”?
Чтобы ответить на этот вопрос, нужно разобраться с энергопотреблением в ходе
исполнения тех или иных процедур.
Больше всего энергии потребляется в ходе исполнения процедуры преобразования
температуры.
В этом случае, максимальное значение тока разряда накопительного конденсатора
может достигать 1,5 ма.
Соответственно, при заряде, также нужно ориентироваться на это значение.
Повышенное энергопотребление (но меньше, чем в первом случае) наблюдается также
в ходе исполнения процедуры записи байтов в EEPROM память DS1820, но эта
процедура “ушла” во вспомогательное устройство и ее можно “сбросить со счета”.
Остальное - “мелочь пузатая”.
Итак, все упирается в процедуру преобразования температуры.
Указанная выше цифра (1,5 ма) “выдана на гора” разработчиками, а все разработчики,
как известно, большие любители перестраховок (и это вполне естественно).
Реально же, эта цифра меньше.
Практический пример.
Если взять за основу значение максимального тока 1,5 ма, то номинал подтягивающего
резистора должен быть не более 5 в : 0,0015 А = 3,33…Ком.
Я не стал менять номинал подтягивающего резистора и оставил его равным 4,7 Ком.
Устройство прекрасно работает.
Напоминаю, что речь идет о работе с одним датчиком.
Вот что получается из “материнской” программы DS1820.asm, при переводе ее с
3-проводной на 2-проводную линию:

;********************************************************************************
; DS1820_3.asm ЭЛЕКТРОННЫЙ ТЕРМОМЕТР НА ОСНОВЕ ДАТЧИКА ТЕМПЕРАТУРЫ DS1820
; М/контроллер и DS1820 работают по интерфейсу 1-Wire.
; Работа с одним датчиком и "паразитным" питанием.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах".
; Эта программа входит в состав 5-го раздела.
; Авторы: Alberto Rolando Senelyuk (Argentina),
; Корабельников Евгений Александрович (Русь-матушка)
; http://ikarab.narod.ru karabea@lipetsk.ru
;********************************************************************************
; Используется м/контроллер PIC16F84A. Частота кварца 4 Мгц.
; Сигнальный вывод (DQ) датчика DS1820 подключается к выводу RA4.
; Между выводом RA4 и шиной питания подключается подтягивающий резистор
; номиналом 4,7-5,1 кОм.
; DS1820 включается по схеме с "паразитным" питанием, т.е.:
; выводы 1 и 3 соединяются - общий провод,
; вывод 2 - сигнальный провод.
; Информация выводится в русифицированный ЖКИ модуль 16х2 на
; основе м/к HD44780 (по 4-разрядному интерфейсу).
; Функции выводов порта А:
; RA0 - RW (ЖКИ),

2
; RA1 - RS (ЖКИ),
; RA2 - E (ЖКИ),
; RA4 - вывод DQ датчика DS1820.
;-------------------------------
; Объем программы: 244 команды.
;================================================================================
LIST p=16F84a ; Используется м/контроллер PIC16F84A.
__CONFIG 03FF1H ; Бит защиты выключен, WDT выключен,
; XT-генератор.
;================================================================================
; Определение положения регистров специального назначения.
;================================================================================
IndF equ 00h ; Доступ к памяти через FSR.
PC equ 02h ; Счетчик команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.
PortA equ 05h ; Регистр Port A.
TrisA equ 05h ; Регистр Tris A-банк1.
PortB equ 06h ; Регистр Port B.
TrisB equ 06h ; Регистр Tris B-банк1.
;================================================================================
; Определение названия и положения регистров общего назачения.
;================================================================================
N equ 0Ch ; Счетчик битов.
Temp equ 0Dh ; Многофункциональный регистр временного
; хранения.
Temp_MSB equ 0Eh ; Байт знака температуры (старший байт).
Temp_LSB equ 0Fh ; Байт значения температуры (младший байт).
Flag equ 10h ; Регистр флагов.
Count equ 11h ; Многофункциональный счетчик.
LED0 equ 12h ; Регистры двоично-десятичного
LED1 equ 14h ; преобразования.
Reg_1 equ 15h ; Регистр младшего разряда счетчика.
Reg_2 equ 16h ; Регистр среднего разряда счетчика.
Reg_3 equ 17h ; Регистр старшего разряда счетчика.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присваивание битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
RP0 equ 5 ; Бит выбора банка.
DQ equ 4 ; Бит порта A для управления DS1820.
RW equ 0 ; Бит №0 регистра PortA (вывод RA0 - линия RW)
RS equ 1 ; Бит №1 регистра PortA (вывод RA1 - линия RS)
E equ 2 ; Бит №2 регистра PortA (вывод RA2 - линия E)
BF equ 7 ; Бит №7 регистра PortB.
;================================================================================
org 0 ; Начать выполнение программы
goto START ; с подпрограммы START.
;********************************************************************************

;********************************************************************************
; ----------------------- "РАБОЧАЯ" ЧАСТЬ ПРОГРАММЫ ----------------------
;********************************************************************************
; "Рабочая" инициализация ЖКИ модуля.
;================================================================================
LCD_INIT movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
3
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.

movlw b'00001100' ; Установка: дисплей включен, видимое


; отображение курсора выключено.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00001100.
;----> Возврат по стеку из ПП ENTER_BF.

movlw b'00000001' ; Установка: очистка дисплея со сбросом


; данных, установка курсора в начало 1-й
; строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00000001.
;----> Возврат по стеку из ПП ENTER_BF.

return ; Возврат по стеку на начало вывода символов


; в 1-ю строку.
;================================================================================
; ПП "плавающей" задержки на основе анализа состояния флага занятости BF
; (вариант для 4-разрядного интерфейса).
;================================================================================
ENTER_BF movwf Temp ; Переправка старшего п/байта регистра W на
movwf PortB ; линии RB4...7.
;------------------------------------------
; Запуск в работу старшего п/байта (строб).
;------------------------------------------
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortA,E ; Установка на линии Е "0".
;------------------------------------------
swapf Temp,W ; Смена п/байтов с сохранением результата
; операции в W.
movwf PortB ; Переправка младшего п/байта регистра W на
; линии RB4...7.
;------------------------------------------
; Запуск в работу младшего п/байта (строб).
;------------------------------------------
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortA,E ; Установка на линии Е "0".
;-------------------------------------------------
; Проверка состояния флага занятости BF.
;-------------------------------------------------
; Подготовка к проверке.
;------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'11110000' ; Запись в W "11110000"
movwf TrisB ; RB4...7 работают на вход, а RB0...3
; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.

bcf PortA,RS ; Установка на линии RS "0" (режим команд).


bsf PortA,RW ; Линия RW в "1" (режим чтения данных).
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на лини Е "1".
POVTOR nop ; Задержка в 1 м.ц.
;-----------------------
; Сама проверка.
;-----------------------
btfsc PortB,BF ; Проверка состояния флага занятости BF.
4
goto POVTOR ; Если BF=1, то продолжение задержки до тех
; пор, пока BF не установится в "0" (программа
; исполняется далее).
;-----------------------
; Завершение процедуры.
;-----------------------
clrf PortA ; Сброс в "0" всех защелок порта А
; (RW=0, RS=0, E=0).
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы порта В работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.

return ; Возврат по стеку.


;********************************************************************************

;********************************************************************************
; Подпрограмма вывода на индикацию.
;********************************************************************************
; Выбор 6-го слева знакоместа 2-й строки.
;----------------------------------------------------------
DISPLAY movlw b'11000101' ; Выбор ячейки DD RAM с адресом 45h, что
; соответствует установке курсора в 6-е слева
; знакоместо 2-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 11000101.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Определение и вывод на индикацию знака температуры (+/-).
;----------------------------------------------------------
btfsc Temp_MSB,0 ; В бите №0 старшего байта температуры 0или1 ?
goto MINUS ; Если 1, то переход в ПП MINUS.
movlw 2Bh ; Если 0, то на индикацию
bsf PortA,RS ; выводится символ "+".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto SDVIG ; После вывода на индикацию символа "+",
; переход на обработку младшего байта
; температуры.
MINUS movlw 2Dh ; На индикацию выводится
bsf PortA,RS ; символ "-".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Перевод двоичного числа младшего байта температуры
; из отрицательной области температур в положительную.
;----------------------------------------------------------
comf Temp_LSB,F ; После вывода на индикацию символа "-", все
incf Temp_LSB,F ; биты младшего байта температуры
; инвертируются и к результату прибавляется 1.
;================================================================================
; Подпрограмма обработки содержимого младшего байта температуры.
;================================================================================
; Деление числа, записанного в младшем байте температуры, на 2
; и запись, в бит №0 регистра Flag, признака символов "0" или "5".
;--------------------------------------------------------------------------------
SDVIG clrf Flag ; Flag=0 (подготовка к работе).
rrf Temp_LSB,F ; Деление на 2.
btfsc Status,C ; В бите С 0 или 1 ?
bsf Flag,0 ; Если С=1, то в бит №0 регистра Flag
; записывается 1 (признак символа "5").
; Если С=0, то в бите №0 регистра Flag так и
; останется "лежать" 0 (признак символа "0"),
; и программа будет исполняться далее.
;--------------------------------------------------------------------------------
5
; Установка (или нет) признака добавления (к показаниям) символа "1"
; (признак устанавливается при температуре от 100 градусов и выше).
;--------------------------------------------------------------------------------
movlw .100 ;
subwf Temp_LSB,W ; Temp_LSB - .100 = ? Результат - в W.
btfss Status,C ; Результат положительный или отрицательный?
goto BIN2_10 ; Если отрицательный, то признак добавления
; символа "1" не устанавливается
; (бит №7 регистра Flag=0).
bsf Flag,7 ; Если положительный, то устанавливается
; (бит №7 регистра Flag=1).
;********************************************************************************
; Подпрограмма двоично-десятичного преобразования (для двух десятичных чисел).
;********************************************************************************
BIN2_10 bcf Status,C ; Сброс флага переноса-заема.
movlw .8 ; Запись в регистр Count числа
movwf Count ; проходов преобразования.
clrf LED0 ; Сброс регистра LED0.
;--------------------------------------------------------------------------------
; Циклический сдвиг влево через бит С регистра Status.
;--------------------------------------------------------------------------------
LOOP_16 rlf Temp_LSB,F ; Циклический сдвиг влево содержимого
; регистра Temp_LSB.
rlf LED0,F ; Циклический сдвиг влево содержимого
; регистра LED0.
decfsz Count,F ; Декремент содержимого регистра Count,
; с сохранением результата в нем же.
goto adjDEC ; Если результат не = 0, то переход в ПП
; adjDEC, а если = 0, то программа
; исполняется далее.
;--------------------------------------------------------------------------------
; Порязрядное распределение полубайтов.
;--------------------------------------------------------------------------------
swapf LED0,W ; Запись старшего полубайта LED0
andlw 0Fh ; в младший полубайт LED1
movwf LED1 ;

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


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

goto ASC ; Переход в ПП ASC.


;--------------------------------------------------------------------------------
; Запись в регистр FSR адреса регистра LED0 для дальнейшей косвенной адресации
; к нему в ПП adjBCD.
;--------------------------------------------------------------------------------
adjDEC movlw LED0 ; Запись в регистр FSR адреса регистра LED0
movwf FSR ; с дальнейшим переходом в ПП adjBCD.
call adjBCD ;
;---> Возврат по стеку из ПП adjBCD.
goto LOOP_16 ; Переход на следующее кольцо числовых
; преобразований.
;--------------------------------------------------------------------------------
; Основные операции преобразования двоичных чисел в двоично-десятичные.
;--------------------------------------------------------------------------------
adjBCD clrwdt ; Сброс сторожевого таймера WDT.
movlw 3 ; Суммирование содержимого текущего LED
addwf 0,W ; (LED0...3) с числом 03h, с записью
; результата операции, через регистр W,
movwf Temp ; в регистр Temp.
btfsc Temp,3 ; Анализ состояния бита №3 регистра Temp.
movwf 0 ; Если бит №3 = 1, то содержимое регистра Temp
; копируется в текущий LED.
movlw 30 ; Если бит №3 = 0, то содержимое текущего LED
addwf 0,W ; складывается с константой 30h, с записью
movwf Temp ; результата операции, через регистр W, в
6
; регистр Temp.
btfsc Temp,7 ; Анализ состояние бита №7 регистра Temp.
movwf 0 ; Если бит №7 = 1, то содержимое регистра Temp
; копируется в текущий LED.
retlw 0 ; Если бит №7 = 0, то регистр W очищается и
; происходит возврат по стеку в ПП adjDEC.
;********************************************************************************
; Процедура преобразования кода.
;================================================================================
ASC movlw 30h ; Запись в регистр W числа 30h.
iorwf LED0,F ; Логическое "ИЛИ" содержимого регистра W и
; регистра LED0 с сохранением результата в
; LED0.
iorwf LED1,F ; То же самое для LED1.
;********************************************************************************
; Вывод на индикацию результата измерения.
;********************************************************************************
; Вывод (или нет) на индикацию символа "1" (выводится при Т=100 градусов и выше).
;================================================================================
btfss Flag,7 ; Бит №7 регистра Flag =0 или =1 ?
goto C_00_99 ; Если =0, то символ "1" на индикацию не
; выводится.
movlw 31h ; Если =1, то символ "1" (31h)
bsf PortA,RS ; на индикацию выводится.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Вывод на индикацию двух символов результата измерения
; (в диапазоне от 00 до 99 градусов).
;================================================================================
C_00_99 movf LED1,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED1.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movf LED0,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED0.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Вывод на индикацию пары символов ",0" или ",5".
;================================================================================
movlw 2Ch ; Вывод на индикацию
bsf PortA,RS ; символа "," (2Ch).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
btfsc Flag,0 ; Бит №0 регистра Flag =0 или =1 ?
goto _5 ; Если =1, то далее (goto _5), на
; индикацию будет выведен символ "5".
movlw 30h ; Если =0, то на индикацию
bsf PortA,RS ; выводится символ "0" (30h).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.

_5 movlw 35h ; Вывод на индикацию


bsf PortA,RS ; символа "5" (35h).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;********************************************************************************
7
;================================================================================
; Подпрограмма табличного вычисляемого перехода.
;================================================================================
TEXT addwf PC,F ; Приращение PC на величину содержимого W.
retlw 0x20 ; "пусто"
retlw 0x20 ; "пусто"
retlw 0x54 ; "T"
retlw 0x45 ; "E"
retlw 0x4D ; "M"
retlw 0xA8 ; "П"
retlw 0x45 ; "E"
retlw 0x50 ; "P"
retlw 0x41 ; "A"
retlw 0x54 ; "T"
retlw 0xA9 ; "У"
retlw 0x50 ; "P"
retlw 0x41 ; "A"
retlw 0x3A ; ":"
retlw 0x20 ; "пусто"
retlw 0x20 ; "пусто"
;================================================================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ
;********************************************************************************
START clrf PortA ; Сброс всех защелок порта А.
clrf PortB ; Сброс всех защелок порта В.
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisA ; Все выводы портов А и В
clrf TrisB ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
call LCD_INIT ; Условный переход в процедуру "рабочей"
; инициализации.
;----> Возврат по стеку из ПП LCD_INIT.
;------------------------------
; Вывод символов в 1-ю строку.
;------------------------------
movlw .16 ; Запись числа .16 (количества выводимых в
movwf Count ; строку символов) в регистр Count.
WR_1 movf Count,W ; Копирование содержимого регистра Count в W.
sublw .16 ; .16-Count=... (результат записывается в W).
call TEXT ; Условный переход в ПП TEXT.
;----> Возврат по стеку из ПП TEXT.
bsf PortA,RS ; Вывод на индикацию текущего символа.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
decfsz Count,F ; Подготовка к выводу на индикацию
; следующего символа таблицы.
goto WR_1 ; Если результат декремента не=0, то переход
; в ПП WR_1.
; Если результат декремента =0, то программа
; исполняется далее.
;################################################################################
; Начало работы с датчиком DS1820.
;################################################################################
; Инициализация DS1820.
;--------------------------------------------------------------------------------
SNOVA call DQ_INIT ; Инициализация DS1820.
;----> Возврат по стеку из ПП DQ_INIT.
;--------------------------------------------------------------------------------
; Команда Skip ROM (CCh).
; Команда пропуска процедуры сравнения серийного номера. Применяется в случае
; использования одного датчика (как в данном случае).

8
;--------------------------------------------------------------------------------
movlw 0CCh ; Запись команды CCh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;--------------------------------------------------------------------------------
; Команда Convert T (44h).
; Эта команда запускает процесс преобразования температуры. В течение времени ее
; исполнения, DS1820 не реагирует на команды "мастера".
; Это время нужно просто переждать.
;--------------------------------------------------------------------------------
movlw 44h ; Запись команды 44h
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;********************************************************************************
; Ожидание завершения процесса преобразования температуры:
; задержка 700 мс.
;********************************************************************************
movlw .18 ;
movwf Reg_1 ;
movlw .142 ;
movwf Reg_2 ;
movlw .4 ;
movwf Reg_3 ;

WR decfsz Reg_1,F ;
goto WR ; Стандартный,
decfsz Reg_2,F ; 3-разрядный,
goto WR ; вычитающий
decfsz Reg_3,F ; счетчик.
goto WR ;
;--------------------------------------------------------------------------------
; Инициализация DS1820.
;--------------------------------------------------------------------------------
call DQ_INIT ; Инициализация DS1820.
;----> Возврат по стеку из ПП DQ_INIT.
;--------------------------------------------------------------------------------
; Еще одна команда Skip ROM (CCh).
;--------------------------------------------------------------------------------
movlw 0CCh ; Запись команды CCh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;--------------------------------------------------------------------------------
; Команда Read Scratchpad (BEh).
; Чтение содержимого блокнотной памяти в части касающейся байтов температуры.
;--------------------------------------------------------------------------------
movlw 0BEh ; Запись команды BEh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.

call IN_BYTE ; Чтение младшего байта температуры.


;----> Возврат по стеку из ПП IN_BYTE.
movwf Temp_LSB ; Запись принятого байта в регистр Temp_LSB.

call IN_BYTE ; Чтение старшего байта температуры.


;----> Возврат по стеку из ПП IN_BYTE.
movwf Temp_MSB ; Запись принятого байта в регистр Temp_MSB.
;---------------------------------------------------
; Итог; в Temp_MSB записан старший байт температуры,
; а в Temp_LSB записан младший байт температуры.
;---------------------------------------------------
call DISPLAY ; Переход в ПП вывода результата измерения

9
; на индикацию.
;----> Возврат по стеку из ПП DISPLAY.
goto SNOVA ; Переход на новый цикл измерения.
;********************************************************************************

;================================================================================
; Подпрограмма нициализации 1-Wire устройства (DS1820).
;================================================================================
DQ_INIT call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
call PIN_LO ; Установка на линии нуля.
;----> Возврат по стеку из ПП PIN_LO.
movlw .60 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
movlw .60 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
return ; Возврат по стеку.
;********************************************************************************
; Подпрограмма задержки.
;================================================================================
; Задание количества проходов по 10 мкс.
;----------------------------------------
PAUSE_X movwf Count ; Копирование количества проходов из W в Count
;----------------------------------------
; Пауза в 10 мкс.
;----------------------------------------
PAUSE_10 nop ;
goto $+1 ; Одноразрядный,
goto $+1 ; вычитающий
goto $+1 ; счетчик
decfsz Count,F ; с "врезкой".
goto PAUSE_10 ;
return ; Возврат по стеку.
;================================================================================

;********************************************************************************
; Базовые процедуры чтения/записи по 1-Wire протоколу.
;********************************************************************************
; Подпрограмма передачи "мастером" байта: цикл передачи бита начинается импульсом
; низкого уровня длительностью 1...15 мкс, далее следует передаваемый бит.
; Цикл завершается импульсом высокого уровня длительностью не менее 1 мкс.
;================================================================================
OUT_BYTE movlw .8 ; Запись количества бит передаваемого
movwf N ; байта в регистр N.

METKA_1 rrf Temp,F ; Сдвиг вправо содержимого передаваемого


; байта.
btfss Status,C ; В бите С "лежит" 0 или 1 ?
goto OUT_0 ; Если С=0, то переход в ПП передачи нуля.
goto OUT_1 ; Если С=1, то переход в ПП передачи единицы.

METKA_2 decfsz N,F ; Уменьшение на 1 содержимого счетчика битов.


goto METKA_1 ; Если результат не =0, то переход на метку
; METKA_1.
return ; Если результат =0, то возврат по стеку.
10
;================================================================================
; Подпрограмма приема "мастером" байта: цикл приема бита начинается импульсом
; низкого уровня длительностью 1...15 мкс, после чего DS1820 выставляет на
линии ; бит. Цикл завершается импульсом высокого уровня длительностью не менее 1
мкс.
;================================================================================
IN_BYTE movlw .8 ; Запись количества бит принимаемого
movwf N ; байта в регистр N.
clrf Temp ; Очистка регистра принимаемого байта.

IN_BYTE_1 call PIN_LO ; Формирование на линии уровня 0.


;----> Возврат по стеку из ПП PIN_LO.

call PIN_HI ; Формирование на линии уровня 1.


;----> Возврат по стеку из ПП PIN_HI.
nop ; Калибровочный NOP.
;-------------------------------------------------------------------
; Запись, в бит С, уровня текущего бита, выдаваемого DS1820 в линию.
;-------------------------------------------------------------------
btfss PortA,DQ ; На линии 0 или 1 ?
bcf Status,C ; Если на линии 0, то в бите С выставляется 0
btfsc PortA,DQ ; Если на линии 1 (а также после исполнения
; предыдущей команды), то еще одна проверка
; состояния линии.
bsf Status,C ; Если на линии 1, то в бите С выставляется 1
; Если на линии 0 (а также после исполнения
; предыдущей команды), то программа
; исполняется далее.
;-------------------------------------------------------------------
; Последовательное заполнение битами регистра Temp.
;-------------------------------------------------------------------
rrf Temp,F ; Сдвиг содержимого регистра Temp вправо
; (через C).
movlw .4 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=4х10=40мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
decfsz N,F ; Уменьшение на 1 содержимого счетчика битов.
goto IN_BYTE_1 ; Если результат не=0, то переход
; на прием следующего бита.
movf Temp,W ; Если =0, то копирование принятого байта
; в регистр W.
return ; Возврат по стеку.
;================================================================================
; Подпрограмма передачи бита с уровнем "0".
;================================================================================
OUT_0 call PIN_LO ; Переход в ПП установки уровня 0.
; Начало передачи.
;----> Возврат по стеку из ПП PIN_LO.
movlw .6 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=6х10=60мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
call PIN_HI ; Переход в ПП установки уровня 1.
; Конец передачи.
;----> Возврат по стеку из ПП PIN_HI.
goto METKA_2 ; Переход на исполнение процедуры декремента
; и анализа содержимого счетчика битов.
;================================================================================
; Подпрограмма передачи бита с уровнем "1".
;================================================================================
OUT_1 call PIN_LO ; Переход в ПП установки уровня 0.
; Начало передачи.
;----> Возврат по стеку из ПП PIN_LO.
call PIN_HI ; Переход в ПП установки уровня 1.
; (передача 1).
11
;----> Возврат по стеку из ПП PIN_HI.
movlw .6 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=6х10=60мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
goto METKA_2 ; Переход на новый цикл передачи бита.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "1" за счет подтягивающего резистора
;--------------------------------------------------------------------------------
PIN_HI bsf Status,RP0 ; Переход в банк 1.
bsf TrisA,DQ ; Настройка вывода RA4 на работу "на вход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "0" средствами микроконтроллера
;--------------------------------------------------------------------------------
PIN_LO bcf PortA,DQ ; Установка 0 на выходе защелки вывода RA4.
bsf Status,RP0 ; Переход в банк 1.
bcf TrisA,DQ ; Настройка вывода RA4 на работу "на выход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;********************************************************************************
end ; Конец программы.

В “рабочей” части программы DS1820_3.asm, темно – синим цветом выделена та ее


часть, которая, по сравнению с программой DS1820.asm, не притерпела изменений, а
черным цветом выделен предмет разговора.
Обратите внимание на то, что “плавающая” задержка (ПП WAIT) заменена на
фиксированную.
Если Вы ранее разобрались с принципом работы ПП WAIT, то без труда поймете, в
чем здесь “собака порылась”: в течение почти всего времени работы ПП WAIT,
DS1820 выставляет на линии DQ ноль, что, как сами понимаете, противоположно
требуему.
По этой причине, датчик, в связи с “глубоким” разрядом накопительного конденсатора,
просто не будет работать.
Вывод: при организации “паразитного” питания, “пережидание” отработки процедуры
преобразования температуры нужно производить только с помощью фиксированной
задержки.
В этом случае, все “шито – крыто” и “мин нет”.
Теперь о величине фиксированной задержки.
Мои опытные данные: варианты задержек величиной 0,5 c. и менее не прошли.
“Маловата кольчужка” оказалась (“высвечивается” +85,0 и никаких “телодвижений”).
А вот вариант задержки величиной 0,6 c. прошел.
Для надежности (перестраховка от возможных разбросов), я “влепил” в текст
программы фиксированную задержку величиной 0,7 c.
Вот, собственно говоря, и вся совсем не сложная суть.
Объяснять больше нечего.
Поехали дальше.
А если датчиков 2, 3 или более?
Ведь процесс преобразования температуры это “оптовый” процесс, и запускается он
сразу во всех датчиках, подключенных к линии DQ.
Естественно, суммарный ток разрядов накопительных конденсаторов увеличится кратно,
и для “восполнения этих потерь” нужно соответствующим образом увеличить
суммарный ток их зарядов, что означает значительное уменьшение номинала
подтягивающего резистора.
Если количество датчиков более трех - четырех, то номинал подтягивающего резистора
становится недопустимо низким, чего допустить нельзя.
Я слегка поэкспериментировал с теми двумя датчиками, которые у меня есть (глубоко
не рыл: омы “не ловил”) и получается, что внешний, подтягивающий резистор
номиналом 4,7 Ком два датчика уже “не тянет” (в обеих показаниях “высвечиваются” те
же самые +85,0 и никаких “телодвижений”).
12
Но стоит только подключить (в параллель подтягивающему) еще один резистор
номиналом 4,7 Ком (Rподт. = 2,35 Ком), как термометр начинает работать нормально.
Это и подтверждает сказанное выше.
В принципе, уменьшая номинал подтягивающего резистора, можно запитать 3 датчика,
а может быть даже и 4 (если бы было такое количество, то проверил), но это
“счастье” не бесконечно, так как ниже номинала в 1,5 Ком опускаться не
рекомендуется (могут быть проблемы).
Как “извернуться”? А вот так:

Примечание: естественно, “форсажный” транзистор может быть использован и при


работе с одним датчиком.
Принцип очень простой: транзистор (я его назвал “форсажным”, так как этим словом
объясняется его функция) все время закрыт, за исключением времени исполнения
процедуры преобразования температуры.
В начале “пережидающей” задержки (той, которая после команды Convert T), он
открывается и коммутирует +5в на линию DQ, что с запасом обеспечивает
необходимую величину суммарного тока заряда всех накопительных конденсаторов
большого количества датчиков.
После окончания этого “перекура”, транзистор закрывается и работа происходит
обычным образом.
Дешево и сердито, и особенно с учетом того, что я использовал транзистор, цена
которому - копейка.
Можно использовать и другой тип p-n-p транзистора.
Вообще-то, разработчики, в качестве активного ключа, рекомендуют использовать
MOSFET транзистор, но я сработал по-старинке.
Единственное неудобство - нужно подбирать номинал резистора R4 (я пометил его
звездочкой).
Это связано с тем, что остаточное напряжение нулевого уровня его открывает, а это
есть “Гитлер капут” (никаких дымов не будет и ничто в железе “не даст дуба”, просто
термометр не будет работать).
Значит нужно “задавить” эту остаточную “напругу”, что и делается при помощи
резистора R4.
Его номинал сильно зависит от коэффициента усиления по току применяемого
транзистора, так что этот номинал придется подбирать.
Начинайте где-то с 4,7 - 5,1 Ком и постепенно увеличивайте этот номинал до тех пор,
пока устройство нормально не заработает.
Потом еще “накиньте” процентов 20 – 30 сверху (от “пограничного” уровня) и можете
быть спокойны.
13
Можно также “зайти и с другого конца”.
Вот что получается из “материнской” программы DS1820_2.asm, при переводе ее с
3-проводной на 2-проводную линию и использовании “форсажного” транзистора:
;********************************************************************************
; DS1820_4.asm ЭЛЕКТРОННЫЙ ТЕРМОМЕТР НА ОСНОВЕ ДАТЧИКОВ ТЕМПЕРАТУРЫ DS1820
; М/контроллер и DS1820 работают по интерфейсу 1-Wire.
; Работа с двумя датчиками, вычислением контрольной суммы,
; температурными порогами, учетом импульса присутствия и "паразитным"
; питанием (с использованием "форсажного" транзистора).
; Количество датчиков можно увеличить.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах".
; Эта программа входит в состав 5-го раздела.
; Авторы: Alberto Rolando Senelyuk (Argentina),
; Корабельников Евгений Александрович (Русь-матушка)
; http://ikarab.narod.ru karabea@lipetsk.ru
;********************************************************************************
; Используется м/контроллер PIC16F84A. Частота кварца 4 Мгц.
; Сигнальный вывод (DQ) датчика DS1820 подключается к выводу RA4.
; Между выводом RA4 и шиной питания подключается подтягивающий резистор
; номиналом 4,7-5,1 кОм.
; DS1820 включается по схеме с "паразитным" питанием, т.е.:
; выводы 1 и 3 соединяются - общий провод,
; вывод 2 - сигнальный провод.
; Используется "форсажный" транзистор.
; Информация выводится в русифицированный ЖКИ модуль 16х2 на
; основе м/к HD44780 (по 4-разрядному интерфейсу).
; Функции выводов порта А:
; RA0 - RW (ЖКИ),
; RA1 - RS (ЖКИ),
; RA2 - E (ЖКИ),
; RA4 - вывод DQ датчика DS1820.
;-------------------------------
; Объем программы: 395 команд.
;================================================================================
LIST p=16F84a ; Используется м/контроллер PIC16F84A.
__CONFIG 03FF1H ; Бит защиты выключен, WDT выключен,
; XT-генератор.
;================================================================================
; Определение положения регистров специального назначения.
;================================================================================
IndF equ 00h ; Доступ к памяти через FSR.
PC equ 02h ; Счетчик команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.
PortA equ 05h ; Регистр Port A.
TrisA equ 05h ; Регистр Tris A-банк1.
PortB equ 06h ; Регистр Port B.
TrisB equ 06h ; Регистр Tris B-банк1.
IntCon equ 0Bh ; Регистр IntCon.
;================================================================================
; Определение названия и положения регистров общего назачения.
;================================================================================
N equ 0Ch ; Счетчик битов.
N1 equ 0Dh ; Счетчик байтов.
Temp equ 0Eh ; Многофункциональный регистр
; временного хранения.
Mem equ 0Fh ; Регистр оперативной памяти номеров датчиков.
Temp_LSB equ 10h ; Регистр младшего байта температуры.
Temp_MSB equ 11h ; Регистр старшего байта температуры.
TH equ 12h ; Регистр верхнего предела температуры.
TL equ 13h ; Регистр нижнего предела температуры.
NO_1 equ 14h ; Регистр резерва.
NO_2 equ 15h ; Регистр резерва.
Count_REM equ 16h ; Применяются при измерении температуры

14
Count_D_C equ 17h ; с более высоким разрешением.
CRC equ 18h ; Регистр хранения считанного байта
; контрольной суммы.
CRC_1 equ 19h ; Регистр хранения вычисленного байта
; контрольной суммы.
Flag equ 1Ah ; Регистр флагов.
Count equ 1Bh ; Многофункциональный счетчик.
LED0 equ 1Ch ; Регистры двоично-десятичного преобразования
LED1 equ 1Dh ; (плюс, LED0 используется при вычислении CRC)
Reg_1 equ 20h ; Регистр младшего разряда счетчика.
Reg_2 equ 21h ; Регистр среднего разряда счетчика.
Reg_3 equ 22h ; Регистр старшего разряда счетчика.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присваивание битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
Z equ 2 ; Флаг нулевого результата.
RP0 equ 5 ; Бит выбора банка.
DQ equ 4 ; Бит порта A для управления DS1820.
RW equ 0 ; Бит №0 регистра PortA (вывод RA0 - линия RW)
RS equ 1 ; Бит №1 регистра PortA (вывод RA1 - линия RS)
E equ 2 ; Бит №2 регистра PortA (вывод RA2 - линия E)
BF equ 7 ; Бит №7 регистра PortB.
;================================================================================
org 0 ; Начать выполнение программы
goto START ; с подпрограммы START.
;********************************************************************************

;******************************************************************
; -------------- "РАБОЧАЯ" ЧАСТЬ ПРОГРАММЫ ------------
;******************************************************************
; "Рабочая" инициализация ЖКИ модуля.
;================================================================================
LCD_INIT movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00001100' ; Установка: дисплей включен, видимое
; отображение курсора выключено.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00001100.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00000001' ; Установка: очистка дисплея со сбросом
; данных, установка курсора в начало
; 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00000001.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку на начало вывода символов
; в 1-ю строку.
;================================================================================
; ПП "плавающей" задержки на основе анализа состояния флага занятости BF
; (вариант для 4-разрядного интерфейса).
15
;================================================================================
ENTER_BF movwf Temp ; Переправка старшего п/байта регистра W на
movwf PortB ; линии RB4...7.
;------------------------------------------
; Запуск в работу старшего п/байта (строб).
;------------------------------------------
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortA,E ; Установка на линии Е "0".
;------------------------------------------
swapf Temp,W ; Смена п/байтов с сохранением результата
; операции в W.
movwf PortB ; Переправка младшего п/байта регистра W на
; линии RB4...7.
;------------------------------------------
; Запуск в работу младшего п/байта (строб).
;------------------------------------------
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на линии Е "1".
nop ; Задержка в 1 м.ц.
bcf PortA,E ; Установка на линии Е "0".
;-------------------------------------------------
; Проверка состояния флага занятости BF.
;-------------------------------------------------
; Подготовка к проверке.
;------------------------
bsf Status,RP0 ; Переход в 1-й банк.
movlw b'11110000' ; Запись в W "11110000"
movwf TrisB ; RB4...7 работают на вход, а RB0...3
; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
bcf PortA,RS ; Установка на линии RS "0" (режим команд).
bsf PortA,RW ; Линия RW в "1" (режим чтения данных).
nop ; Задержка в 1 м.ц.
bsf PortA,E ; Установка на лини Е "1".
POVTOR nop ; Задержка в 1 м.ц.
;-----------------------
; Сама проверка.
;-----------------------
btfsc PortB,BF ; Проверка состояния флага занятости BF.
goto POVTOR ; Если BF=1, то продолжение задержки до тех
; пор, пока BF не установится в "0" (программа
; исполняется далее).
;-----------------------
; Завершение процедуры.
;-----------------------
clrf PortA ; Сброс в "0" всех защелок порта А
; (RW=0, RS=0, E=0).
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisB ; Все выводы порта В работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
return ; Возврат по стеку.
;********************************************************************************

;================================================================================
; Подпрограмма вывода на индикацию надписи "АВАРИЯ".
;================================================================================
AVARIJA movlw 41h ; На индикацию выводится
bsf PortA,RS ; символ "А".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movlw 42h ; На индикацию выводится
bsf PortA,RS ; символ "В".
call ENTER_BF ; ------"------
16
;----> Возврат по стеку из ПП ENTER_BF.
movlw 41h ; На индикацию выводится
bsf PortA,RS ; символ "А".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 50h ; На индикацию выводится
bsf PortA,RS ; символ "Р".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 0A5h ; На индикацию выводится
bsf PortA,RS ; символ "И".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 0B1h ; На индикацию выводится
bsf PortA,RS ; символ "Я".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;================================================================================
; Подпрограмма вывода на индикацию надписи "НОРМА:".
;================================================================================
NORMA movlw 48h ; На индикацию выводится
bsf PortA,RS ; символ "Н".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movlw 4Fh ; На индикацию выводится
bsf PortA,RS ; символ "О".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 50h ; На индикацию выводится
bsf PortA,RS ; символ "Р".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 4Dh ; На индикацию выводится
bsf PortA,RS ; символ "М".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 41h ; На индикацию выводится
bsf PortA,RS ; символ "А".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
movlw 3Ah ; На индикацию выводится
bsf PortA,RS ; символ ":".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;================================================================================
;********************************************************************************
; ПОДПРОГРАММА ВЫВОДА НА ИНДИКАЦИЮ.
;********************************************************************************
; Работа в 1-й строке.
;********************************************************************************
; Анализ состояния аварийного флага.
;-----------------------------------------------
DISPLAY btfss Flag,5 ; Бит №5 регистра Flag =0 или =1 ?
goto OBHOD ; Если =0, то обход процедуры вывода надписи
; "АВАРИЯ".
movf Mem,W ; Если =1, то копирование содержимого регистра
; оперативной памяти номеров датчиков Mem
; в регистр W.
;=========================================================
; Определение датчика, показанию которого нужно
; поставить в соответствие надпись "АВАРИЯ".
;=========================================================
addwf PC,F ; Вычисляемый переход.
17
goto AVAR ; Если Mem=.0, то переход на метку AVAR.
; Если Mem=.1, то переход на команду
; movlw b'10001001'.
;-----------------------------------------------
; Вывод надписи "АВАРИЯ" для датчика №2.
;-----------------------------------------------
movlw b'10001001' ; Выбор ячейки DD RAM с адресом 09h, что
; соответствует установке курсора в 10-е слева
; знакоместо 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 10001001.
;----> Возврат по стеку из ПП ENTER_BF.
call AVARIJA ; Переход в ПП вывода надписи "АВАРИЯ".
;----> Возврат по стеку из ПП AVARIJA.
goto DISPLAY_1 ; Переход в ПП DISPLAY_1.
;-----------------------------------------------
; Вывод надписи "АВАРИЯ" для датчика №1.
;-----------------------------------------------
AVAR movlw b'10000001' ; Выбор ячейки DD RAM с адресом 01h, что
; соответствует установке курсора в 2-е слева
; знакоместо 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 10000001.
;----> Возврат по стеку из ПП ENTER_BF.
call AVARIJA ; Переход в ПП вывода надписи "АВАРИЯ".
;----> Возврат по стеку из ПП AVARIJA.
goto DISPLAY_1 ; Переход в ПП DISPLAY_1.
;=========================================================
; Определение датчика, показанию которого нужно
; поставить в соответствие надпись "НОРМА:".
;=========================================================
OBHOD movf Mem,W ; Копирование содержимого регистра оперативной
; памяти номеров датчиков Mem в регистр W.
addwf PC,F ; Вычисляемый переход.
goto NORMAL ; Если Mem=.0, то переход на метку NORMAL.
; Если Mem=.1, то переход на команду
; movlw b'10001001'.
;-----------------------------------------------
; Вывод надписи "НОРМА:" для датчика №2.
;-----------------------------------------------
movlw b'10001001' ; Выбор ячейки DD RAM с адресом 09h, что
; соответствует установке курсора в 10-е слева
; знакоместо 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 10001001.
;----> Возврат по стеку из ПП ENTER_BF.
call NORMA ; Переход в ПП вывода надписи "НОРМА:".
;----> Возврат по стеку из ПП NORMA.
goto DISPLAY_1 ; Переход в ПП DISPLAY_1.
;-----------------------------------------------
; Вывод надписи "НОРМА:" для датчика №1.
;-----------------------------------------------
NORMAL movlw b'10000001' ; Выбор ячейки DD RAM с адресом 01h, что
; соответствует установке курсора в 2-е слева
; знакоместо 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 10000001.
;----> Возврат по стеку из ПП ENTER_BF.
call NORMA ; Переход в ПП вывода надписи "НОРМА:".
;----> Возврат по стеку из ПП NORMA.
;********************************************************************************
; Работа во 2-й строке.
;********************************************************************************
; Выбор места начальной установки курсора во 2-й строке.
;----------------------------------------------------------
DISPLAY_1 movf Mem,W ; Копирование содержимого регистра оперативной
18
; памяти номеров датчиков Mem в регистр W.
addwf PC,F ; Вычисляемый переход.
goto DISPL ; Если Mem=.0, то переход на метку DISPL.
; Если Mem=.1, то переход на команду
; movlw b'11001001'.
;----------------------
; Для датчика №2.
;----------------------
movlw b'11001001' ; Выбор ячейки DD RAM с адресом 49h, что
; соответствует установке курсора в 10-е слева
; знакоместо 2-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 11001001.
;----> Возврат по стеку из ПП ENTER_BF.
goto $+3 ; Обход последующих двух команд.
;----------------------
; Для датчика №1.
;----------------------
DISPL movlw b'11000001' ; Выбор ячейки DD RAM с адресом 41h, что
; соответствует установке курсора во 2-е слева
; знакоместо 2-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 11000001.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Определение и вывод на индикацию знака температуры (+/-).
;----------------------------------------------------------
btfsc Temp_MSB,0 ; В бите №0 старшего байта температуры 0или1 ?
goto MINUS ; Если 1, то переход в ПП MINUS.
movlw 2Bh ; Если 0, то на индикацию
bsf PortA,RS ; выводится символ "+".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto SDVIG ; После вывода на индикацию символа "+",
; переход на обработку младшего байта
; температуры.
MINUS movlw 2Dh ; На индикацию выводится
bsf PortA,RS ; символ "-".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Перевод двоичного числа младшего байта температуры
; из отрицательной области температур в положительную.
;----------------------------------------------------------
comf Temp_LSB,F ; После вывода на индикацию символа "-", все
incf Temp_LSB,F ; биты младшего байта температуры
; инвертируются и к результату прибавляется 1.
;================================================================================
; Подпрограмма обработки содержимого младшего байта температуры.
;================================================================================
; Деление числа, записанного в младшем байте температуры, на 2
; и запись, в бит №0 регистра Flag, признака символов "0" или "5".
;--------------------------------------------------------------------------------
SDVIG clrf Flag ; Flag=0 (подготовка к работе).
rrf Temp_LSB,F ; Деление на 2.
btfsc Status,C ; В бите С 0 или 1 ?
bsf Flag,0 ; Если С=1, то в бит №0 регистра Flag
; записывается 1 (признак символа "5").
; Если С=0, то в бите №0 регистра Flag так и
; останется "лежать" 0 (признак символа "0"),
; и программа будет исполняться далее.
;--------------------------------------------------------------------------------
; Установка (или нет) признака добавления (к показаниям) символа "1"
; (признак устанавливается при температуре от 100 градусов и выше).
19
;--------------------------------------------------------------------------------
movlw .100 ;
subwf Temp_LSB,W ; Temp_LSB - .100 = ? Результат - в W.
btfss Status,C ; Результат положительный или отрицательный?
goto BIN2_10 ; Если отрицательный, то признак добавления
; символа "1" не устанавливается (бит №7
; регистра Flag=0).
bsf Flag,7 ; Если положительный, то устанавливается
; (бит №7 регистра Flag=1).
;********************************************************************************
; Подпрограмма двоично-десятичного преобразования (для двух десятичных чисел).
;********************************************************************************
BIN2_10 bcf Status,C ; Сброс флага переноса-заема.
movlw .8 ; Запись в регистр Count числа
movwf Count ; проходов преобразования.
clrf LED0 ; Сброс регистра LED0.
;--------------------------------------------------------------------------------
; Циклический сдвиг влево через бит С регистра Status.
;--------------------------------------------------------------------------------
LOOP_16 rlf Temp_LSB,F ; Циклический сдвиг влево содержимого регистра
; Temp_LSB.
rlf LED0,F ; Циклический сдвиг влево содержимого
; регистра LED0.
decfsz Count,F ; Декремент содержимого регистра Count,
; с сохранением результата в нем же.
goto adjDEC ; Если результат не = 0, то переход в ПП
; adjDEC, а если = 0, то программа
; исполняется далее.
;--------------------------------------------------------------------------------
; Порязрядное распределение полубайтов.
;--------------------------------------------------------------------------------
swapf LED0,W ; Запись старшего полубайта LED0
andlw 0Fh ; в младший полубайт LED1
movwf LED1 ;

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


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

goto ASC ; Переход в ПП ASC.


;--------------------------------------------------------------------------------
; Запись в регистр FSR адреса регистра LED0 для дальнейшей косвенной адресации
; к нему в ПП adjBCD.
;--------------------------------------------------------------------------------
adjDEC movlw LED0 ; Запись в регистр FSR адреса регистра LED0
movwf FSR ; с дальнейшим переходом в ПП adjBCD.
call adjBCD ;
;---> Возврат по стеку из ПП adjBCD.
goto LOOP_16 ; Переход на следующее кольцо числовых
; преобразований.
;--------------------------------------------------------------------------------
; Основные операции преобразования двоичных чисел в двоично-десятичные.
;--------------------------------------------------------------------------------
adjBCD clrwdt ; Сброс сторожевого таймера WDT.
movlw 3 ; Суммирование содержимого текущего LED
addwf 0,W ; (LED0...3) с числом 03h, с записью
movwf Temp ; результата операции, через регистр W, в
; регистр Temp.
btfsc Temp,3 ; Анализ состояния бита №3 регистра Temp.
movwf 0 ; Если бит №3 = 1, то содержимое регистра Temp
; копируется в текущий LED.
movlw 30 ; Если бит №3 = 0, то содержимое текущего LED
addwf 0,W ; складывается с константой 30h, с записью
movwf Temp ; результата операции, через регистр W, в
; регистр Temp.
btfsc Temp,7 ; Анализ состояние бита №7 регистра Temp.
20
movwf 0 ; Если бит №7 = 1, то содержимое регистра Temp
; копируется в текущий LED.
retlw 0 ; Если бит №7 = 0, то регистр W очищается и
; происходит возврат по стеку в ПП adjDEC.
;********************************************************************************
; Процедура преобразования кода.
;================================================================================
ASC movlw 30h ; Запись в регистр W числа 30h.
iorwf LED0,F ; Логическое "ИЛИ" содержимого регистра W и
; регистра LED0с сохранением результата
; в LED0.
iorwf LED1,F ; То же самое для LED1.
;********************************************************************************
; Вывод на индикацию результата измерения.
;********************************************************************************
; Вывод (или нет) на индикацию символа "1" (выводится при Т=100 градусов и выше).
;================================================================================
btfss Flag,7 ; Бит №7 регистра Flag =0 или =1 ?
goto C_00_99 ; Если =0, то символ "1" на индикацию не
; выводится.
movlw 31h ; Если =1, то символ "1" (31h)
bsf PortA,RS ; на индикацию выводится.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Вывод на индикацию двух символов результата измерения
; (в диапазоне от 00 до 99 градусов).
;================================================================================
C_00_99 movf LED1,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED1.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movf LED0,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED0.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Вывод на индикацию пары символов ",0" или ",5".
;================================================================================
movlw 2Ch ; Вывод на индикацию
bsf PortA,RS ; символа "," (2Ch).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
btfsc Flag,0 ; Бит №0 регистра Flag =0 или =1 ?
goto _5 ; Если =1, то далее (goto _5), на
; индикацию будет выведен символ "5".
movlw 30h ; Если =0, то на индикацию
bsf PortA,RS ; выводится символ "0" (30h).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.

_5 movlw 35h ; Вывод на индикацию


bsf PortA,RS ; символа "5" (35h).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;********************************************************************************

21
;************************************************************************
; НАЧАЛО ПРОГРАММЫ
;************************************************************************
START clrf PortA ; Сброс всех защелок порта А.
bsf PortA,3 ; Закрытие "форсажного" транзистора.
clrf PortB ; Сброс всех защелок порта В.
clrf Mem ; Сброс регистра оперативной памяти номера
; датчика.
clrf IntCon ; Запрет всех прерываний.
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisA ; Все выводы портов А и В
clrf TrisB ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.

call LCD_INIT ; Условный переход в процедуру "рабочей"


; инициализации.
;----> Возврат по стеку из ПП LCD_INIT.

;########################################################################
; Начало работы с датчиком DS1820.
;########################################################################
; Инициализация DS1820.
;================================================================================
SNOVA call DQ_INIT ; Переход в ПП нициализации DS1820.
;----> Возврат по стеку из ПП DQ_INIT.
;================================================================================
; Команда Skip ROM (CCh).
; Необходима для запуска процедуры преобразования температуры сразу всеми
; датчиками.
;================================================================================
movlw 0CCh ; Запись команды CCh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;================================================================================
; Команда Convert T (44h).
; Эта команда запускает процесс преобразования температуры. В течение времени ее
; исполнения, DS1820 не реагирует на команды "мастера".
; Это время нужно просто переждать.
;================================================================================
movlw 44h ; Запись команды 44h
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;================================================================================
; Ожидание завершения процесса преобразования температуры: задержка 700 мс.
;================================================================================
bcf PortA,3 ; Открытие "форсажного" транзистора
; (включение "подпитки").
movlw .18 ;
movwf Reg_1 ;
movlw .142 ;
movwf Reg_2 ;
movlw .4 ;
movwf Reg_3 ;

WR decfsz Reg_1,F ;
goto WR ; Стандартный,
decfsz Reg_2,F ; 3-разрядный,
goto WR ; вычитающий
decfsz Reg_3,F ; счетчик.
goto WR ;

bsf PortA,3 ; Закрытие "форсажного" транзистора


; (выключение "подпитки").
22
;================================================================================
; Инициализация DS1820.
;================================================================================
RE_START call DQ_INIT ; Переход в ПП нициализации DS1820.
;----> Возврат по стеку из ПП DQ_INIT.
;================================================================================
; Команда Match ROM (55h).
; Эта команда разрешает адресацию к конкретному датчику, с целью
; дальнейшего считывания данных из области его оперативной памяти.
;================================================================================
movlw 055h ; Запись команды Match ROM.
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта.
;----> Возврат по стеку из ПП OUT_BYTE.
;----------------------------------------
; Подготовка к процедуре адресации.
;----------------------------------------
movlw 10h ; Вывод типа прибора (для DS1820 - 10h, для
movwf Temp ; DS1990A - 01h, для DS18B20 - 28h, для
call OUT_BYTE ; DS2415(часы реального времени) - 24h и
; т.д.).
;--------------------------------------------------------------------------------
; Выбор того датчика, из которого будет считано содержимое области
; оперативной памяти.
;--------------------------------------------------------------------------------
movf Mem,W ; Копирование содержимого регистра оперативной
; памяти номеров датчиков Mem, в регистр W.
addwf PC,F ; Вычисляемый переход.
goto NOMER ; Если Mem=.0, то переход на метку NOMER.
; Если Mem=.1, то переход на команду
; movlw 3Fh.
;--------------------------------------------------------------------------------
; Процедура адресации к датчику №2 (адрес: 57 00 08 00 DC 00 3F 10)
; В ячейку TH записано 3Eh (порог 31 градус), в ячейку TL записано 00h.
;--------------------------------------------------------------------------------
movlw 3Fh ; Передача первого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0 ; Передача второго байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0DCh ; Передача третьего байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0 ; Передача четвертого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 8 ; Передача пятого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0 ; Передача шестого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 57h ; Передача байта контрольной суммы
movwf Temp ; предыдущих семи байтов.
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
goto BLOKNOT ; Переход в ПП BLOKNOT.
;--------------------------------------------------------------------------------

23
; Процедура адресации к датчику №1 (адрес: A1 00 08 00 E5 31 62 10)
; В ячейку TH записано 3Ch (порог 30 градусов), в ячейку TL записано 01h.
;--------------------------------------------------------------------------------
NOMER movlw 62h ; Передача первого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 31h ; Передача второго байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0E5h ; Передача третьего байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0 ; Передача четвертого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 8 ; Передача пятого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0 ; Передача шестого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 0A1h ; Передача байта контрольной суммы
movwf Temp ; предыдущих семи байтов.
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
;================================================================================
; Команда Read Scratchpad (BEh).
; Разрешение чтения из области оперативной памяти DS1820.
;================================================================================
BLOKNOT movlw 0BEh ; Запись команды BEh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;--------------------------------------------------------------------------------
; Чтение содержимого области оперативной памяти DS1820
; (в полном объеме - 9 байтов).
;--------------------------------------------------------------------------------
call IN_BYTE ; Прием младшего байта температуры.
;----> Возврат по стеку из ПП IN_BYTE.
movwf Temp_LSB ; Запись принятого байта в регистр Temp_LSB.

call IN_BYTE ; Прием старшего байта температуры.


;----> Возврат по стеку из ПП IN_BYTE.
movwf Temp_MSB ; Запись принятого байта в регистр Temp_MSB.

call IN_BYTE ; Прием байта верхнего предела температуры.


;----> Возврат по стеку из ПП IN_BYTE.
movwf TH ; Запись принятого байта в регистр TH.

call IN_BYTE ; Прием байта нижнего предела температуры.


;----> Возврат по стеку из ПП IN_BYTE.
movwf TL ; Запись принятого байта в регистр TL.

call IN_BYTE ; Прием резервного байта (по умолчанию


; записано FFh).
;----> Возврат по стеку из ПП IN_BYTE.
movwf NO_1 ; Запись принятого байта в регистр NO_1.

call IN_BYTE ; Прием резервного байта (по умолчанию

24
; записано FFh).
;----> Возврат по стеку из ПП IN_BYTE.
movwf NO_2 ; Запись принятого байта в регистр NO_2.

call IN_BYTE ; Count_REM применяется при измерении


;----> Возврат по стеку из ПП IN_BYTE. ; температуры с более высоким разрешением.
movwf Count_REM ; Запись принятого байта в регистр Count_REM.

call IN_BYTE ; Count_D_C применяется при измерении


;----> Возврат по стеку из ПП IN_BYTE. ; температуры с более высоким разрешением.
movwf Count_D_C ; Запись принятого байта в регистр Count_D_C.

call IN_BYTE ; Прием байта контрольной суммы (CRC).


;----> Возврат по стеку из ПП IN_BYTE.
movwf CRC ; Запись принятого байта в регистр CRC.
;================================================================================
; Вычисление контрольной суммы (CRC) первых 8-ми, считанных
; из области оперативной памяти DS1820, байтов.
;================================================================================
clrf CRC_1 ; Подготовка регистра CRC_1 к вычислению.
movlw 8 ; Запись количества обрабатываемых байтов (.8)
movwf N1 ; в регистр счетчика байтов N1.

movlw Temp_LSB ; Запись адреса регистра хранения 1-го


movwf FSR ; принятого байта в регистр косвенной
; адресации FSR.
SNOVA_2 movlw 8 ; Запись количества обрабатываемых битов (.8)
movwf N ; в регистр счетчика битов N.
movf IndF,W ; Копирование текущего байта (через W)
movwf LED0 ; в регистр LED0.
;------------------------------------
SNOVA_1 xorwf CRC_1,W ;
movwf Temp ;
rrf Temp,W ;
movf CRC_1,W ;
btfsc Status,C ;
xorlw b'00011000' ; Процедура вычисления
movwf Temp ; контрольной суммы.
rrf Temp,W ;
movwf CRC_1 ;
bcf Status,C ;
rrf LED0,F ;
movf LED0,W ;
;------------------------------------
decfsz N,F ; Декремент содержимого счетчика битов N.
goto SNOVA_1 ; Если результат не=0, то переход на обработку
; следующего бита.
incf FSR,F ; Если результат =0, то подготовка к обработке
; следующего байта (FSR+1=...).
decfsz N1,F ; Декремент содержимого счетчика байтов N_1.
goto SNOVA_2 ; Если результат не=0, то переход на обработку
; следующего байта.
; Если результат =0, то программа
; исполняется далее.
;******************************************************
; После вычисления, результат вычисления контрольной
; суммы первых 8-ми байтов "осядет" в регистре CRC_1.
;******************************************************
;--------------------------------------------------------------------------------
; Анализ совпадения или не совпадения числовых значений байтов регистров
; CRC и CRC_1.
;--------------------------------------------------------------------------------
movf CRC,W ; Вычитание содержимого регистра CRC из
subwf CRC_1,W ; содержимого регистра CRC_1. Результат - в W.
btfss Status,Z ; Результат вычитания =0 или не=0 ?
goto RE_START ; Если не=0, то процедура адресации
25
; повторяется.
; Если =0, то программа исполняется далее.
;================================================================================
; Работа с температурными порогами.
;================================================================================
bcf Flag,5 ; Подготовка к работе бита №5 регистра Flag.
;------------------------------------------------------
; Сравнение результата замера с температурным порогом
; (работа с регистром TH).
;------------------------------------------------------
movf TH,W ; Копирование температурного порога в W.
subwf Temp_LSB,W ; Temp_LSB - TH = ?
btfss Status,C ; Результат вычитания положительный или
; отрицательный?
goto $+2 ; Если "-", то 1 в бит №5 регистра Flag
; не записывается (обход).
; Если "+" (превышение порога), то программа
; исполняется далее.
bsf Flag,5 ; В бит №5 регистра Flag записывается 1
; (признак превышения порога).
call DISPLAY ; Переход в ПП вывода результата измерения
; на индикацию.
;----> Возврат по стеку из ПП DISPLAY.
;------------------------------------------------------
; Подготовка к работе со следующим датчиком
; (работа с регистром TL).
;------------------------------------------------------
movf TL,W ; Перезапись признака следующего датчика
movwf Mem ; из регистра TL (через W) в регистр Mem.
goto SNOVA ; Переход на новый цикл измерения.
;********************************************************************************

;================================================================================
; Подпрограмма нициализации 1-Wire устройства (DS1820).
;================================================================================
; Установка на линии DQ 1.
;-----------------------------------
DQ_INIT call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
;-----------------------------------
; Установка на линии DQ 0.
;-----------------------------------
call PIN_LO ; Установка на линии нуля.
;----> Возврат по стеку из ПП PIN_LO.
;-----------------------------------
; Задержка 600 мкс.
;-----------------------------------
movlw .60 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
;-----------------------------------
; Установка на линии DQ 1.
;-----------------------------------
call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
;-----------------------------------
; Задержка 70 мкс.
;-----------------------------------
movlw .7 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки

26
; (задержка=7х10=70мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
;--------------------------------------------------------------------------------
; Определение наличия (или нет) отклика на импульс сброса.
;--------------------------------------------------------------------------------
btfsc PortA,DQ ; На линии DQ 0 или 1 (отклик есть или нет)?
goto DQ_INIT ; Если отклика нет (1), то снова начинается
; исполнение процедуры инициализации.
; Если отклик есть (0), то программа
; исполняется далее.
;-----------------------------------
; Задержка 500 мкс.
;-----------------------------------
movlw .50 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=50х10=500мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
return ; Возврат по стеку.
;********************************************************************************
; Подпрограмма задержки.
;================================================================================
; Задание количества проходов по 10 мкс.
;----------------------------------------
PAUSE_X movwf Count ; Копирование количества проходов из W
; в Count.
;----------------------------------------
; Пауза в 10 мкс.
;----------------------------------------
PAUSE_10 nop ;
goto $+1 ; Одноразрядный,
goto $+1 ; вычитающий
goto $+1 ; счетчик
decfsz Count,F ; с "врезкой".
goto PAUSE_10 ;

return ; Возврат по стеку.


;================================================================================

;************************************************************************
; Базовые процедуры чтения/записи по 1-Wire протоколу.
;************************************************************************
; Подпрограмма передачи "мастером" байта: цикл передачи бита начинается
; импульсом низкого уровня длительностью 1...15 мкс, далее следует передаваемый
; бит. Цикл завершается импульсом высокого уровня длительностью не менее 1 мкс.
;================================================================================
OUT_BYTE movlw .8 ; Запись количества бит передаваемого
movwf N ; байта в регистр N.

METKA_1 rrf Temp,F ; Сдвиг вправо содержимого передаваемого


; байта.
btfss Status,C ; В бите С "лежит" 0 или 1 ?
goto OUT_0 ; Если С=0, то переход в ПП передачи нуля.
goto OUT_1 ; Если С=1, то переход в ПП передачи единицы.

METKA_2 decfsz N,F ; Уменьшение на 1 содержимого счетчика битов.


goto METKA_1 ; Если результат не =0, то переход на метку
; METKA_1.
return ; Если результат =0, то возврат по стеку.
;================================================================================
; Подпрограмма приема "мастером" байта: цикл приема бита начинается импульсом
; низкого уровня длительностью 1...15 мкс, после чего DS1820 выставляет на линии
; бит. Цикл завершается импульсом высокого уровня длительностью не менее 1 мкс.
;================================================================================
IN_BYTE movlw .8 ; Запись количества бит принимаемого
27
movwf N ; байта в регистр N.
clrf Temp ; Очистка регистра принимаемого байта.

IN_BYTE_1 call PIN_LO ; Формирование на линии уровня 0.


;----> Возврат по стеку из ПП PIN_LO.

call PIN_HI ; Формирование на линии уровня 1.


;----> Возврат по стеку из ПП PIN_HI.
nop ; Калибровочный NOP.
;-------------------------------------------------------------------
; Запись, в бит С, уровня текущего бита, выдаваемого DS1820 в линию.
;-------------------------------------------------------------------
btfss PortA,DQ ; На линии 0 или 1 ?
bcf Status,C ; Если на линии 0, то в бите С выставляется 0
btfsc PortA,DQ ; Если на линии 1 (а также после исполнения
; предыдущей команды), то еще одна проверка
; состояния линии.
bsf Status,C ; Если на линии 1, то в бите С выставляется 1
; Если на линии 0 (а также после исполнения
; предыдущей команды), то программа
; исполняется далее.
;-------------------------------------------------------------------
; Последовательное заполнение битами регистра Temp.
;-------------------------------------------------------------------
rrf Temp,F ; Сдвиг содержимого регистра Temp вправо
; (через C).
movlw .4 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=4х10=40мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
decfsz N,F ; Уменьшение на 1 содержимого счетчика битов.
goto IN_BYTE_1 ; Если результат не=0, то переход
; на прием следующего бита.
movf Temp,W ; Если =0, то копирование принятого байта
; в регистр W.
return ; Возврат по стеку.
;================================================================================
; Подпрограмма передачи бита с уровнем "0".
;================================================================================
OUT_0 call PIN_LO ; Переход в ПП установки уровня 0.
; Начало передачи.
;----> Возврат по стеку из ПП PIN_LO.
movlw .6 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=6х10=60мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
call PIN_HI ; Переход в ПП установки уровня 1.
; Конец передачи.
;----> Возврат по стеку из ПП PIN_HI.
goto METKA_2 ; Переход на исполнение процедуры декремента
; и анализа содержимого счетчика битов.
;================================================================================
; Подпрограмма передачи бита с уровнем "1".
;================================================================================
OUT_1 call PIN_LO ; Переход в ПП установки уровня 0.
; Начало передачи.
;----> Возврат по стеку из ПП PIN_LO.
call PIN_HI ; Переход в ПП установки уровня 1.
; (передача 1).
;----> Возврат по стеку из ПП PIN_HI.
movlw .6 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=6х10=60мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
goto METKA_2 ; Переход на новый цикл передачи бита.

28
;--------------------------------------------------------------------------------
; Формирование на линии уровня "1" за счет подтягивающего резистора
;--------------------------------------------------------------------------------
PIN_HI bsf Status,RP0 ; Переход в банк 1.
bsf TrisA,DQ ; Настройка вывода RA4 на работу "на вход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "0" средствами микроконтроллера
;--------------------------------------------------------------------------------
PIN_LO bcf PortA,DQ ; Установка 0 на выходе защелки вывода RA4.
bsf Status,RP0 ; Переход в банк 1.
bcf TrisA,DQ ; Настройка вывода RA4 на работу "на выход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;********************************************************************************
end ; Конец программы.

Я советую Вам “положить глаз” на эту программу, так как в ней реализовано
достаточно большое количество полезных “наворотов”.
“Боевая раскраска” - такая же, как и в предыдущей программе.
В программе DS1820_4.asm Вы видите все ту же фиксированную задержку на 0,7 сек.,
только сверху и снизу она “ограничена” командами bcf PortA,3 и bsf PortA,3
соответственно.
То есть, в начале задержки, “форсажный” транзистор открывается, а в ее конце,
закрывается (управляющий вывод - RA3).
Кроме того, этот транзистор нужно закрыть и в начале 1-го “витка” полного цикла
программы (см. команду bsf PortA,3 в ПП START).
Вот теперь полный порядок: “форсаж” (“подпитка”) будет обеспечен только тогда, когда
это требуется, а все остальное время “форсажный” транзистор “спит” (закрыт) и совсем
не мешает (в открытом состоянии, он блокирует подтягивающий резистор) делать
разные нужные дела.
Если разобраться, то предмет данного разговора очень прост, но не смотря на это,
имеют место быть вполне приличные “девиденды”.
“Убийство”, с минимумом “головной боли”, одной из 3-х “проволочин” длинной линии,
это солидно и “пахнет” большим материальным (и иным) “счастьем”.
Есть еще один способ перехода с 3-проводной линии на 2-проводную, но он уже не
такой интеллектуальный: датчики просто запитываются от источника/источников питания
непосредственно в местах своего расположения.
Это, по понятным причинам, конечно более хлопотно, но вполне может иметь место
быть.
И последнее: разработчики не рекомендуют использовать “паразитное” питание при
замерах температур от 100 градусов и выше.
Это нужно принять как данность (хотя, если есть желание, то можно и
поэкспериментировать).

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

30

Оценить