DS1820 может измерять температуру с более высоким, чем 0,5 градусов, разрешением
(0,1 градус), но для этого нужно произвести вычисления по формуле:
1
Что получается?
А получается “геморрой”, которые разработчики, не мудрствуя лукаво, подарили всем
нам (могли бы и “подсуетиться”…).
Его “материальным воплощением” и является приведенная выше формула.
Ладно, данность есть данность и придется работать с тем, что есть, уповая на
здравый смысл разработчиков.
Уповать-то конечно можно, но и проверить не помешает.
В необходимости последнего, лично меня, убедил грандиозный “бардак”, который
“порождает” указанная выше формула.
Я просмотрел несколько программ, в которых используется данное вычисление и
убедился, что их авторы просто бездумно копируют соответствующую процедуру
вычисления, предлагаемую разработчиками.
Ни один из них не только не пытался “сразиться с этим зверем”, но даже и не
удосужился “убить” регистр Count_D_C (см. выше), а это “на поверхности лежит”.
Что, по факту, имеется?
В приложении к ПИКам, имеется “мозгозаворотная”, “тормозная” процедура вычисления
“массой” в 90 команд, плюс проблемы с дальнейшим использованием результата этого
вычисления, плюс “куча” дополнительных регистров общего назначения и т.д.
Вопрос: “Ради чего льется такая масса крови”?
Это можно было бы как-то оправдать, если бы был толк в части касающейся
погрешности измерения (в пределах одного градуса).
Полез в математику.
Что означает (16 – Count_REM)/16 ?
Count_REM это остаток от измерения, который всегда меньше .16-ти, следовательно,
результат этого вычисления будет представлять собой десятичную дробь с нулем в
целой части и “массой” от одного до 4-х знаков после запятой, кроме случая
(16 – 16)/16 = 0.
Остальная часть формулы, в этом отношении, “погоды не делает”, так как, после
запятой, будет наблюдаться такая же “картина” (а именно это и интересует).
Что сие означает?
А означает это то, что придется производить округление, ведь нужен только один знак
после запятой.
Если от этого будет “точностный” толк, то можно и округлить.
Проверяю.
Ниже Вы видите пример “голого”, математического расчета, произведенного по
указанной выше формуле, с TEMP_READ = 20 и округлением до одной десятой.
Что касается числового значения TEMP_READ, то оно может быть различным. Суть не
в нем, а в том, что получается после запятой.
Табл. 1
16 – Count_REM (16-Count_REM) /16 TEMP_READ - 0.25 + Округление “Диаграмма”
(16 – Count_REM)/16
16 -1 = 15 0,9375 20,6875 20,7
16 – 2 = 14 0,875 20,625 20,6
16 – 3 = 13 0,8125 20,5625 20,6
16 – 4 = 12 0,75 20,5 20,5
16 – 5 = 11 0,6875 20,4375 20,4
16 – 6 = 10 0,625 20,375 20,4
16 – 7 = 9 0,5625 20,3125 20,3
16 – 8 = 8 0,5 20,25 20,3
16 – 9 = 7 0,4375 20,1875 20,2
16 – 10 = 6 0,375 20,125 20,1
16 – 11 = 5 0,3125 20,0625 20,1
16 – 12 = 4 0,25 20 20,0
16 – 13 = 3 0,1875 19,9375 19,9
16 – 14 = 2 0,125 19,875 19,9
16 – 15 = 1 0,0625 19,8125 19,8
16 – 16 = 0 0 19,75 19,8
2
Примечание: опытным путем (засылка “шпиона” и т.д.) я выяснил, что в регистре
Count_REM “лежит” одно число из числового диапазона .1 … .16 (см. табл. 1), то есть,
число .0 в нем никогда не “лежит”.
По поводу таблицы 1 могут быть разные суждения.
С точки зрения “голой” математики, число 0,25 вообще лишнее на этом “празднике
жизни”, так как оно “порждает” смещение результата вычисления относительно здравого
смысла (например, там где должно быть 20,0, получается 19,8 и т.д.).
Но так или иначе, неоспоримым фактом является то, что величина температурных
интервалов неравномерна (“гуляет”), что означает наличие “плавающей” погрешности
измерения температуры в пределах одного градуса.
И за это “великое счастье” еще нужно и несоразмерно “заплатить” (см. выше)!
“Да видел я такое счастье в гробу, в белых тапках”, как сказал один очень уважаемый
человек. И это как раз тот случай. Присоединяюсь.
Но мало быть “гробовых дел мастером”, для этого много ума не требуется, а нужно
предложить взамен “трупа” какой-то “живой организм”, который бы был, как минимум,
не хуже “покойника”, а в идеале - лучше, иначе какой смысл в этих “похоронах”?
Кстати, на Руси, с этим всегда были и есть большие проблемы: огреют работягу
дубиной по голове (отправят к праотцам), а затем делают круглые глаза и искренне
удивляются, что у горна (и т.д.) стоять некому и демография какая-то неправильная
получается.
Чур меня! Избавь Бог от такой напасти.
А раз это так, то нужно “извилиной шевелить”. Другого не дано.
“Вражеского шпиона (формулу) арестовываю и сажаю на нары”.
Далее следуют процедуры “выкручивания конечностей” и “дергания зубов”, в результате
чего “шпион раскололся” и выдал самую главную свою тайну: “центром вселенной”
является регистр Count_REM, в котором “лежит” “хвостик” (остаток) измерения.
Отдыхайте, господин “шпион”, вы больше не нужны.
Работаю с “важняком”. Все внимание на него.
Примечание: может также потребоваться константа .16 (но не регистр Count_D_C! Он
“убит”), хотя, забегая вперед, скажу, что можно обойтись и без нее.
Итак, в пределах одного градуса, имеется 16 градаций.
Для того чтобы вывести на индикацию десятые доли градуса, нужно 10 градаций.
16 : 10 = 1,6, следовательно, если “привязаться” к наиболее привычной и удобной для
восприятия форме представления чисел, то получится следующее соответствие:
Табл. 2
Десятые доли градуса 0 1 2 3 4 5 6 7 8 9
Остаток от измерения 0 1,6 3,2 4,8 6,4 8 9,6 11,2 12,8 14,4
3
Получается вот что:
Табл. 3
Десятые доли градуса 0 1 2 3 4 5 6 7 8 9
Остаток от измерения 0 2 3 5 6 8 10 11 13 14
Вы видите в нижней строке только целые числа, а это уже совсем другая “опера”, так
как заумные вычисления “дали дуба” (не нужны).
Принцип формирования десятичной цифры после запятой, “заложенный” в эту таблицу,
по погрешности, как минимум, не хуже (если не лучше) того “счастья”, которое
предлагают разработчики, плюс на изумление простой (и понятный) способ его
программной реализации (нет вычислений).
Плюс, целая часть результата замера температуры (то, что левее запятой) “и пальцем
не тронута”.
То, что правее и левее запятой, образно выражаясь, “живет отдельной друг от друга
жизнью” в том смысле, что, после считывания байтов из области оперативной памяти
DS1820, взаимовлияние одного на другое (и наоборот) отсутствует.
Плюс, обеспечивается “простор для маневра” в том смысле, что можно без проблем,
сделать, например, разрешение в 0,2 градуса или, на свой лад, изменить “привязки”
чисел нижней строки таблицы к числам верхней строки таблицы.
Что касается последнего, то можно, например, сделать так:
Табл. 4
Десятые доли градуса 0 1 2 3 4 5 6 7 8 9
Остаток от измерения 0 1 2 4 6 8 10 12 14 15
;********************************************************************************
; 0_1grad1.asm ЭЛЕКТРОННЫЙ ТЕРМОМЕТР НА ОСНОВЕ ДАТЧИКА ТЕМПЕРАТУРЫ DS1820
; М/контроллер и 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 включается по схеме с активным питанием, т.е.: вывод 1 - общий,
; вывод 2 - сигнальный,
; вывод 3 - питание (+5в).
; Информация выводится в русифицированный ЖКИ модуль 16х2 на
; основе м/к HD44780 (по 4-разрядному интерфейсу).
; Функции выводов порта А:
; RA0 - RW (ЖКИ),
; RA1 - RS (ЖКИ),
; RA2 - E (ЖКИ),
; RA4 - вывод DQ датчика DS1820.
;-------------------------------
; Объем программы: 254 команды.
;================================================================================
LIST p=16F84a ; Используется м/контроллер PIC16F84A.
__CONFIG 03FF1H ; Бит защиты выключен, WDT выключен,
; XT-генератор.
;================================================================================
; Определение положения регистров специального назначения.
;================================================================================
IndF equ 00h ; Доступ к памяти через FSR.
PC equ 02h ; Счетчик команд.
Status equ 03h ; Регистр Status.
FSR equ 04h ; Регистр косвенной адресации.
PortA equ 05h ; Регистр Port A.
TrisA equ 05h ; Регистр Tris A-банк1.
PortB equ 06h ; Регистр Port B.
TrisB equ 06h ; Регистр Tris B-банк1.
;================================================================================
; Определение названия и положения регистров общего назачения.
;================================================================================
N equ 0Ch ; Счетчик битов.
Temp equ 0Dh ; Многофункциональный регистр временного
; хранения.
Temp_MSB equ 0Eh ; Байт знака температуры (старший байт).
Temp_LSB equ 0Fh ; Байт значения температуры (младший байт).
Flag equ 10h ; Регистр флагов.
Count equ 11h ; Многофункциональный счетчик.
LED0 equ 12h ; Регистры двоично-десятичного
LED1 equ 14h ; преобразования.
Count_REM equ 15h ; Применяются при измерении температуры
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
5
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присваивание битам названий.
;================================================================================
C equ 0 ; Флаг переноса-заема.
Z equ 2 ; Флаг нулевого результата.
RP0 equ 5 ; Бит выбора банка.
DQ equ 4 ; Бит порта A для управления DS1820.
RW equ 0 ; Бит №0 регистра PortA (вывод RA0 - линия RW)
RS equ 1 ; Бит №1 регистра PortA (вывод RA1 - линия RS)
E equ 2 ; Бит №2 регистра PortA (вывод RA2 - линия E)
BF equ 7 ; Бит №7 регистра PortB.
;================================================================================
org 0 ; Начать выполнение программы
goto START ; с подпрограммы START.
;********************************************************************************
;********************************************************************************
; ------------------------ "РАБОЧАЯ" ЧАСТЬ ПРОГРАММЫ ----------------------
;********************************************************************************
; "Рабочая" инициализация ЖКИ модуля.
;================================================================================
LCD_INIT movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00101000' ; Установка: 4-разрядный интерфейс, 2 строки,
; 5х7 точек.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00101000.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00001100' ; Установка: дисплей включен, видимое
; отображение курсора выключено.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00001100.
;----> Возврат по стеку из ПП ENTER_BF.
movlw b'00000001' ; Установка: очистка дисплея со сбросом
; данных, установка курсора в начало
; 1-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 00000001.
;----> Возврат по стеку из ПП ENTER_BF.
return ; Возврат по стеку на начало вывода символов
; в 1-ю строку.
;================================================================================
; ПП "плавающей" задержки на основе анализа состояния флага занятости BF
; (вариант для 4-разрядного интерфейса).
;================================================================================
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.
;------------------------------------------
; Запуск в работу младшего п/байта (строб).
6
;------------------------------------------
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-й банк.
;********************************************************************************
; Подпрограмма вывода на индикацию.
;********************************************************************************
; Выбор 6-го слева знакоместа 2-й строки.
;----------------------------------------------------------
DISPLAY movlw b'11000101' ; Выбор ячейки DD RAM с адресом 45h, что
; соответствует установке курсора в 6-е слева
; знакоместо 2-й строки.
call ENTER_BF ; "Плавающая" задержка со стробом под команду
; 11000101.
;----> Возврат по стеку из ПП ENTER_BF.
;----------------------------------------------------------
; Определение и вывод на индикацию знака температуры (+/-).
;----------------------------------------------------------
btfsc Temp_MSB,0 ; В бите №0 старшего байта температуры 0или1 ?
goto MINUS ; Если 1, то переход в ПП MINUS.
movlw 2Bh ; Если 0, то на индикацию
bsf PortA,RS ; выводится символ "+".
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
goto SDVIG ; После вывода на индикацию символа "+",
; переход на обработку младшего байта
; температуры.
MINUS movlw 2Dh ; На индикацию выводится
7
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.
;--------------------------------------------
; btfsc Status,C ; УДАЛЕНО.
; bsf Flag,0 ; УДАЛЕНО.
;--------------------------------------------------------------------------------
; Установка (или нет) признака добавления (к показаниям) символа "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 ;
;********************************************************************************
; Процедура преобразования кода.
;================================================================================
ASC movlw 30h ; Запись в регистр W числа 30h.
iorwf LED0,F ; Логическое "ИЛИ" содержимого регистра W и
; регистра LED0 с сохранением результата
; в LED0.
iorwf LED1,F ; То же самое для LED1.
;********************************************************************************
; Вывод на индикацию результата измерения.
;********************************************************************************
; Вывод (или нет) на индикацию символа "1" (выводится при Т=100 градусов и выше).
;================================================================================
btfss Flag,7 ; Бит №7 регистра Flag =0 или =1 ?
goto C_00_99 ; Если =0, то символ "1" на индикацию не
; выводится.
movlw 31h ; Если =1, то символ "1" (31h)
bsf PortA,RS ; на индикацию выводится.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;================================================================================
; Вывод на индикацию двух символов результата измерения
; (в диапазоне от 00 до 99 градусов).
;================================================================================
C_00_99 movf LED1,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED1.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
movf LED0,W ; Вывод на индикацию байта,
bsf PortA,RS ; записанного в регистре LED0.
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
9
;----> Возврат по стеку из ПП ENTER_BF.
;========================================================================
; Формирование запятой и символов после запятой.
;========================================================================
; Формирование запятой.
;-------------------------------------
movlw 2Ch ; Вывод на индикацию
bsf PortA,RS ; символа "," (2Ch).
call ENTER_BF ; "Плавающая" задержка со стробом под вывод
; данных на индикацию.
;----> Возврат по стеку из ПП ENTER_BF.
;-----------------------------------------------
; btfsc Flag,0 ; УДАЛЕНО.
; goto _5 ; УДАЛЕНО.
; movlw 30h ; УДАЛЕНО.
; bsf PortA,RS ; УДАЛЕНО.
; call ENTER_BF ; УДАЛЕНО.
;----> Возврат по стеку из ПП ENTER_BF.
; return ; УДАЛЕНО.
;_5 movlw 35h ; УДАЛЕНО.
; bsf PortA,RS ; УДАЛЕНО.
; 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.
return ; Возврат по стеку.
;********************************************************************************
;========================================================================
; Подпрограммы табличного вычисляемого перехода.
;========================================================================
; Вычисляемый переход под тестовую надпись.
;----------------------------------------------------------------------
TEXT addwf PC,F ; Приращение PC на величину содержимого W.
retlw 0x20 ; "пусто"
retlw 0x20 ; "пусто"
retlw 0x54 ; "T"
retlw 0x45 ; "E"
retlw 0x4D ; "M"
retlw 0xA8 ; "П"
retlw 0x45 ; "E"
retlw 0x50 ; "P"
retlw 0x41 ; "A"
retlw 0x54 ; "T"
retlw 0xA9 ; "У"
retlw 0x50 ; "P"
retlw 0x41 ; "A"
retlw 0x3A ; ":"
retlw 0x20 ; "пусто"
retlw 0x20 ; "пусто"
;======================================================================
; Перекодировщик 16/10.
;======================================================================
; Вычисляемый переход под табл. 3 п/раздела 5/8 "Практикума...".
;----------------------------------------------------------------------
TEXT_1 addwf PC,F ; Приращение PC на величину содержимого W.
10
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"
;;; 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-й банк.
11
; следующего символа таблицы.
goto WR_1 ; Если результат декремента не=0, то переход
; в ПП WR_1.
; Если результат декремента =0, то программа
; исполняется далее.
;################################################################################
; Начало работы с датчиком 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.
;--------------------------------------------------------------------------------
; Команда Start_Conv (44h).
; Эта команда запускает процесс преобразования температуры. В течение времени ее
; исполнения, DS1820 не реагирует на команды "мастера".
; Это время нужно просто переждать.
;--------------------------------------------------------------------------------
movlw 44h ; Запись команды 44h
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;--------------------------------------------------------------------------------
; Ожидание завершения процесса преобразования температуры.
; То что Вы видите ниже, есть один из способов реализации "плавающей" (следящей)
; задержки (можно применить фиксированную задержку).
;--------------------------------------------------------------------------------
WAIT call IN_BYTE ; Переход в ПП приема байта IN_BYTE.
;----> Возврат по стеку из ПП IN_BYTE.
movlw b'11111111' ; Запись в W числа FFh.
subwf Temp,W ; Temp - FFh = ...
btfss Status,Z ; Z=0 или Z=1 (нулевой результат)?
goto WAIT ; Если Z=0, то ждем дальше.
; Если Z=1 (Temp заполнен единицами, то есть,
; на линии появился и надежно зафиксировался
; уровень 1), то программа исполняется далее.
;--------------------------------------------------------------------------------
; Инициализация DS1820.
;--------------------------------------------------------------------------------
call DQ_INIT ; Инициализация DS1820.
;----> Возврат по стеку из ПП DQ_INIT.
;--------------------------------------------------------------------------------
; Еще одна команда Skip_ROM (CCh).
;--------------------------------------------------------------------------------
movlw 0CCh ; Запись команды CCh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
;----> Возврат по стеку из ПП OUT_BYTE.
;--------------------------------------------------------------------------------
; Команда Read Scratchpad (BEh).
; Чтение содержимого блокнотной памяти в части касающейся байтов температуры.
;--------------------------------------------------------------------------------
movlw 0BEh ; Запись команды BEh
movwf Temp ; в регистр Temp.
call OUT_BYTE ; Переход в ПП передачи байта OUT_BYTE.
12
;----> Возврат по стеку из ПП OUT_BYTE.
;------------------------------------------------------------------------
; Чтение содержимого области оперативной памяти DS1820.
;------------------------------------------------------------------------
call IN_BYTE ; ПРИЕМ МЛАДШЕГО БАЙТА ТЕМПЕРАТУРЫ.
;----> Возврат по стеку из ПП IN_BYTE.
movwf Temp_LSB ; Запись принятого байта в регистр Temp_LSB.
;================================================================================
; Подпрограмма нициализации 1-Wire устройства (DS1820).
;================================================================================
DQ_INIT call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
call PIN_LO ; Установка на линии нуля.
;----> Возврат по стеку из ПП PIN_LO.
movlw .60 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
call PIN_HI ; Установка вывода в высокоимпедансное
; состояние: за счет подтягивающего резистора,
; на линии устанавливается 1.
;----> Возврат по стеку из ПП PIN_HI.
movlw .60 ; Установка количества проходов по 10мкс.
call PAUSE_X ; Переход в ПП задержки
; (задержка=60х10=600мкс.).
;----> Возврат по стеку из ПП PAUSE_X.
return ; Возврат по стеку.
;********************************************************************************
; Подпрограмма задержки.
;================================================================================
13
; Задание количества проходов по 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.
;********************************************************************************
; ВЫЧИСЛЕНИЕ ТЕМПЕРАТУРЫ.
; T=TEMP_READ-0.25+(Count_D_C - Count_REM)/Count_D_C
;********************************************************************************
; R3:R2 = Count_D_C - Count_REM
movf Count_REM,W ;
subwf Count_D_C,W ; Count_D_C - Count_REM
movwf R2 ;
clrf R3 ;
;----------------------------------------------
; R1:R0 = R3:R2 * 10
movlw 0x0A ;
movwf R4 ;
clrf R5 ;
call mul_16 ; R1:R0 = R3:R2 * R5:R4
;----------------------------------------------
16
; R1:R0 = R1:R0 / Count_D_C
movf R0,W ;
movwf R2 ;
movf R1,W ;
movwf R3 ;
movf Count_D_C,W ;
movwf R4 ;
clrf R5 ;
call div_16 ; R1:R0 = R3:R2 / R5:R4
;----------------------------------------------
; R7:R6 = R1:R0 - 2;
movlw 0xFE ;
addwf R0,F ;
btfss Status,C ;
decf R1,F ; Перенос.
movf R0,W ;
movwf R6 ;
movf R1,W ;
movwf R7 ;
;----------------------------------------------
; R1:R0 = TEMP_READ * 10
rrf Temp_MSB,0 ;
rrf Temp_LSB,0 ; В W получился TEMP_READ.
movwf R2 ;
movf Temp_MSB,W ;
movwf R3 ;
movlw d'10' ;
movwf R4 ;
clrf R5 ;
call mul_16 ; R1:R0 = R3:R2 * R5:R4
;----------------------------------------------
; Temp = R1:R0 + R7:R6
movf R6,W ;
addwf R0,F ;
btfsc Status,C ;
incf R1,F ; Перенос.
movf R7,W ;
addwf R1,F ;
movf R0,W ;
movwf Temp_LSB ;
movf R1,W ;
movwf Temp_MSB ;
GT_exit:
return ;
;********************************************************************************
........................
........................
;=============================================================================
; Умножение. Использует R0,R1,R2,R3,R4,R5.
;=============================================================================
mul_16: ; R1:R0 = R3:R2 * R5:R4
clrf R0 ;
clrf R1 ;
mul16_Loop:
; R5:R4--;
decf R4,F ;
btfsc R4,7 ;
decf R5,F ;
btfsc R5,7 ;
goto mul16_exit ;
; R1:R0 += R3:R2.
movf R2,0 ;
addwf R0,1 ;
btfsc Status,C ;
17
incf R1,1 ; Перенос.
movf R3,0 ;
addwf R1,1 ;
clrwdt ;
goto mul16_Loop ;
mul16_exit:
return ;
;=============================================================================
; Деление. Использует R0,R1,R2,R3,R4,R5.
;=============================================================================
div_16: ; R1:R0 = R3:R2 / R5:R4
; В R3:R2 остаток.
clrf R0 ;
clrf R1 ;
movf R4,W ;
btfss Status,Z ;
goto div16_Loop ;
movf R5,W ;
btfss Status,Z ;
goto div16_Loop ;
return ;
div16_Loop:
; Вычитаем RR5:RR4 из RR3:RR2.
movf R4,W ;
subwf R2,F ; F = F - W
btfss Status,C ;
decf R3,F ; Перенос.
btfsc R3,7 ;
goto div16_exit ;
movf R5,W ;
subwf R3,F ;
btfss Status,C ;
goto div16_exit ;
; Увеличиваем частное на 1.
movlw 1 ;
addwf R0,F ;
btfsc Status,C ;
incf R1,F ;
clrwdt ;
goto div16_Loop ;
div16_exit:
movf R4,W ;
addwf R2,F ;
; btfss Status,C ;
incf R3,F ; Перенос.
movf R5,W ;
addwf R3,F ;
return ;
;=============================================================================