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

5/10.

“Снятие сливок”: базовые программы, работающие с одним и несколькими


датчиками, с полномасштабным задействованием всех возможностей DS1820
(DS18S20).

В этом подразделе предоставлены 2 программы: 0_1grad3.asm и 0_1grad4.asm.


“Обслуга” - ЖКИ модуль 16х2 (на основе HD44780). Обе программы проверены в
“железе”.
Программа, работающая с одним датчиком (0_1grad3.asm).
Характеристики:
1. Разрешение 0,1 градус.
2. Вывод на индикацию результатов замеров температуры в диапазоне -55 …+125
градусов, с указанием знака температуры и гашением незначащих нулей.
3. Возможность работы по длинной, 2-проводной физической линии с помехами:
- “паразитное” питание без использования “форсажного” транзистора,
- работа с контрольной суммой,
- работа с импульсом присутствия.
4. Работа с одним температурным порогом и визуальным контролем выхода (или
нет) за него (надписи “НОРМА:” и “АВАРИЯ”).
5. Сторожевой таймер включен.
6. Принципиальная схема - см. рис. 1 подраздела 5/7.

;************************************************************************
; 0_1grad3.asm ЭЛЕКТРОННЫЙ ТЕРМОМЕТР НА ОСНОВЕ ДАТЧИКА ТЕМПЕРАТУРЫ DS1820
; (DS18S20)
; М/контроллер и DS1820 работают по интерфейсу 1-Wire.
; Работа с одним датчиком, вычислением контрольной суммы, одним температурным
; порогом (TH), учетом импульса присутствия, "паразитным" питанием и гашением
; незначащих нулей. Разрешение 0,1 градус. Сторожевой таймер включен.
;************************************************************************
; "Практикум по конструированию устройств на 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.
;-------------------------------
; Объем программы: 348 команд.
;================================================================================
LIST p=16F84a ; Используется м/контроллер PIC16F84A.
__CONFIG 03FF5H ; Бит защиты выключен, WDT включен,
; XT-генератор.
;================================================================================
; Определение положения регистров специального назначения.
;================================================================================
IndF equ 00h ; Доступ к памяти через FSR.
PC equ 02h ; Счетчик команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.

1
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 ; Счетчик битов.
N1 equ 0Dh ; Счетчик байтов.
Temp equ 0Eh ; Многофункциональный регистр временного
; хранения.
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 ; Регистр хранения остатка измерения.
Count_D_C equ 17h ; Регистр хранения количества градаций
; на 1 градус.
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 ; Результат направить в регистр.
;================================================================================
; Присваивание битам названий.
;================================================================================
Z equ 2 ; Флаг нулевого результата.
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.
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
2
; 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.
goto POVTOR ; Если BF=1, то продолжение задержки до тех
; пор, пока BF не установится в "0" (программа
; исполняется далее).
;-----------------------
3
; Завершение процедуры.
;-----------------------
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 ; ------"------
;----> Возврат по стеку из ПП 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 ; символ ":".
4
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП ENTER_BF.

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


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

;********************************************************************************
; ПОДПРОГРАММА ВЫВОДА НА ИНДИКАЦИЮ.
;********************************************************************************
; Работа в 1-й строке.
;********************************************************************************
; Выбор знакоместа в 1-й строке, с которого будет
; выводиться на индикацию надпись "НОРМА:" или "АВАРИЯ".
;-------------------------------------------------------
DISPLAY movlw b'10000101' ; Выбор ячейки DD RAM с адресом 05h, что
; соответствует установке курсора в 6-е слева
; знакоместо 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 10000101.
;----> Возврат по стеку из ПП ENTER_BF.
clrwdt ; Сброс WDT.
;-----------------------------------------------
; Анализ состояния аварийного флага.
;-----------------------------------------------
btfss Flag,5 ; Бит №5 регистра Flag =0 или =1 ?
goto OBHOD ; Если =0, то выводится надпись "НОРМА:".
; Если =0, то выводится надпись "АВАРИЯ".
;-----------------------------------------------
; Вывод на индикацию надписи "АВАРИЯ".
;-----------------------------------------------
call AVARIJA ; Переход в ПП вывода надписи "АВАРИЯ".
;----> Возврат по стеку из ПП AVARIJA.
goto DISPLAY_1 ; Переход в ПП DISPLAY_1.
;-----------------------------------------------
; Вывод на индикацию надписи "НОРМА:".
;-----------------------------------------------
OBHOD call NORMA ; Переход в ПП вывода надписи "НОРМА:".
;----> Возврат по стеку из ПП NORMA.
;********************************************************************************
; Работа во 2-й строке.
;********************************************************************************
; Выбор 6-го слева знакоместа 2-й строки.
;----------------------------------------------------------
DISPLAY_1 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 ; выводится символ "+" (2Bh).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto SDVIG ; После вывода на индикацию символа "+",
; переход на обработку младшего байта
; температуры.
MINUS movlw 2Dh ; На индикацию выводится
bsf PortA,RS ; символ "-" (2Dh).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
5
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Перевод двоичного числа младшего байта температуры
; из отрицательной области температур в положительную.
;----------------------------------------------------------
comf Temp_LSB,F ; После вывода на индикацию символа "-", все
incf Temp_LSB,F ; биты младшего байта температуры
; инвертируются и к результату прибавляется 1.
;================================================================================
; Подпрограмма обработки содержимого младшего байта температуры.
;================================================================================
; Деление числа, записанного в младшем байте температуры, на 2.
;--------------------------------------------------------------------------------
SDVIG clrf Flag ; Flag=0 (подготовка к работе).
rrf Temp_LSB,F ; Деление на 2.
;--------------------------------------------------------------------------------
; Установка (или нет) признака добавления (к показаниям) символа "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 ; Сброс флага переноса-заема.
clrwdt ; Сброс WDT.
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 ;
6
;---> Возврат по стеку из ПП 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.
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 градусов и выше).
;================================================================================
clrwdt ; Сброс WDT.
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.
goto OBHOD_1 ; Если температура 100 и более, то обход
; гашения левого незначащего нуля.
;================================================================================
; Гашение левого незначащего нуля.
;================================================================================
C_00_99 movlw 30h ; В LED1 "лежит"
xorwf LED1,W ; символ "0" или
btfss Status,Z ; другой символ?
goto OBHOD_1 ; Если не "0", то незначащий ноль не гасится.

movlw 20h ; Если "0", то он заменяется на символ "пусто"


bsf PortA,RS ; (20h), т.е. гасится без смещения показания.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto $+4 ; Обход следующих трех команд.
;================================================================================
; Вывод на индикацию двух символов результата измерения
; (в диапазоне от 00 до 99 градусов).
;================================================================================
7
; Вывод цифры десятков градусов (левой).
;----------------------------------------
OBHOD_1 movf LED1,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED1.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------
; Вывод цифры единиц градусов (правой).
;----------------------------------------
movf LED0,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED0.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;-------------------------------------
; Формирование символа "запятая".
;-------------------------------------
movlw 2Ch ; Вывод на индикацию
bsf PortA,RS ; символа "," (2Ch).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;-------------------------------------
; Формирование символов после запятой.
;-------------------------------------
movf Count_REM,W ; Копирование содержимого Count_REM в W.
sublw .16 ; .16 - Count_REM (от .1 до .16) = от .0
; до .15 (W).
call TEXT_1 ; Переход в перекодировщик 16/10.
bsf PortA,RS ; "Плавающая" задержка со стробом под вывод
call ENTER_BF ; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Гашение правого незначащего ("паразитного") нуля.
;================================================================================
movlw 20h ; Гашение (символом "пусто") правого
bsf PortA,RS ; "паразитного" нуля, возникающего в случае
; перехода от 100 к 99 градусам.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;********************************************************************************

;================================================================================
; Перекодировщик 16/10.
;================================================================================
; Вычисляемый переход под табл. 3 п/раздела 5/8 "Практикума...".
;--------------------------------------------------------------------------------
TEXT_1 addwf PC,F ; Приращение PC на величину содержимого W.
retlw 0x30 ; "0"
retlw 0x30 ; "0"
retlw 0x31 ; "1"
retlw 0x32 ; "2"
retlw 0x32 ; "2"
retlw 0x33 ; "3"
retlw 0x34 ; "4"
retlw 0x34 ; "4"
retlw 0x35 ; "5"
retlw 0x35 ; "5"
retlw 0x36 ; "6"
retlw 0x37 ; "7"
retlw 0x37 ; "7"
retlw 0x38 ; "8"
retlw 0x39 ; "9"
8
retlw 0x39 ; "9"
;--------------------------------------------------------------------------------
; Вычисляемый переход под табл. 4 п/раздела 5/8 "Практикума...".
;--------------------------------------------------------------------------------
;;;TEXT_1 addwf PC,F ; Приращение PC на величину содержимого W.
;;; retlw 0x30 ; "0"
;;; retlw 0x31 ; "1"
;;; retlw 0x32 ; "2"
;;; retlw 0x32 ; "2"
;;; retlw 0x33 ; "3"
;;; retlw 0x33 ; "3"
;;; retlw 0x34 ; "4"
;;; retlw 0x34 ; "4"
;;; retlw 0x35 ; "5"
;;; retlw 0x35 ; "5"
;;; retlw 0x36 ; "6"
;;; retlw 0x36 ; "6"
;;; retlw 0x37 ; "7"
;;; retlw 0x37 ; "7"
;;; retlw 0x38 ; "8"
;;; retlw 0x39 ; "9"
;================================================================================

;********************************************************************************
; НАЧАЛО ПРОГРАММЫ
;********************************************************************************
START clrf PortA ; Сброс всех защелок порта А.
clrf PortB ; Сброс всех защелок порта В.
bsf Status,RP0 ; Переход в 1-й банк.
clrf TrisA ; Все выводы портов А и В
clrf TrisB ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
clrwdt ; Сброс WDT.
call LCD_INIT ; Условный переход в процедуру "рабочей"
; инициализации.
;----> Возврат по стеку из ПП LCD_INIT.
clrwdt ; Сброс WDT.
;################################################################################
; Начало работы с датчиком 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 мс.

9
; (при "паразитном" питании применяется только фиксированная задержка).
;================================================================================
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 ;
clrwdt ; Сброс WDT.
;================================================================================
; Инициализация DS1820.
;================================================================================
RE_START 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).
; Разрешение чтения из области оперативной памяти DS1820.
;================================================================================
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 ; Прием резервного байта (по умолчанию


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

10
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.
;--------------------------------------------------------------------------------
clrwdt ; Сброс WDT.
movf CRC,W ; Вычитание содержимого регистра CRC из
subwf CRC_1,W ; содержимого регистра CRC_1. Результат - в W.
btfss Status,Z ; Результат вычитания =0 или не=0 ?
goto RE_START ; Если не=0, то процедура адресации
; повторяется.
; Если =0, то программа исполняется далее.
11
;================================================================================
; Работа с температурными порогами.
;================================================================================
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
; (признак превышения порога).
bcf Status,C ; Подготовка бита C к дальнейшей работе.
call DISPLAY ; Переход в ПП вывода результата измерения
; на индикацию.
;----> Возврат по стеку из ПП DISPLAY.
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 ; Переход в ПП задержки
; (задержка=7х10=70мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
;--------------------------------------------------------------------------------
; Определение наличия (или нет) отклика на импульс сброса.
;--------------------------------------------------------------------------------
btfsc PortA,DQ ; На линии DQ 0 или 1 (отклик есть или нет)?
goto DQ_INIT ; Если отклика нет (1), то снова начинается
; исполнение процедуры инициализации.
12
; Если отклик есть (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 ; Запись количества бит принимаемого
movwf N ; байта в регистр N.
clrf Temp ; Очистка регистра принимаемого байта.

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


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

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


;----> Возврат по стеку из ПП PIN_HI.
nop ; Калибровочный NOP.
13
;-------------------------------------------------------------------
; Запись, в бит С, уровня текущего бита, выдаваемого 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 ; Переход на новый цикл передачи бита.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "1" за счет подтягивающего резистора
;--------------------------------------------------------------------------------
PIN_HI bsf Status,RP0 ; Переход в банк 1.
bsf TrisA,DQ ; Настройка вывода RA4 на работу "на вход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "0" средствами микроконтроллера
;--------------------------------------------------------------------------------
14
PIN_LO bcf PortA,DQ ; Установка 0 на выходе защелки вывода RA4.
bsf Status,RP0 ; Переход в банк 1.
bcf TrisA,DQ ; Настройка вывода RA4 на работу "на выход".
bcf Status,RP0 ; Переход в банк 0.
return ; Возврат по стеку.
;********************************************************************************
end ; Конец программы.

Пояснение: в данном случае, применение вспомогательного устройства (см. подраздел


5/5) обязательно, так как в ячейку области EEPROM памяти DS1820 нужно
предварительно записать значение температурного порога, но, в случае применения
одного датчика, можно вообще обойтись без “услуг” вспомогательного устройства, если
“перекроить” процедуру сравнения результата замера с температурным порогом
следующим образом:
;------------------------------------------------------
; Сравнение результата замера с температурным порогом
; (работа с регистром TH).
;------------------------------------------------------
movf TH,W ; Копирование температурного порога в W.
movlw (константа температурного порога)
subwf Temp_LSB,W ; Temp_LSB - TH = ?
btfss Status,C ; Результат вычитания положительный или
; отрицательный?
…………………………..
…………………………..
То, что отмечено красным цветом, нужно убрать, а то, что отмечено зеленым цветом,
нужно вставить.
В этом случае, даже удобнее, так как значение температурного порога можно
назначить в тексте “боевой” программы, “не забивая себе голову” работой со
вспомогательным устройством (адресоваться к одному датчику не нужно и
температурный порог устанавливается программой).
Вопрос: “Можно ли “провернуть это пороговотемпературное дельце” в устройстве,
имеющем в своем составе 2 и более датчика”?
Ответ: можно, но не желательно, так как придется организовывать процедуру выбора
того или иного температурного порога, да и зачем это нужно, ведь со
вспомогательным устройством все равно придется иметь дело (считывание адресов
датчиков)?
А раз это так, то в DS1820, “за компанию” со считыванием адреса датчика,
записываются температурные пороги, “и дело в шляпе” (никакой процедуры выбора
организовывать не нужно).
С точки зрения более широких возможностей, работа с двумя датчиками (и более)
гораздо перспективнее работы с одним датчиком.
В этом случае, “всплывает” проблема адресации, о которую разбились “душ высокие
порывы” большого количества “страждущих”.
Я ее решил на свой лад в том смысле, что, прежде чем “ваять” “боевую” программу,
нужно поработать со вспомогательным устройством.
Механика этой работы подробно описана ранее.

Программа, работающая с двумя датчиками (0_1grad4.asm).


Характеристики:
1. Разрешение 0,1 градус.
2. Вывод на индикацию результатов замеров температуры в диапазоне -55…+125
градусов, с указанием знака температуры и гашением незначащих нулей.
3. Возможность работы по длинной, 2-проводной физической линии с помехами:
- “паразитное” питание с использованием “форсажного” транзистора,
- работа с контрольной суммой,
- работа с импульсом присутствия.
4. Работа с несколькими температурными порогами и визуальным контролем
выхода (или нет) за них (надписи “НОРМА:” и “АВАРИЯ”).
5. Сторожевой таймер включен.

15
6. Принципиальная схема - см. рис. 2 подраздела 5/7.
7. Имеется возможность наращивания количества датчиков.

;********************************************************************************
; 0_1grad4.asm ЭЛЕКТРОННЫЙ ТЕРМОМЕТР НА ОСНОВЕ ДАТЧИКОВ ТЕМПЕРАТУРЫ DS1820
; (DS18S20).
; М/контроллер и DS1820 работают по интерфейсу 1-Wire.
; Работа с двумя датчиками, вычислением контрольной суммы, температурными
; порогами, учетом импульса присутствия, "паразитным" питанием (с использованием
; "форсажного" транзистора) и гашением незначащих нулей. Разрешение 0,1 градус.
; Количество датчиков можно увеличить.
;********************************************************************************
; "Практикум по конструированию устройств на PIC контроллерах".
; Эта программа входит в состав 5-го раздела.
; Авторы: Alberto Rolando Senelyuk (Argentina),
; Корабельников Евгений Александрович (Русь-матушка)
; http://ikarab.narod.ru karabea@lipetsk.ru
;********************************************************************************
; Используется м/контроллер PIC16F84A. Частота кварца 4 Мгц.
; Сигнальный вывод (DQ) датчика DS1820 подключается к выводу RA4.
; Между выводом RA4 и шиной питания подключается подтягивающий резистор
; номиналом 4,7-5,1 кОм.
; DS1820 включается по схеме с "паразитным" питанием (2-проводная линия), т.е.:
; выводы 1 и 3 соединяются - общий провод,
; вывод 2 - сигнальный провод.
; Используется "форсажный" транзистор.
; Информация выводится в русифицированный ЖКИ модуль 16х2 на
; основе м/к HD44780 (по 4-разрядному интерфейсу).
; Функции выводов порта А:
; RA0 - RW (ЖКИ),
; RA1 - RS (ЖКИ),
; RA2 - E (ЖКИ),
; RA4 - вывод DQ датчика DS1820.
;-------------------------------
; Объем программы: 425 команд.
;================================================================================
LIST p=16F84a ; Используется м/контроллер PIC16F84A.
__CONFIG 03FF5H ; Бит защиты выключен, 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 ; Регистр резерва.

16
Count_REM equ 16h ; Регистр хранения остатка измерения.
Count_D_C equ 17h ; Регистр хранения количества градаций
; на 1 градус.
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 ; Возврат по стеку на начало вывода символов


17
; в 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.
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 ; символ "А".
18
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movlw 42h ; На индикацию выводится
bsf PortA,RS ; символ "В".
call ENTER_BF ; ------"------
;----> Возврат по стеку из ПП 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, то обход процедуры вывода надписи
; "АВАРИЯ".
19
movf Mem,W ; Если =1, то копирование содержимого регистра
; оперативной памяти номеров датчиков Mem в
; регистр W.
clrwdt ; Сброс WDT.
;=========================================================
; Определение датчика, показанию которого нужно
; поставить в соответствие надпись "АВАРИЯ".
;=========================================================
addwf PC,F ; Вычисляемый переход.
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.
20
;----> Возврат по стеку из ПП ENTER_BF.
call NORMA ; Переход в ПП вывода надписи "НОРМА:".
;----> Возврат по стеку из ПП NORMA.

;********************************************************************************
; Работа во 2-й строке.
;********************************************************************************
; Выбор места начальной установки курсора во 2-й строке.
;----------------------------------------------------------
DISPLAY_1 movf Mem,W ; Копирование содержимого регистра оперативной
; памяти номеров датчиков 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.
;--------------------------------------------------------------------------------
SDVIG clrf Flag ; Flag=0 (подготовка к работе).
rrf Temp_LSB,F ; Деление на 2.
21
;--------------------------------------------------------------------------------
; Установка (или нет) признака добавления (к показаниям) символа "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, с записью
movwf Temp ; результата операции, через регистр W, в
; регистр Temp.
btfsc Temp,3 ; Анализ состояния бита №3 регистра Temp.
movwf 0 ; Если бит №3 = 1, то содержимое регистра Temp
; копируется в текущий LED.
movlw 30 ; Если бит №3 = 0, то содержимое текущего LED
addwf 0,W ; складывается с константой 30h, с записью
22
movwf Temp ; результата операции, через регистр W, в
; регистр 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 градусов и выше).
;================================================================================
clrwdt ; Сброс WDT.
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.
goto OBHOD_1 ; Если температура 100 и более, то обход
; гашения левого незначащего нуля.
;================================================================================
; Гашение левого незначащего нуля.
;================================================================================
C_00_99 movlw 30h ; В LED1 "лежит"
xorwf LED1,W ; символ "0" или
btfss Status,Z ; другой символ?
goto OBHOD_1 ; Если не "0", то незначащий ноль не гасится.

movlw 20h ; Если "0", то он заменяется на символ "пусто"


bsf PortA,RS ; (20h), т.е. гасится без смещения показания.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto $+4 ; Обход следующих трех команд.
;================================================================================
; Вывод на индикацию двух символов результата измерения
; (в диапазоне от 00 до 99 градусов).
;================================================================================
; Вывод цифры десятков градусов (левой).
;----------------------------------------
OBHOD_1 movf LED1,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED1.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------
; Вывод цифры единиц градусов (правой).
;----------------------------------------
movf LED0,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED0.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;-------------------------------------
; Формирование символа "запятая".
23
;-------------------------------------
movlw 2Ch ; Вывод на индикацию
bsf PortA,RS ; символа "," (2Ch).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;-------------------------------------
; Формирование символов после запятой.
;-------------------------------------
movf Count_REM,W ; Копирование содержимого Count_REM в W.
sublw .16 ; .16 - Count_REM (от .1 до .16) = от .0
; до .15 (W).
call TEXT_1 ; Переход в перекодировщик 16/10.
bsf PortA,RS ; "Плавающая" задержка со стробом под вывод
call ENTER_BF ; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Гашение правого незначащего ("паразитного") нуля.
;================================================================================
movlw 20h ; Гашение (символом "пусто") правого
bsf PortA,RS ; "паразитного" нуля, возникающего в случае
; перехода от 100 к 99 градусам.
call ENTER_BF ; "Плавающая" задержка со стробом
; под вывод данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку.
;********************************************************************************

;================================================================================
; Перекодировщик 16/10.
;======================================================================
; Вычисляемый переход под табл. 3 п/раздела 5/8 "Практикума...".
;----------------------------------------------------------------------
TEXT_1 addwf PC,F ; Приращение PC на величину содержимого W.
retlw 0x30 ; "0"
retlw 0x30 ; "0"
retlw 0x31 ; "1"
retlw 0x32 ; "2"
retlw 0x32 ; "2"
retlw 0x33 ; "3"
retlw 0x34 ; "4"
retlw 0x34 ; "4"
retlw 0x35 ; "5"
retlw 0x35 ; "5"
retlw 0x36 ; "6"
retlw 0x37 ; "7"
retlw 0x37 ; "7"
retlw 0x38 ; "8"
retlw 0x39 ; "9"
retlw 0x39 ; "9"
;----------------------------------------------------------------------
; Вычисляемый переход под табл. 4 п/раздела 5/8 "Практикума...".
;----------------------------------------------------------------------
;;;TEXT_1 addwf PC,F ; Приращение PC на величину содержимого W.
;;; retlw 0x30 ; "0"
;;; retlw 0x31 ; "1"
;;; retlw 0x32 ; "2"
;;; retlw 0x32 ; "2"
;;; retlw 0x33 ; "3"
;;; retlw 0x33 ; "3"
;;; retlw 0x34 ; "4"
;;; retlw 0x34 ; "4"
;;; retlw 0x35 ; "5"
;;; retlw 0x35 ; "5"
;;; retlw 0x36 ; "6"
;;; retlw 0x36 ; "6"
24
;;; retlw 0x37 ; "7"
;;; retlw 0x37 ; "7"
;;; retlw 0x38 ; "8"
;;; retlw 0x39 ; "9"
;========================================================================

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

bsf Status,RP0 ; Переход в 1-й банк.


clrf TrisA ; Все выводы портов А и В
clrf TrisB ; работают на выход.
bcf Status,RP0 ; Переход в 0-й банк.
clrwdt ; Сброс WDT.

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


; инициализации.
;----> Возврат по стеку из ПП LCD_INIT.
clrwdt ; Сброс WDT.
;########################################################################
; Начало работы с датчиком 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 ;

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

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


; (выключение "подпитки").
clrwdt ; Сброс WDT.
;================================================================================
; Инициализация 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.

26
movlw 0 ; Передача шестого байта серийного номера.
movwf Temp ;
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
movlw 57h ; Передача байта контрольной суммы
movwf Temp ; предыдущих семи байтов.
call OUT_BYTE ;
;----> Возврат по стеку из ПП OUT_BYTE.
goto BLOKNOT ; Переход в ПП BLOKNOT.
;--------------------------------------------------------------------------------
; Процедура адресации к датчику №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.

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

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


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

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


; записано 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, то программа
; исполняется далее.
;******************************************************
; После вычисления, результат вычисления контрольной
28
; суммы первых 8-ми байтов "осядет" в регистре CRC_1.
;******************************************************
;--------------------------------------------------------------------------------
; Анализ совпадения или не совпадения числовых значений байтов регистров
; CRC и CRC_1.
;--------------------------------------------------------------------------------
clrwdt ; Сброс WDT.
movf CRC,W ; Вычитание содержимого регистра CRC из
subwf CRC_1,W ; содержимого регистра CRC_1. Результат - в W.
btfss Status,Z ; Результат вычитания =0 или не=0 ?
goto RE_START ; Если не=0, то процедура адресации
; повторяется.
; Если =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
; (признак превышения порога).
bcf Status,C ; Подготовка бита C к дальнейшей работе.
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.
29
;-----------------------------------
; Установка на линии DQ 1.
;-----------------------------------
call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
;-----------------------------------
; Задержка 70 мкс.
;-----------------------------------
movlw .7 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=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, то переход в ПП передачи нуля.
30
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 ; Запись количества бит принимаемого
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".
;================================================================================
31
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 ; Переход на новый цикл передачи бита.
;--------------------------------------------------------------------------------
; Формирование на линии уровня "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 ; Конец программы.

Еще раз напоминаю, что в программу 0_1grad4.asm нужно “закладывать” адреса


тех датчиков, которые у Вас имеются (считываются при помощи
вспомогательного устройства).
С указанными в программе адресами, Ваше устройство работать не будет, так как это
адреса моих датчиков.
По поводу команд clrwdt: часть их, конечно же, можно убрать, но я исходил из
принципа “кашу маслом не испортишь” (плюс, перестраховка).
По поводу уменьшения количества команд: проанализировав текст программы, я не
счел нужным это делать, так как не вижу в этом какого-то существенного выигрыша.
На мой взгляд, с учетом максимально расширенной функциональности обеих программ,
их конструкция оптимальна, и имеет место быть вполне приличная “командная
компрессия”.
По поводу увеличения количества датчиков: рекомендации по наращиванию количества
датчиков даны в конце подраздела 5/4.
Программу 0_1grad4.asm можно “трансформировать” под решение различных и весьма
не слабых задач.
Тут уж, как говорится, Вам и карты в руки. Моя задача - дать то, от чего можно
“оттолкнуться” и снять все “тормоза”.
Температурные датчики это только “пропуск в мир” 1-Wire устройств.
Ниже опубликован список 1-Wire устройств с указанием их функций и кодов устройств.

Групповой код Наименование Описание


01 (DS1990A), DS2401 Только сетевой адрес 1-Wire (серийный номер)
02 (DS1991), (DS1425) Мультиключ (Multikey) iButton, защищенная память
объемом 1152 бит
04 (DS1994), DS2404 4-Кбит энергонезависимое ОЗУ (RAM) с часами,
таймером и сигнальными таймерами (alarms)
05 DS2405 Один адресуемый ключ
06 (DS1993) 4-Кбит энергонезависимое ОЗУ
08 (DS1992) 1-Кбит энергонезависимое ОЗУ
09 (DS1982),DS2502 1-Кбит СППЗУ (EPROM)
0А (DS1995) 16-Кбит энергонезависимое ОЗУ

32
0В (DS1985), DS2505 16-Кбит СППЗУ
0С (DS1996),(DS1996x2), 64…256-Кбит энергонезависимое ОЗУ
(DS1996x4)
0F (DS1986), DS2506 64-Кбит СППЗУ
10 (DS1920), DS1820, Датчик температуры с программируемыми
DS18S20 пороговыми значениями температуры
12 DS2406, DS2407 1-Кбит СППЗУ, двухканальный адресуемый ключ
14 (DS1971), DS2430A 256-бит ЭСППЗУ (EEPROM) и 64-бит однократно
программируемый (ОТР) регистр
18 (DS1963S) 4-Кбит энергонезависимое ОЗУ и процессор SHA-1
1A (DS1963L) 4-Кбит энергонезависимое ОЗУ со счетчиками
циклов записи
1D DS2423 4-Кбит энергонезависимое ОЗУ с внешними
счетчиками
1F DS2409 2-канальный адресуемый ответвитель для
подсетей
20 DS2450 4-канальный АЦП
21 (DS1921), (DS1921H), Датчик/регистратор температуры Thermochron™
(DS1921Z)
22 DS1822 Недорогой датчик температуры
23 (DS1973), DS2433 4-Кбит ЭСППЗУ
24 (DS1904), DS2415 Часы реального времени (RTC)
26 DS2438 Интеллектуальный монитор батарейного питания с
датчиком температуры и АЦП
27 DS2417 Часы реального времени с прерыванием
28 DS18B20 Датчик температуры с регулируемым разрешением
2C DS2890 Одноканальный цифровой потенциометр
30 DS2760 Высокоточный монитор Li-Ion-батареи с датчиком
температуры и тока, встроенный АЦП
33 (DS1961S), DS2432 1-Кбит ЭСППЗУ с процессором SHA-1
91 (DS1981) 512-бит СППЗУ (только по специальному заказу)
96 (DS1955), (DS1957B) Поддерживающий Java™ криптографический
iButton (64-Кбайт ПЗУ, 64…134-Кбайт
энергонезависимое ОЗУ)

Примечание: в скобках указаны устройства в корпусе iButton. Групповые коды (коды


устройств) предоставлены в HEX формате.
Предмет разговора выделен желтым цветом.
Как видите, список выглядит довольно-таки внушительно.
На мой взгляд, особый интерес представляют системы доступа, которые можно
сконструировать на “базе” 1-Wire устройств.
Бог даст, и до этого доберусь, а пока уясните то, что “выдано на гора”.
Поле деятельности - широчайшее.
Я даже злюсь на то, что в сутках всего 24 часа и мои физические возможности
ограничены.
В мире современной электроники столько всего интересного и заманчивого, что просто
“глаза разбегаются”. И того хочется, и этого …
Но ничего, потихоньку – помаленьку буду “свою копну молотить”. Вода камень точит.
Просто “канцелярия” много времени требует, но и без нее никак нельзя, так как, если
не объяснишь, то и понимания не будет.
Лично я, в результате работы с термодатчиками, получил большое удовольствие.
Надеюсь на то, что то же самое, так или иначе, отразится и на Вас и придаст Вам
уверенность в своих силах.

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

34

Оценить