AVR Урок 23. Собираем часы на DS1307 и LED индикаторе. Часть 5



 

Урок 23

Часть 5

 

Собираем часы на DS1307 и LED индикаторе

 

В прошлой части нашего занятия мы занимались автоматическим реагированием яркости свечения индикатора на условия окружающей освещённости. Нам это удалось.

Сегодня мы попробуем подключить к нашей схеме также датчика температуры 18B20, а также попытаемся отобразить показания не только времени, но и даты, дня недели, а также температуры. А уж как нам это удастся, посмотрим.

Подключим файлы DS18B20.c и DS18B20.h из проекта урока 20 по датчику температуры My1820LCD.

Подключим данную библиотеку также в main.h

 

#include «led.h»

#include «DS18B20.h»

 

Также из того же проекта скопируем объявление переменной в main()

 

int main(void)

{

  unsigned int tt=0; //переменная для хранения температуры

 

Скопируем и вставим также измерение температуры в бесконечный цикл

 

date = RTC_ConvertFromDec(date); //Преобразуем в десятичный формат

tt = converttemp(dt_check());

 

Теперь нам нужно эту температуру как-то отобразить, хотя бы пока как-то.

Закомментируем пока отображение времени

 

//ledprint(hour*100+min);

 

Также можно закомментировать и чтение времени.

 

 

И пока мы просто отобразим значение переменной tt

 

else OCR2=7;

ledprint(tt);

 

Посмотрим также изменение нашей схемы в связи с подключением датчика температуры (нажмите на картинку для увеличения изображения)

 

image25_0500

 

Как видим, термометр у нас своим информационным входом подключен на ножку PC2, поэтому в файле DS18B20.h мы должны внести соответствующие изменения

 

#define PORTTEMP PORTC

#define DDRTEMP DDRC

#define PINTEMP PINC

#define BITTEMP 2

 

Вот теперь можно собирать проект и прошивать контроллер

 

image26

 

Температура у нас 22 градуса, всё у нас нормально отображается, но температура у нас измеряется 12-битно, это очень расточительно, ибо нужно использовать задержку в 750 милисекунд. Поэтому зайдём в файл DS18B20.c и перенастроим функцию считывания температуры. Как известно, нам достаточно просто изменить задержку, и просто потом не использовать младшие биты

 

dt_sendbyte(T_CONVERT);//измеряем температуру

_delay_ms(100);//9 битный режим преобразования — 100ms

 

 

Так как для вывода целой части температуры, нам достаточно 8 бит, то самый младший бит у нас не используется. Можно его использовать. То есть, если данный бит установлен в 0, то это даёт нам право после запятой поставить 0, а если 1 — то 5. Таким образом мы полностью будем использовать точность микросхемы 0,5. Поэтому данный бит будем использовать и не будем отсекать его в функции converttemp

 

char converttemp (unsigned int tt)

{

  char t =tt>>3;//сдвиг — целую часть получим сдвинутую 1 байт влево, а дробную в самом младшем байте

 

А потом мы с данной функцией разберёмся. Это ничто иное, как температура с точностью до 0,5, умноженная на 2. Правда у нас ещё отсечется самый старший бит, но он у нас отвечает уже за температуры, которые более 128, у нас необходимости такие температуры измерять нет, поэтому ничего страшного.

Теперь вернёмся в бесконечный цикл функции main() и поработаем там над выводом показаний температуры.

Мы показания сдвинем ещё на 1 бит, чтобы отсечь доли и умножим всё это на 10, чтобы у нас остался разряд справа для показания десятых долей. Потом мы к данному результату прибавим остаток от деления на 2 несдвинутой величины, умноженный на 5 и это у нас покажется в последнем разряде

 

ledprint((tt>>1)*10+((tt%2)*5));

 

Соберём проект, прошьём контроллер и посмотрим, что у нас получилось с температурой

 

image27

 

Теперь всё правильно. Температура у нас 22,5 градуса. На двоеточие и остутствие разделителя целой и дробной части пока внимание не обращаем, потом мы с этим разберёмся.

Будем считать, что с температурой мы разобрались.

Теперь нам нужно будет все наши считанные данные нормально показать и этим мы сейчас и займёмся.

Поэтому нам нужно придумать какие-нибудь режимы для показа значений и создать для них макросы в главном модуле

 

#include «main.h»

//—————————————-

#define MODETIMEVIEW 100

#define MODETEMPERVIEW 101

#define MODEDATEVIEW 102

#define MODEDAYVIEW 103

//———————————————

 

Я думаю, что наименование каждого режима говорит само о себе и в комментариях не нуждается.

Теперь надо придумать, как нам использовать данные режимы. Нам нужно первым делом решить, когда и что мы будем отображать. Ну, я думаю, что время надо отображать почти всегда, на то они и часы. В 30 секунд каждой минуты отобразим температуры, ещё через 4 секунды день недели, и ещё через 4 секунды покажем дату, а потом опять будем показывать время.

Во-первых, создадим для этого переменную, можно даже локальную в main() и сразу проинициализируем её обычным режимом отображения времени

 

unsigned int tt=0; //переменная для хранения температуры

unsigned char clockmode=MODETIMEVIEW;//обычный режим показаний дисплея

 

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

 

date = RTC_ConvertFromDec(date); //Преобразуем в десятичный формат

if ((sec<30)||(sec>41)) clockmode=MODETIMEVIEW;

else if (sec<34) clockmode=MODETEMPERVIEW;

else if (sec<38) clockmode=MODEDAYVIEW;

else clockmode=MODEDATEVIEW;

 

Ну вот. Предположим, что режимы у нас вовремя меняются. Теперь надо как-то нашему индикатору на всё это реагировать.

Напишем ещё условия и реакции на них

 

tt = converttemp(dt_check());

if(clockmode==MODETIMEVIEW) ledprint(hour*100+min);

if(clockmode==MODETEMPERVIEW) ledprint((tt>>1)*10+((tt%2)*5));

if(clockmode==MODEDAYVIEW) ledprint(day*10);

if(clockmode==MODEDATEVIEW) ledprint(month + date*100);

 

Всё остальное с ledprint, что было до этого написано в бесконечном цикле удалим.

Пока здесь всё будет происходить коряво и с мигающим двоеточием. Потом нам надо будет погасить ненужные цифры, день недели мы сдвинули к десяткам для того чтобы справа и слева показать чёрточки.

Ну, давайте хотя бы так посмотрим. Соберём для этого проект и прошьём контроллер

 

image31 image28 image29 image30

 

Пока вот так. У нас время 18:12, 23 градуса, 4 день недели или четверг и 17 марта.

Согласитесь, уже неплохо! У нас меняются режимы отображения. Но смотреть так неудобно с постоянно мигающим двоеточием. кучей нулей вокруг. А вот этим вопросом мы займёмся в следующей части нашего урока.

 

 

Предыдущая часть Программирование МК AVR Следующая часть

 

Программатор, модуль RTC DS1307 с микросхемой памяти и индикатор можно приобрести здесь:

Программатор (продавец надёжный) USBASP USBISP 2.0

Модуль RTC DS1307 с микросхемой памяти

Семисегментный чертырехразрядный индикатор красный с общим анодом 10 шт

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

AVR Собираем часы на DS1307 и LED индикаторе

3 комментария на “AVR Урок 23. Собираем часы на DS1307 и LED индикаторе. Часть 5
  1. Kirill:

    Все бы хорошо, но при работе с датчиком по 1-Wire мы надолго отключаем прерывания, из-за чего сного чего идет прахом… Та же индикация динамическая. Как вы это обошли то? Уже на этапе протеуса видно проблемы — после считывания температуры перестает работать получение по прерываниям ADC

  2. User:

    Увеличение картинок не работает. Поправьте пожалуйста!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*