Главная » Статьи » Проекты

Термометр на Tiny2313 и ds18b20. Вывод температуры на семисегментный индикатор
  Особенностью работы датчика температуры DS18b20, рассмотренного в предыдущей статье является то, что от запроса на преобразование до чтения значения температуры должно пройти определенное время (не менее 0,75 сек по даташиту). Это время требуется датчику для преобразования аналогового сигнала в цифровую форму, к тому же при частом опросе возможен нагрев датчика, что вызовет искажение показаний. Для совместной работы с семисегментным индикатором необходимо учитывать, что индикация происходит в динамическом режиме и поэтому запихивать запуск преобразования и чтение результата в один цикл с обработкой индикации не следует. Иначе  индикация во время ожидания преобразования заглохет и вывод показаний прекратится, что вызовет моргание индикатора.
  Чтобы этого избежать можно индикацию оставить в главном цикле, а работу с датчиком повесить в обработчик прерывания от таймера. Таким образом распараллелить задачу – пока датчик ведет преобразование микроконтроллер обрабатывает индикацию. Тут я поступил практически также: в главном цикле происходит вывод текущей температуры на индикатор, когда очередь доходит до работы с датчиком, проверяется переменная отвечающая за то, что нужно сделать – начать преобразование или считать результат преобразования. Значение этой переменной изменяется в обработчике прерывания от таймера (каждые 0,5 сек). Таким образом, работа с датчиком и динамическая индикация находятся в одном цикле, но за один цикл выполняется либо преобразование, либо чтение результата или работа с датчиком пропускается совсем.



 В качестве таймера задействован Timer1 с предделителем на 64, таким образом при частоте работы МК 8 МГц переполнение и изменение переменной будет происходить каждые 0,52 сек.  Схему подключения индикатора взял со статьи о подключении энкодера, сигнальный провод датчика прицепил к ноге PortD.2







Листинг программы в Bascom-AVR:

$regfile = "attiny2313.dat"
$crystal = 8000000

Dim A As Bit                                 'флаг запуска преобразования
Dim B As Bit                                 'флаг готовности опроса датчика

Dim N1 As Bit                                'переменные для хранения чисел в разрядах индикатора
Dim N2 As Byte
Dim N3 As Byte
Dim N4 As Byte
Dim N5 As Byte


Dim M2 As Integer                            'переменные для предварительных преобразований
Dim M3 As Integer

Dim Byte0 As Byte                            'переменные для приема данных с датчика
Dim Byte1 As Byte

Dim T1 As Byte                               'переменные для хранения температуры
Dim T2 As Byte

Ddrd = &B11011011                            'порт для подключения анодов
Ddrb = &B11111111                            'порт для подключения сегментов

Config 1wire = Portd.2                       'конфигурируем ногу для подключения датчика

Config Timer1 = Timer , Prescale = 64        'при 8МГц переполнение таймера за 0,52 сек

On Timer1 Dat                       'даем ссылку на обработчик прерывания по переполнению таймера


'разрешаем прерывания

Enable Interrupts
Enable Timer1

'останавливаем таймер

Stop Timer1


 N2 = 11
 N3 = 11

Waitms 100

 'ГЛАВНЫЙ ЦИКЛ ПРОГРАММЫ

Do

Portd = &B11111110                           'первый разряд

Select Case N1
Case 0 : Portb = &B10111111                  '-
Case 1 : Portb = &B11111111

End Select

Waitus 500

Portd = &B11111101                           'второй разряд

Select Case N2
Case 0 : Portb = &B11000000
Case 1 : Portb = &B11111001
Case 2 : Portb = &B10100100
Case 3 : Portb = &B10110000
Case 4 : Portb = &B10011001
Case 5 : Portb = &B10010010
Case 6 : Portb = &B10000010
Case 7 : Portb = &B11111000
Case 8 : Portb = &B10000000
Case 9 : Portb = &B10010000
Case 10 : Portb = &B10000110                 'E
Case 11 : Portb = &B10111111                 '-
End Select

Waitus 500

Portd = &B11110111                           'третий разряд

Select Case N3
Case 0 : Portb = &B11000000
Case 1 : Portb = &B11111001
Case 2 : Portb = &B10100100
Case 3 : Portb = &B10110000
Case 4 : Portb = &B10011001
Case 5 : Portb = &B10010010
Case 6 : Portb = &B10000010
Case 7 : Portb = &B11111000
Case 8 : Portb = &B10000000
Case 9 : Portb = &B10010000
Case 10 : Portb = &B10101111                 'r
Case 11 : Portb = &B10111111                 '-
End Select

Waitus 500

Portd = &B11101111                           'четвертый разряд

Select Case N4
Case 0 : Portb = &B10111111                  '-
Case 1 : Portb = &B10011100                  'градус
Case 2 : Portb = &B10101111                  'r

End Select

Waitus 500


Portd = &B10111111                           'пятый разряд

Select Case N5
Case 0 : Portb = &B10111111                  '-
Case 1 : Portb = &B11000110                  'C

End Select

Waitus 500



'*** РАБОТА С ДАТЧИКОМ ***

 'запускаем преобразование

If A = 0 Then                                'пока переменная А=0 запускаем опрос датчика

 1wreset                                     'сбрасываем линию
 1wwrite &HCC                                'пропуск ПЗУ
 1wwrite &H44                                'запускаем преобразование

  If Err = 1 Then                            'если ответа небыло, выводим сообщение об ошибке

    N1 = 0
    N2 = 10
    N3 = 10
    N4 = 2
    N5 = 0

  Else

    A = 1                          'увеличиваем, чтобы в следующем цикле пропустить опрос датчика

   Start Timer1                              'запускаем таймер

  End If
End If


 'чтение результата

If A = 1 And B = 1 Then                      'чтение не произойдет пока В не станет равна 1

 Stop Timer1                                 'останавливаем и обнуляем таймер
 Timer1 = 0

 1wreset                                     'сбрасываем линию
 1wwrite &HCC                                'пропуск ПЗУ
 1wwrite &HBE                                'читаем из ОЗУ, чего мы там наизмеряли

 Byte0 = 1wread()                            'читаем нулевой и первый байт памяти датчика
 Byte1 = 1wread()                            'в них хранится считанная температура


   If Byte1 > 248 Then                       'Проверка на отрицательность температуры

      Byte0 = &HFF - Byte0
      Byte1 = &HFF - Byte1
      N1 = 0                                 'отрицательная температура

    Else

     N1 = 1                                  'иначе, положительная

   End If

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


   If N1 = 0 Then                            'для корректного вывода отрицательных температур
      T1 = T1 + 1
   End If

   If N1 = 1 And T1 = 0 Then                 'убираем знак "+" с нулевой температуры
      N1 = 1
   End If


'ГОТОВИМ ПЕРЕМЕННЫЕ ДЛЯ ВЫВОДА НА ИНДИКАТОР

M2 = T1
M3 = T1

M2 = M2 / 10                                 'обработка второго разряда
N2 = Abs(m2)

M3 = M3 Mod 10                               'обработка третьего разряда
N3 = Abs(m3)

N4 = 1                                       'если 1 то отобразим символ градус

N5 = 1                                       'если 1 отобразим С

A = 0
B = 0

End If

Loop

'ПРЕРЫВАНИЕ ОТ ТАЙМЕРА

Dat:

 B = 1                                                      'ставим флаг готовности опроса датчика

Return


End




 При ошибке чтения или при отсутствии датчика отображается сообщение об ошибке:


  А это отображение измеренной температуры:


Скачать файлы к проекту

Категория: Проекты | Добавлено: 01.06.2011
Просмотров: 44475 | Комментарии: 49 | Теги: ATtiny2313, 18b20, индикатор, Алгоритм | Рейтинг: 4.6/10
Всего комментариев: 491 2 »
49 Aisek   (25.07.2017 17:05) [Материал]
Не туда написал коммент.

48 Aisek   (25.07.2017 17:00) [Материал]
Сдела в протеусе симуляцию кажет отрицательную температуру. Откуда? Если в коде не предусмотрено измерение отрицательной температуры.

0  
47 exersizze   (05.08.2015 08:59) [Материал]
Smak112, просто нужно снять галочку CKDIV8, тем самым отключить деление частоты на 8. Камень будет работать на необходимой частоте 8 МГц.

46 Smak112   (04.08.2015 16:31) [Материал]
А какие фьюзы выставить для меги8? Просто это мой первый проект, мега есть на руках, исходник перекроил, плату развел, а со фьюзами не дружу!)))

0  
45 exersizze   (03.08.2015 08:26) [Материал]
В железе будет работать как надо, это проблема симулятора.

44 Smak112   (02.08.2015 14:08) [Материал]
День добрый!

Собрал схему в протеусе. Пока в схеме присутствуют транзисторы, на индикаторах все в кашу. Убираю транзисторы со схемы, все работает. Подскажите, в железе будет то же самое или все будет работать как нужно?

43 palex300182   (15.04.2015 09:33) [Материал]
Тинька новая, делитель частоты на 8 убирал при программировании. Помогло изменение значений задержки с Waitus 500 на Waitms 1. Возможно, это связано с особенностями самого индикатора. Использовал в схеме Kingbright SA56-11EWA. Спасибо за помощь.

0  
42 exersizze   (14.04.2015 21:05) [Материал]
Еще есть фьюз ckdiv8, деление частоты на 8. Если тини новая, то фьюз запрограммирован и фактическая частота работы 1МГц.

41 sany2   (14.04.2015 18:18) [Материал]
Тут вывод на индикацию не по таймеру.Waitus 500 пробуйте уменьшайте.С фьююзами точно разобрались?

40 palex300182   (14.04.2015 06:49) [Материал]
Хочется изменить не время опроса датчика, а только частоту вывода информации на индикатор. Поэтому и спрашиваю, какой кусок кода нужно изменить. Сейчас, я так понимаю, и вывод на индикатор и опрос датчика завязан на прерывание по переполнению таймера.

39 sany2   (13.04.2015 23:18) [Материал]
Обновление информации на индикаторе происходит примерно с частотой 2 Гц.-всё правильно -работа с датчиком по таймеру каждые пол-секунды.
В каком нужно изменить код, чтобы увеличить частоту обновления до незаметной глазу например 50 Гц -Ds18B20 нельзя опрашивать с такой частотой.

38 palex300182   (13.04.2015 16:44) [Материал]
P.S. Пост 36... заливал прошивку, конечно, не в ЕЕPROM, а во FLASH.

37 palex300182   (13.04.2015 11:49) [Материал]
Я так понимаю, что частота и выбор источника задается фьюзами CKSEL3…0 = 0100 – Внутренний тактовый генератор – частота 8 МГц, т.е. нужно в данном случае выставить галки SKCEL3,SKCEL1,SKCEL0 снять SKSEL2, если да, то все так и выставлялось при прошивке.

36 palex300182   (13.04.2015 11:42) [Материал]
Exersizze, если честно, то я только начинаю осваивать МК и разбираться с настройками. Заливал в EEPROM PonyProg-ом приложенную здесь прошивку, с установками фьюзов согласно 26 посту (со снятием галки CKDIV8). Какими настройками выставляется частота работы МК 8 Мгц ?

0  
35 exersizze   (12.04.2015 21:56) [Материал]
Частоту работы МК выставили на 8МГц?

34 palex300182   (12.04.2015 18:09) [Материал]
Всем доброго времени суток. Собрал данное устройство, устройство работает, но есть небольшой нюанс. Динамическая индикация слишком заметна глазу. Обновление информации на индикаторе происходит примерно с частотой 2 Гц. В каком нужно изменить код, чтобы увеличить частоту обновления до незаметной глазу например 50 Гц ? Спасибо.

33 lao   (12.08.2013 09:48) [Материал]
Запросто. Вот пример чтения DS1820. http://mcselec.com/index.php?option=com_content&task=view&id=39&Itemid=57

32 gkuprienko1954   (05.07.2013 11:47) [Материал]
Ребята. Хотел бы попросить.
Сделал данный аппарат но в радиомагазине "втюрили" DS1820 (а других и не было). Не работает. Навел справки в Интернете - они не заменяемые. Можно заставить работать но необходимо внести в программу изменения. Я нуль.

31 exersizze   (14.09.2012 10:53) [Материал]
Я бы не советовал так делать, без транзисторов придется ставить дополнительные токоограничительные резисторы чтобы не спалить порт, а это приведет к уменьшению яркости индикатора. Плюс к этому яркость свечения индикаторов будет разная в зависимости от того какое число отображается (в зависимости от числа горящих сегментов)

30 Savel   (14.09.2012 10:08) [Материал]
Привет! Подскажите, можно ли сделать эту схему исключив транзисторы?

29 exersizze   (29.03.2012 18:13) [Материал]
в коментариях к прошлой статье обсуждали считывание с десятыми долями
вот здесь http://avrproject.ru/publ/termometr_na_ds18b20_mega32/1-1-0-15

28 osa   (29.03.2012 17:05) [Материал]
Изучаю опрашивание температурного датчика, и попутно перекраиваю вашу программу под работу с четырехзначным индикатором. Хочу сделать чтобы температуры отображалась с точностью до десятых. Не подскажете как это правильно сделать?

27 Serzh   (07.02.2012 16:23) [Материал]
Собрал Ваш термометр все работает!Спасибо!
Есть предложения по модернизации термометра:
1. Убрать незначащий ноль (00, 01, 03 ит.д.);
2. Подключение датчика по двум проводам (паразитное питание). Пробовал подключать по 2-м проводам - резистор менял с 4,7ком на 1ком. Показывает 85.

26 exersizze   (05.02.2012 01:03) [Материал]
настройки будут выглядить так как на рисунке ниже, только со снятой галкой CKDIV8



про кварц на программаторе не понял..

25 Serzh   (04.02.2012 22:10) [Материал]
Пожалуйста дайте фьюзы для программы PonyProg2000. Кварц на программаторе 10Мгц.

24 exersizze   (22.09.2011 19:09) [Материал]
пока памяти хватает на такой алгоритм
вот если припрет, тогда будем думать дальше...
а почему используется всеми, так это первое что приходит в голову (не зная команды сдвига в компиляторе).

23 pchela5   (22.09.2011 18:55) [Материал]
это я знаю - и в хелпе об этом тоже написано. вопрос был - почему это гуляет из схемы в схему - неужели всем памяти хватает? И еще - case кушает больше памяти, чем lookup - не рассматривал применение этой функции?

22 exersizze   (22.09.2011 18:35) [Материал]
В двоичной системе сдвиг вправо на Х равнозначен делению числа на двойку в квадрате Х. А сдвиг влево - умножению на двойку в квадрате Х. Так что разницы никакой нет smile А выигрыш вероятно из-за оптимизации компилятором битовых операций shift.

21 pchela5   (22.09.2011 16:36) [Материал]
сорри - на 16

20 pchela5   (22.09.2011 16:34) [Материал]
еще вот такой вопрос - везде (в апноуте тоже) при формировании температуры присутствуют оперции умножения и деления на 8 - чем это обусловлено? я сделал сдвигом - результат тот же, а памяти экономится несколько процентов:
Shift Byte0 , Right , 4
Shift Byte1 , Left , 4
T1 = Byte0 + Byte1

1-30 31-49
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]






авторизация
Логин:
Пароль: