Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » DS18B20 - помогите пожалуйста


DS18B20 - помогите пожалуйста

Сообщений 1 страница 30 из 62

1

Код не работает ни в Proteus ни в железе. В чем ошибка?

$regfile = "2313def.dat"                                    'работаем с at90s2313
$crystal = 4000000
Config Lcd = 16 * 2                                         ' дисплей 2 строки по 16 символов
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portb.6       ' конфигурируем дисплей

Config 1wire = Portd.5                                      ' на эту ножку подключим DS18B20 и подтягивающий резистор на 4,7 ком к + питания

Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Signtemperatura As String * 1
Dim T1 As Byte
Dim T2 As Byte
Dim I As Integer

Do
1wreset
1wwrite &HCC                                                ' Выдаем команду чтения ПЗУ
1wwrite &H44                                                ' Запуск измерения

Waitms 750                                                  ' Ждем окончания преобразования

1wreset
1wwrite &HCC
1wwrite &HBE                                                ' Команда чтения ОЗУ датчика

Byte0 = 1wread()                                            ' Читаем нулевой байт

Byte1 = 1wread()                                            ' Читаем первый байт

If Byte1 >= 248 Then                                        ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF

Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Signtemperatura = "-"

Else
Signtemperatura = "+"
End If

T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)

T1 = T1 + T2                                                ' Формирмируем результам и выдаем его на индикатор. Команда LCD сама преобразует его в десятичный вид

Cls
Lcd Signtemperatura ; T1 ; "C"
Wait 2
Loop
End

0

2

Всем спасибо. Разобрался.

0

3

ну и что было?

0

4

Два датчика DS18B20
Кому интересно - вот код для обработкb двух датчиков соедененных паралельно и висящих на одной шине данных.
Подскажите как можно оптимизировать код???? и еще При инициализации первые 3 сек температура показывается +88 градусов, дальше все ок!
Подозреваю гдето нет задержки. Как правильно реализовать округление???? Тут оно через темную дырочку.

Код:
'программа обработки двух датчиков типа ds18b20
'и вывода показаний температуры на дисплей.
'температура показывается со знаком и десятыми
'градуса цельсия. замер происходит раз в 3 секунды.

'mailton p-a-h-a@yaandex.ru

$regfile = "m32def.dat"
$crystal = 8000000
$lib "lcd4.lbx"
Config 1wire = Portc.7                                      'порт, куда садим ногами два датчика типа ds18b20
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.2 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 2                                         'используем дисплей на 2 строчки по 16 знакомест в каждой
Cursor Off                                                  'выключить курсор дисплея
Config Timer1 = Timer , Prescale = 64                       'конфигурируем таймер и ставим его делитель 64. таймер будет переполнятся 2 раза в секунду
On Timer1 Pulse:                                            'при переполнении таймера запустить подпрограмму Pulse
Enable Interrupts                                           'разрешить прерывания
Enable Timer1                                               'разрешить таймер1
'--------задаем переменные------------------
Dim S05 As Byte
Dim W As Word
Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte
Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Signtemperatura As String * 1
Dim T1 As Single
Dim T2 As Integer
Dim Ttemp As Byte
Dim Hh As Byte
Dim Mm As Byte
Dim X As Byte
'-----------считываем 64 битные номера датчиков----------------

W = 1wirecount()
Dsid1(1) = 1wsearchfirst()
Do
 Dsid2(1) = 1wsearchnext()
Loop Until Err = 1
Cls
'_________________________основной цикл программы________________________________________________________
Do
If S05 >= 6 Then                                            'если щетчик таймер насчитал 3 секунды (таймер срабатывает 2 раза в секунду при 8 мГц
S05 = 0                                                     'обнуляем щетчик таймер
Gosub Convallt                                              'переходим на подпрограмму подачи запросов в датчик температуры
1wverify Dsid1(1)
X = 1                                                       'переменная номера строки дисплея
Gosub Temperature                                           'переходим на подпрограмму подсчета и вывода температуры на дисплей
1wverify Dsid2(1)
X = 2
Gosub Temperature
End If
  Loop
End
'_________________________________________________________________________________
Convallt:
 1wreset                                                    ' reset the bus
 1wwrite &HCC                                               ' skip rom
 1wwrite &H44
' Waitms 500
Return                                                      ' возврат в основной цикл на место, откуда пришли
'----------------
Temperature:
If Err = 0 Then
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт
If Byte1 >= 248 Then                                        ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Signtemperatura = "-"
Else
Signtemperatura = "+"
End If
T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
Hh = Fix(t1)                                                'отсекаем от температуры все после запятой
Ttemp = T1 * 10                                             '
Mm = Ttemp Mod 10                                           'берем десятичную часть температуры
Locate X , 1                                                'указываем куда вывести на дисплей
Lcd Signtemperatura ; Hh ; "." ; Mm                         'выводим целую часть потом рисуем точку потом десятую часть температуры
End If
Return
'-----------------
Pulse:                                                      'подпрограмма обработки переполнения таймера1
Incr S05                                                    ' S05 = S05+1
Return

0

5

If S05 >= 6 Then                                            'если щетчик таймер насчитал 3 секунды (таймер срабатывает 2 раза в секунду при 8 мГц
S05 = 0                                                     'обнуляем щетчик таймер
Gosub Convallt 

У ж не тут-ли собака порыдась?
Пока не наберешь 3 секунды температуру не читаешь...

0

6

AlexandrM написал(а):

У ж не тут-ли собака порыдась?Пока не наберешь 3 секунды температуру не читаешь...

Да действительно! Собака зарыта сдесь!
Писал основываясь на инфу с этого  же форума что датчик греется при частом опросе. Сейчас провел эксперимент - опрос каждые 700мс. Температура держится стабильно, но датчик подпаян толстыми проводами.

чтоб постоянно опрашивать надо выбросить строчки о прирывании и счетчик

Код:
Config Timer1 = Timer , Prescale = 64                       'конфигурируем таймер и ставим его делитель 64. таймер будет переполнятся 2 раза в секунду
On Timer1 Pulse:                                            'при переполнении таймера запустить подпрограмму Pulse
Enable Interrupts                                           'разрешить прерывания
Dim S05 As Byte

.....бла бла бла
If S05 >= 6 Then                                            'если щетчик таймер насчитал 3 секунды (таймер срабатывает 2 раза в секунду при 8 мГц
S05  =  0
....бла бла бла
end if
.....бла бла бла
Pulse:                                                      'подпрограмма обработки переполнения таймера1
Incr S05                                                    ' S05 = S05+1
Return

Как коротко отбросить лишние цифры после запятой???

Код:
't1 посчитали........

Hh = Fix(t1)                                                'отсекаем от температуры все после запятой
Ttemp = T1 * 10                                             '
Mm = Ttemp Mod 10                                           'берем десятичную часть температуры
Locate X , 1                                                'указываем куда вывести на дисплей
Lcd Signtemperatura ; Hh ; "." ; Mm                         'выводим целую часть потом рисуем точку потом десятую часть температуры

0

7

Ребята а почему у меня при комнатной температуре в этом коде +3,5 высвечивает помогите!

0

8

чтоб не плодить тем про 18b20 напишу здесь...
кто нибудь пользовался другим алгоритмом преобразования данных с датчика, а то стандартный алгоритм (тот что в первом посте), дает ошибку в один градус при температуре ниже ноля, из-за двух показаний "+0" и "-0" (ну вы все в курсе наверно :yep: ), и еще как определить наличие датчика? Хотелось бы выводить сообщение о не подключенном датчике, а не отображать 0 как это происходит сейчас.

0

9

Pasha написал(а):

Два датчика DS18B20
Кому интересно - вот код для обработкb двух датчиков соедененных паралельно и висящих на одной шине данных.
Подскажите как можно оптимизировать код???? и еще При инициализации первые 3 сек температура показывается +88 градусов, дальше все ок!
Подозреваю гдето нет задержки. Как правильно реализовать округление???? Тут оно через темную дырочку.
Код:

'программа обработки двух датчиков типа ds18b20
'и вывода показаний температуры на дисплей.
'температура показывается со знаком и десятыми
'градуса цельсия. замер происходит раз в 3 секунды.

'mailton p-a-h-a@yaandex.ru

$regfile = "m32def.dat"
$crystal = 8000000
$lib "lcd4.lbx"
Config 1wire = Portc.7                                      'порт, куда садим ногами два датчика типа ds18b20
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.2 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 16 * 2                                         'используем дисплей на 2 строчки по 16 знакомест в каждой
Cursor Off                                                  'выключить курсор дисплея
Config Timer1 = Timer , Prescale = 64                       'конфигурируем таймер и ставим его делитель 64. таймер будет переполнятся 2 раза в секунду
On Timer1 Pulse:                                            'при переполнении таймера запустить подпрограмму Pulse
Enable Interrupts                                           'разрешить прерывания
Enable Timer1                                               'разрешить таймер1
'--------задаем переменные------------------
Dim S05 As Byte
Dim W As Word
Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte
Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Signtemperatura As String * 1
Dim T1 As Single
Dim T2 As Integer
Dim Ttemp As Byte
Dim Hh As Byte
Dim Mm As Byte
Dim X As Byte
'-----------считываем 64 битные номера датчиков----------------

W = 1wirecount()
Dsid1(1) = 1wsearchfirst()
Do
Dsid2(1) = 1wsearchnext()
Loop Until Err = 1
Cls
'_________________________основной цикл программы________________________________________________________
Do
If S05 >= 6 Then                                            'если щетчик таймер насчитал 3 секунды (таймер срабатывает 2 раза в секунду при 8 мГц
S05 = 0                                                     'обнуляем щетчик таймер
Gosub Convallt                                              'переходим на подпрограмму подачи запросов в датчик температуры
1wverify Dsid1(1)
X = 1                                                       'переменная номера строки дисплея
Gosub Temperature                                           'переходим на подпрограмму подсчета и вывода температуры на дисплей
1wverify Dsid2(1)
X = 2
Gosub Temperature
End If
  Loop
End
'_________________________________________________________________________________
Convallt:
1wreset                                                    ' reset the bus
1wwrite &HCC                                               ' skip rom
1wwrite &H44
' Waitms 500
Return                                                      ' возврат в основной цикл на место, откуда пришли
'----------------
Temperature:
If Err = 0 Then
1wwrite &HBE
Byte0 = 1wread()                                            ' Читаем нулевой байт
Byte1 = 1wread()                                            ' Читаем первый байт
If Byte1 >= 248 Then                                        ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Signtemperatura = "-"
Else
Signtemperatura = "+"
End If
T1 = Byte0 / 16                                             ' Сдвигаем нулевой байт вправо на 4 бита (2*2*2*2=16)
T2 = Byte1 * 16                                             ' Сдвигаем первый байт влево на 4 бита (2*2*2*2=16)
T1 = T1 + T2
Hh = Fix(t1)                                                'отсекаем от температуры все после запятой
Ttemp = T1 * 10                                             '
Mm = Ttemp Mod 10                                           'берем десятичную часть температуры
Locate X , 1                                                'указываем куда вывести на дисплей
Lcd Signtemperatura ; Hh ; "." ; Mm                         'выводим целую часть потом рисуем точку потом десятую часть температуры
End If
Return
'-----------------
Pulse:                                                      'подпрограмма обработки переполнения таймера1
Incr S05                                                    ' S05 = S05+1

Всем привет. Не пойму - или лыжи не едут или я уже "приехал". Этот же самый код повторяю у себя, но .... Определяются 2 датчика (если один откинуть , то вместо его определяется оставшийся), но если подключены оба, то показания обрабатываюся только с одного, а индицируются, как бы с двух датчиков, не пойму что за черт... :(
помогите плиз.
Или может у кого есть пример как обрабатывать 2 датчика на разных портах МК?

Отредактировано Sergik (2011-03-02 03:20:59)

0

10

разобрался. Сам дурак. При индикации был наложения друг на друга, этот код у меня как подпрограмма, поэтому надо будет пару переменных для индикации добавить и оформить по другому.
Вопрос о 2х датчиках на разных портах по прежнему открыт, помогите с кодом плиз, а то нигде не могу примеры найти.

Отредактировано Sergik (2011-03-03 18:02:39)

0

11

Присоединяюсь к посту выше... только интересует код 2ух и более датчиков на разных пинах порта. (т.е. по одному датчику на пин)
Как это реализовать в BASCOM ? Народ кто знает как это сделать по возможности конечно, выделите несколько минут киньте код пжлст...   скорее всего будет признателен не один человек.

0

12

В командах можно задавать конкретный пин.
Например:
1WRESET , PORT , PIN
1WWRITE var1 , bytes , port , pin

Сейчас пишу такую прогу, у меня на одной ноге
DS18S20 на другой DS1990A.
Пока инициализация проходит в Протеусе,
сейчас на макете попробую.

0

13

Проверил - работает.

Код:
1wreset Pina , 7
If Err = 1 Then
   Lcd "Err DS18"
Else
   1wwrite &H33 , 1 , Pina , 7                              ' read rom
   T_buff(1) = 1wread(9 , Pina , 7)
   For Count = 1 To 9
      Lcd Hex(t_buff(count))
   Next
   Locate 2 , 1
   Lcd "DS18x Ok"
End If

Wait 2
Cls

1wreset Pina , 3
If Err = 1 Then
   Lcd "Err DS19"
Else
   1wwrite &H33 , 1 , Pina , 3                              ' read rom
   K_buff(1) = 1wread(9 , Pina , 3)
   For Count = 1 To 9
      Lcd Hex(k_buff(count))
   Next
   Locate 2 , 1
   Lcd "DS19x Ok"
End If
Wait 2

Это тест, читает ROM датчика и ключа и выводит на LCD.

0

14

вот тут писали о 2х датчиках

0

15

alex_r61 и Pasha Спсб большое !  Сам сегодня добил эту проблему. Ковырнул HELP Bascom.  :disappointed:
Вот это в протеусе работает. В железе вот вопрос... нада пробовать.

$regfile = "m16def.dat"
$crystal = 4000000
$baud = 9600

Config 1wire = Portd.5
Config 1wire = Portd.6

Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Byte2 As Byte
Dim Byte3 As Byte

Do
1wreset Pind , 5
1wreset Pind , 6
1wwrite &HCC , 1 , Pind , 5
1wwrite &H44 , 1 , Pind , 5
1wwrite &HCC , 1 , Pind , 6
1wwrite &H44 , 1 , Pind , 6

Waitms 1000

1wreset Pind , 5
1wreset Pind , 6
1wwrite &HCC , 1 , Pind , 5
1wwrite &HBE , 1 , Pind , 5
1wwrite &HCC , 1 , Pind , 6
1wwrite &HBE , 1 , Pind , 6

Byte0 = 1wread(1 , Pind , 5)
Byte1 = 1wread(1 , Pind , 5)
Byte2 = 1wread(1 , Pind , 6)
Byte3 = 1wread(1 , Pind , 6)

Print "=== PORTD PIN.5 ==="
Print Bin(byte0)
Print Bin(byte1)
Print "=== PORTD PIN.6 ==="
Print Bin(byte2)
Print Bin(byte3)
Print "------------------"

Wait 2
Loop
End

Таким макаром можно обвесить всю АТмегу. При отказе или порче датчика просто меняем его и никаких заморочек с ROM датчика. )
Спсб откликнувшимся ещё раз.

0

16

NAPALM написал(а):

Вот это в протеусе работает.

Этот код в железе работать не будет!

Pasha написал(а):

вот тут писали о 2х датчиках

Разве трудно глянуть ссылку?
Я там этот вопрос уже поднимал:

max написал(а):

Всем привет!
Покапался в HELPе и сделал так:

Код:
Config 1wire = Portc.0                               ' на эту ножку подключим DS18B20 и подтягивающий резистор на 4,7 ком к + питания

указываем только один раз, а то васик будет ругаться
первый датчик

Код:
1wreset
Stop Timer0
1wwrite &HCC
1wwrite &H44
Start Timer0
Waitms 750
1wreset
Stop Timer0
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()                                         ' Читаем нулевой байт
Byte1 = 1wread()                                         ' Читаем первый байт
Start Timer0
If Byte1 >= 248 Then          ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - ычитаем из &HFF
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Sign1 = "-"                                    
Else
Sign1 = "+"                                 
End If

второй датчик

Код:
1wreset Pinc , 4
Stop Timer0
1wwrite &HCC , 1 , Pinc , 4                                 ' Выдаем команду чтения ПЗУ
1wwrite &H44 , 1 , Pinc , 4                                 ' Запуск измерения
Start Timer0
Waitms 750                                                  ' Ждем окончания преобразования
1wreset Pinc , 4
Stop Timer0                                                 ': Portd = 255
1wwrite &HCC , 1 , Pinc , 4
1wwrite &HBE , 1 , Pinc , 4                                 ' Команда чтения ОЗУ датчика
B0 = 1wread(1 , Pinc , 4)                                   ' Читаем нулевой байт
B1 = 1wread(1 , Pinc , 4)                                   ' Читаем первый байт
Start Timer0
If B1 >= 248 Then                                           ' Проверяем на отрицательную температуру.248 в десятичном - 11111000 в двоичном. Если температура отрицательная - вычитаем из &HFF
B0 = &HFF - B0
B1 = &HFF - B1
Sign2 = "-"                                   
Else
Sign2 = "+"                               
End If

0

17

Можно сделать не останавливая таймер и не
запрещая прерывания и без задержек в
основном цикле. Это требуется в системах
реального времени.
У меня Timer0 вызывает прерывания раз в 50мс.

Dim Ct_termo As Byte

Tim0_isr:
  Tcnt0 = $3d
  Incr Ct_termo
  If Ct_termo > 200 Then Ct_termo = 0
  If Ct_termo = 1 Then En_conv = 1
  If Ct_termo = 18 Then En_rd = 1
  If Ct_termo <> 1 And Ct_termo <> 18 Then En_1990 = 1
Return
Температура измеряется раз в 10 сек.

Do
   If En_conv = 1 Then
      1wreset Pina , 7
      If Err = 0 Then
         1wwrite &HCC , 1 , Pina , 7
         1wwrite &H44 , 1 , Pina , 7
      End If
      En_conv = 0
   End If

   If En_rd = 1 Then
      1wreset Pina , 7
      If Err = 0 Then
         1wwrite &HCC , 1 , Pina , 7
         1wwrite &HBE , 1 , Pina , 7
         Bt1 = 1wread(1 , Pina , 7)
         Bt2 = 1wread(1 , Pina , 7)
         ......обработка результата
      End If
   En_rd = 0
   End If

0

18

max а такой код будет работоспособен в железе ? (В протеусе и этот код работает. Тут 3 датчика на разные пины)

Код:
$regfile = "m16def.dat"
$crystal = 4000000
$baud = 9600

Config 1wire = Portd.5

Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Byte2 As Byte
Dim Byte3 As Byte
Dim Byte4 As Byte
Dim Byte5 As Byte

Do
1wreset
Stop Timer0
1wwrite &HCC
1wwrite &H44
Start Timer0

Waitms 1000

1wreset
Stop Timer0
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()
Byte1 = 1wread()
Start Timer0

1wreset Pind , 6
Stop Timer0
1wwrite &HCC , 1 , Pind , 6
1wwrite &H44 , 1 , Pind , 6
Start Timer0

Waitms 1000


1wreset Pind , 6
Stop Timer0
1wwrite &HCC , 1 , Pind , 6
1wwrite &HBE , 1 , Pind , 6
Byte2 = 1wread(1 , Pind , 6)
Byte3 = 1wread(1 , Pind , 6)
Start Timer0

1wreset Pind , 7
Stop Timer0
1wwrite &HCC , 1 , Pind , 7
1wwrite &H44 , 1 , Pind , 7
Start Timer0

Waitms 1000


1wreset Pind , 7
Stop Timer0
1wwrite &HCC , 1 , Pind , 7
1wwrite &HBE , 1 , Pind , 7
Byte4 = 1wread(1 , Pind , 7)
Byte5 = 1wread(1 , Pind , 7)
Start Timer0


Print "=== PORTD PIN.5 ==="
Print Bin(byte0)
Print Bin(byte1)
Print "=== PORTD PIN.6 ==="
Print Bin(byte2)
Print Bin(byte3)
Print "=== PORTD PIN.7 ==="
Print Bin(byte4)
Print Bin(byte5)
Print "------------------"

Wait 2
Loop
End

Скажите для чего нужно тормозить таймер ?

Config 1wire = Portc.0                               ' на эту ножку подключим DS18B20 и подтягивающий резистор на 4,7 ком к + питания
указываем только один раз, а то васик будет ругаться

Bascom у меня не ругается )

Отредактировано NAPALM (2011-03-31 20:26:48)

0

19

При прерывании таймера во время считывания данных с датчика глюки идут... Если прерывания в программе не используются, то ничего тормозить и не надо

0

20

спсб за ответ Паш. Т.е. при прерывании камень все дела кидает и начинает его обрабатывть  :D  а в это время DS1820 отсылает вожделенные биты которые никак не фиксируются ? отсюда и глюки как я понимаю. Паш а при работе по UART контроллер работает с использованием прерываний ? Если и использует то уже все датчики опрошены и ничего страшного не случиться так что можно поидее не тормозить таймер.

0

21

потерять "вожделенные биты которые никак не фиксируются" -это пол беды. Всё намного страшнее!
Обмен информации ведется так называемыми тайм-слотами. И Прерывнием, вы можете из 1 сделать 0 .

0

22

считали температуру - отправили ее в уарт, снова считали. Не обязательно ее бесконечно считывать - пауза между опросом DS в 10-30секунд абсолютно норм. А если мерять температуру комнаты - так и в минуту перерыв между опросами не страшен! DS 18b20 ооооочень инертный датчик из-за толстого корпуса. В итоге когда греешь его к примеру зажигалкой - то он выдает 50 градусов, при том что поверхность может и до 150 нагрется. Прекращаеш греть - а он еще секунд 15 повышает температуру к примеру до 100`C Потом птихоньку снижается.

0

23

Ап ветке...
8 датчиков DS18B20 на разных PINах меги.  В железе проверил работает на ура. В Протеусе хрень выводит.
Может кому то из начинающих как мне поможет мало ли.  Опрос всех DS18B20 происходит примерно за 1 сек.
Хотелось за 1 сек опросить все датчики а не поочереди по 1 сек на датчик тратить. Код далеко не оптимален хотя прост как.....

Код:
$regfile = "m16def.dat"
$crystal = 8000000
$baud = 9600

Config 1wire = Portc.0

Dim Byte0 As Byte
Dim Byte1 As Byte
Dim T1 As Single
Dim T2 As Integer
Dim R As Word
Dim P As Byte
Dim Znak As String * 1

Do

 Incr R
'==================================
   If R = 1 Then
      P = 0
  Gosub Zapusk
  End If

   If R = 30000 Then
      P = 0
  Gosub Conversion
  Print "DS18B20-PINC.0 = " ; Znak ; T1
 End If

'==================================
  If R = 100 Then
     P = 1
  Gosub Zapusk
  End If

  If R = 30100 Then
     P = 1
  Gosub Conversion
  Print "DS18B20-PINC.1 = " ; Znak ; T1
 End If

'=================================
  If R = 200 Then
     P = 2
  Gosub Zapusk
  End If

  If R = 30200 Then
     P = 2
  Gosub Conversion
  Print "DS18B20-PINC.2 = " ; Znak ; T1
 End If
'=================================
  If R = 300 Then
     P = 3
  Gosub Zapusk
  End If

  If R = 30300 Then
     P = 3
  Gosub Conversion
  Print "DS18B20-PINC.3 = " ; Znak ; T1
 End If

'=================================
  If R = 400 Then
     P = 4
  Gosub Zapusk
 End If

  If R = 30400 Then
  P = 4
  Gosub Conversion
  Print "DS18B20-PINC.4 = " ; Znak ; T1
 End If
'=================================
  If R = 500 Then
     P = 5
  Gosub Zapusk
  End If

  If R = 30500 Then
     P = 5
  Gosub Conversion
  Print "DS18B20-PINC.5 = " ; Znak ; T1
 End If
'=================================
  If R = 600 Then
     P = 6
  Gosub Zapusk
  End If

  If R = 30600 Then
     P = 6
  Gosub Conversion
  Print "DS18B20-PINC.6 = " ; Znak ; T1
 End If
'================================
 If R = 700 Then
    P = 7
  Gosub Zapusk
  End If

  If R = 30700 Then
     P = 7
  Gosub Conversion
  Print "DS18B20-PINC.7 = " ; Znak ; T1
 End If
'================================

   If R >= 30900 Then R = 0

Loop

 Zapusk:
    1wreset Pinc , P
    1wwrite &HCC , 1 , Pinc , P
    1wwrite &H44 , 1 , Pinc , P
   Return

 Conversion:
    1wreset Pinc , P
    1wwrite &HCC , 1 , Pinc , P
    1wwrite &HBE , 1 , Pinc , P
      Byte0 = 1wread(1 , Pinc , P)
      Byte1 = 1wread(1 , Pinc , P)
    If Byte1 >= 248 Then
      Byte0 = &HFF - Byte0
      Byte1 = &HFF - Byte1
      Znak = "-"
       Else
      Znak = "+"
    End If
      T1 = Byte0 / 16
      T2 = Byte1 * 16
      T1 = T1 + T2
   Return



End

P.S. (Админу: Если пост ниочём снеси его )

Отредактировано NAPALM (2011-05-10 21:22:54)

+1

24

зачем же удалять? - тема популярная
удачи ))

0

25

Позвольте мне позволить себе поднять тему.
Proteus 7.7 SP2. DS18B20 с подтяжкой 4к7 к питанию. Atmega8, 16.
Не работает. Серийный номер датчика читается, при считывании температуры всегда 0xFF.
Банальная программа для однократного считывания с датчика, ни какие таймеры мной не используются.

1wreset
1wwrite &HCC
1wwrite &H44
Waitms 1000

1wreset
1wwrite &HCC
1wwrite &HBE
Byte0 = 1wread()
Byte1 = 1wread()

Byte0 и Byte1 всегда = 0xFF.

Нашел в интернете исходник на асме и скомпилированный с него hex, правда под 2313. Работает.
Чего же с протеусом такая нелюбовь?

0

26

Как обычно :)
Наверное отвечу сам себе. Уже позже нашел в интернете совет: в протеусе, в свойствах датчика поставить Time Slot 30u вместо 120u. Помогло. Хотя это отчасти расходится с даташитом.

0

27

простая переработка выше изложенного материалла 2 датчика на D4, D5 простым копированием 1 блока измерений изменяя только Config 1wire 
и место вывода на дисплей Locate 2 , 5 ( позиция курсора) можно хоть сколько датчиков подключить!

$regfile = "2313def.dat"                                    'работаем с at90s2313
$crystal = 4000000
$lib "lcd4.lbx"
Config Lcdbus = 4

''---------------

'Rs  = PortB.0
'RW  = PortB.1
' E  = PortB.2
'E2  = PortB.3  данный вывод используется для подключения некоторых дисплеев с двумя чипами (здесь не используется)
'Db4 = PortB.4
'Db5 = PortB.5
'Db6 = PortB.6
'Db7 = PortB.7in order for simulation to work correct, you need to specify the used pins
Config Lcd = 16 * 2
Dim Byte0 As Byte
Dim Byte1 As Byte
Dim Signtemperatura As String * 1
Dim T1 As Byte
Dim T2 As Byte
Dim I As Integer
Do

Config 1wire = Portd.5
1wreset
1wwrite &HCC ‘ Выдаем Команду Чтения Пзу
1wwrite &H44 ‘ Запуск Измерения
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE ‘ Команда Чтения Озу Датчика
Byte0 = 1wread()
Byte1 = 1wread()
If Byte1 >= 248 Then
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Signtemperatura = "-"
Else
Signtemperatura = "+"
End If
T1 = Byte0 / 16
T2 = Byte1 * 16
T1 = T1 + T2
Locate 1 , 5
Lcd Signtemperatura ; T1 ; "C"
Waitms 500

Config 1wire = Portd.4
1wreset
1wwrite &HCC ‘ Выдаем Команду Чтения Пзу
1wwrite &H44 ‘ Запуск Измерения
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE ‘ Команда Чтения Озу Датчика
Byte0 = 1wread()
Byte1 = 1wread()
If Byte1 >= 248 Then
Byte0 = &HFF - Byte0
Byte1 = &HFF - Byte1
Signtemperatura = "-"
Else
Signtemperatura = "+"
End If
T1 = Byte0 / 16
T2 = Byte1 * 16
T1 = T1 + T2
Locate 2 , 5
Lcd Signtemperatura ; T1 ; "C"

Loop

End

0

28

Я вынес

1wreset
1wwrite &HCC ‘ Выдаем Команду Чтения Пзу
1wwrite &H44 ‘ Запуск Измерения
Waitms 750
1wreset
1wwrite &HCC
1wwrite &HBE ‘ Команда Чтения Озу Датчика
Byte0 = 1wread()
Byte1 = 1wread()

в subroutine. В некоторых случаях позволяет сэкономить память.

0

29

Dim bit1wire As Byte
Dim Byte0 As Byte
Dim Byte1 As Byte

Main_program
    ' Тут что-то делаем
    Bit1wire = 6
    Gosub Work1wire
    ' Тут обрабатываем полученные данные с первого датчика
    Bit1wire = 7
    Gosub Work1wire
    ' Тут обрабатываем полученные данные со второго датчика
Goto Main_program

End

Work1wire:
    1wreset, PORTC, Bit1wire
    1wwrite &HCC, 1, PORTC, Bit1wire                ' Выдаем Команду Чтения Пзу
    1wwrite &H44, 1, PORTC, Bit1wire                 ' Запуск Измерения
                                                                      ' Waitms 750. Как тут очень хорошо подсказали, вместо Waitms делаю так:
    If Bit1wire = 6 Then                                     ' В одну строчку не работает. Видимо из-за запятой, поэтому так:
          Bitwait 6, Set
    Else
          Bitwait 7, Set
    End If
    1wreset, PORTC, Bit1wire
    1wwrite &HCC, 1, PORTC, Bit1wire
    1wwrite &HBE, 1, PORTC, Bit1wire ‘ Команда Чтения Озу Датчика
    Byte0 = 1wread(1, PORTC, Bit1wire)
    Byte1 = 1wread(1, PORTC, Bit1wire)
Return

+1

30

SIvan написал(а):

в свойствах датчика поставить Time Slot 30u вместо 120u. Помогло. Хотя это отчасти расходится с даташитом.

Но в железе работает  :cool:

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » DS18B20 - помогите пожалуйста