Термометр на 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


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

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

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


Взято с: avrproject.ru


Категория: AVR
Метки:

Написать коментарий

*
= 5 + 9

Добавить изображение

Последние статьи