Часы термометр на atmega8 ds1307

Часы термометр на atmega8 ds1307

Решил к себе в гараж поставить новые часы с термометром. Прошлые часы-термометр отдал соседу по гаражу, больно они ему понравились.
А себе часы сделал более функциональные с LCD экраном1602А на ATMega8.
Схему нашёл вот на этом форуме, автор часов Soir. Автор постарался сделать модель в протеусе, приложил подробную инструкцию и несколько вариантов прошивок. Но плату, к сожалению, ни кто на форуме не предложил. Это не пролема.
Набросал схему в DipTrace.
По рекомендации самого автора питание разделил. Тоесть питание МК, датчика и экрана через стабилизатор 5В, а питание подсветки экрана, пищалки и реле сделал от 12В через транзисторные ключи. Схема такая, чтопри отключении внешнего питания МК питается от батарейки и время и настройки не сбиваются.
Смотрите схему.

Развёл плату, честно, особо не старался получилась достаточно громоздкой и достаточно перемычек. Но перемычки я старался делать под индикатором и одна под МК. Так что если под индикатор не заглядывать не заметишь.

Решил к себе в гараж поставить новые часы с термометром. Прошлые часы-термометр отдал соседу по гаражу, больно они ему понравились.
А себе часы сделал более функциональные с LCD экраном1602А на ATMega8.
Схему нашёл вот на этом форуме, автор часов Soir. Автор постарался сделать модель в протеусе, приложил подробную инструкцию и несколько вариантов прошивок. Но плату, к сожалению, ни кто на форуме не предложил. Это не пролема.
Набросал схему в DipTrace.
По рекомендации самого автора питание разделил. Тоесть питание МК, датчика и экрана через стабилизатор 5В, а питание подсветки экрана, пищалки и реле сделал от 12В через транзисторные ключи. Схема такая, чтопри отключении внешнего питания МК питается от батарейки и время и настройки не сбиваются.
Смотрите схему.

Развёл плату, честно, особо не старался получилась достаточно громоздкой и достаточно перемычек. Но перемычки я старался делать под индикатором и одна под МК. Так что если под индикатор не заглядывать не заметишь.

Тема часов на микросхеме DS1307 довольно актуальна — это простое, но в то же время интересное устройство. Кроме того, оно может реально пригодиться. Но описывать отдельно микросхему смысла нет, поэтому я решил собрать себе подобное устройство, заодно рассказать о том, какие шишки набил при этом. Сам процесс разработки и сборки буду описывать, по мере прохождения некоторых этапов готовности девайса.

Update 17.10.2015
Вначале это была серия статей, целью которых было рассказать про создание устройства с нуля до состояния готовности, но внезапно у меня появилась аллергия на все что называется «часы», поэтому я слил все в одну статью. Устройство закончено на 99.9%, (осталось закрутить винты), но сделать это ой как не просто 🙂 Как только аллергия пройдет появится окончательная фотка.

Начнем с того, что пока нам ничего не известно про ds1307 кроме того, что с ее помощью делают часы. Поэтому качаем документацию, на эту микросхему и читаем список «вкусностей», которыми она обладает. Итак, из первого абзаца в целом понятно, что она обладает низким энергопотреблением, информация передается по I2C, можно узнать дату и время, 12 и 24 часовой формат, автоматическая подстройка даты. Но самое интересное это схема (TYPICAL OPERATING CIRCUIT).

Курим даташит и пытаемся разобраться что к чему. Идем слева направо, CPU — микроконтроллер ( то есть наша atmega), два резистора, написано pull up — значит подтягивающие (можно взять по 10к), кварц на 32768Гц, сама микросхема и батарейка. Выход SQW/OUT может дрыгаться с частотой 1Hz, 4kHz, 8kHz, 32kHz, пока нам это не интересно. Пожалуй, этой информации пока достаточно, хочется уже чего нибудь накодить 🙂

Читайте также:  Имеют ли право снимать на видео

Создаем проект в CodeVision, в разделе I2C находим ds1307 и включаем его в проект. Хорошо бы еще выводить куда нибудь информацию, например на LCD и пара кнопок не помешает.

Все что нужно это LCD настроить на порт D и три кнопки с подтяжкой на вход. Далее нужно вывести на LCD время, для этого заглянем в мануал CodeVision и возьмем оттуда пример. Оказывается все просто — есть функция устанавливающая время:
rtc_set_time(3,0,0); //установить 03:00:00

И есть функция, позволяющая считать текущее время:
rtc_get_time(&h,&m,&s);

т.е. после вызова данной функции в переменных h, m, s будут находиться часы(h), минуты(m) и секунды(s). Осталось вывести их на экран. Уж это мы умеем делать)
Итоговый код будет выглядеть так:

Собираем и тестируем в протеусе:

Схема и прошивка

Продолжим модернизировать нашу прошивку. Начнем со следующей задумки: у DS1307 есть выход SQW/OUT, который может генерировать несколько частот. Если настроить этот выход на 1Гц, и подать этот сигнал на вход внешнего прерывания, то получится, что раз в секунду 1307 будет дергать «за хвост» нашу atmega8. Для меги это будет сигналом к тому, что пора обновлять время. Это позволит не нагружать микроконтроллер постоянным обновлением времени, информация о текущем времени будет обновляться ровно раз в секунду.

Добавим в проект внешнее прерывание по низкому уровню (low level) на ножке Int1 и включим подтяжку. Выход DS1307 настроим на частоту 1Гц. Кстати, читать мануалы полезно, нашел интересную особенность — подтягивающие резисторы на ножках SCL, SDA должны быть 3,3k — 4,7k. Учтем это.

Получившийся код будет выглядеть так:

interrupt [EXT_INT1] void ext_int1_isr(void)

В прерывании выставляем флаг, разрешающий вывод времени, в основном цикле, если флаг выставлен, то показываем время, если не выставлен ничего не делаем.

Теперь перейдем к следующему вопросу, на сколько эффективно использовать sprintf? Чтобы не разводить пустых разговоров, приведу 2 куска кода, которые выполняют одно и тоже — выводят информацию о времени на дисплей.

Первый вариант, уже нам известный:

Согласитесь просто в использовании и наглядно. Теперь вариант номер 2:

lcd_putchar(hour/10+0x30); lcd_putchar(hour%10+0x30); lcd_putchar(‘:’); lcd_putchar(min/10+0x30); lcd_putchar(min%10+0x30); lcd_putchar(‘:’); lcd_putchar(sek/10+0x30); lcd_putchar(sek%10+0x30);

Не очень наглядно, но разобраться можно. Как мы их будем сравнивать? Делается это очень просто — запускаем отладчик AVR STUDIO и смотрим количество тактов затраченных на их выполнение. Итак, «барабанная дробь», результаты… Первый кусок кода выполнялся 16 466 тактов, что равносильно 2 058,25 мкс, при рабочей частоте в 8МГц, для второго куска кода эта цифра составила 12 278 тактов или 1 534,75 мкс. Согласитесь, снизить время выполнения, а значит и разгрузить микроконтроллер на

25% достаточно весомая причина, чтобы не использовать sprintf. Выкидываем sprintf из нашего проекта, в след за ним можно выкинуть stdio.h и lcd_buf[].

Некрасиво, когда в основном цикле мешанина из кода, поэтому вывод информации можно засунуть в функцию. В основном цикле останется

Объявление самой функции будет выглядеть так:

Теперь в нашу прошивку, нужно добавить вывод даты. Установка даты, производится следующей функцией:

rtc_set_date(6,13,10,13); //6- день недели, 13 — день, 10 — месяц, 13 — год

Прочитать текущую дату можно аналогично чтению времени:

rtc_get_date(&week_day,&day,&month,&year); //день недели, день, месяц, год

Вывод даты можно организовать, пока что в основном цикле, рядом со временем, полный исходный код получился такой:

Результат:

Схема и прошивка:

Перейдем к организации меню. Самый главный вопрос состоял в том, как оно все должно выглядеть, т.е. нужно было сформулировать техническое задание(т.з.).
Мне хотелось, чтобы это были отдельные экраны:
-главный экран;
-экран настройки времени;
-экран настройки даты;
-экран настройки будильника.

Читайте также:  Как поменять старые пробки на автоматы

При этом обойтись четырьмя кнопками — вверх, вниз, влево, вправо. Переход между экранами должен осуществляться кнопками вверх и вниз. Настройка производится на соответствующем экране. Применяемый микроконтроллер atmega8. Вот такое примитивное т.з.

То что размер кода будет достаточно большой было понятно изначально. При этом нужно было его разбить на логически связанные части. С частями все понятно — обработка одного экрана одна часть кода. Поэтому начал с того, что основной цикл разбил на четыре части, переключения между которыми производится оператором switch. Внутрь засунул функции — пустышки. Кнопки 0(вверх) и 3(вниз) порта C позволяют изменить переменную menu. Таким образом мы скачем между менюшками. Но пока такая прошивка еще работать не могла, ибо функции еще не определены.

Следующий шаг определение этих функций, изначально я нарисовал статичные названия, вроде lcd_puts(«Set time»); функции получились, такими.

Теперь это уже была рабочая прошивка, в которой можно было переключаться между менюшками и смотреть статичные надписи. Настало время оживить эти надписи. С главным экраном проблем не было, вывод времени/даты аналогичен предыдущему уроку.

Встал следующий вопрос: как организовать сам процесс настройки? Поразмыслив, мне показалась интересной следующая идея: переходим кнопками вверх/вниз в интересующее нас меню, нажимаем вправо, появляется курсор, говорящий нам о том, что идет процесс настройки. Кнопками вверх/вниз мы изменяем величину, влево/вправо скачем курсором между настраиваемыми параметрами. Когда курсор находится под последним параметром, повторное нажатие кнопки вправо позволяет выйти из настройки. Курсор при этом скрывается, что говорит о том что мы вышли из настройки и можем снова переключаться между менюшками.

Но есть небольшие проблемы, например, кнопка вверх должна изменять параметры и при этом, переключать следующий экран. Т.е. логику кнопок внутри одного экрана, пришлось разделить. Из за этого код здорово разросся. Например, на экране будильника, вводим подпрограмму настройки(sub_alarm), соответственно кнопки внутри подпрограммы обрабатываются одним образом, а вне другим.

Есть еще такой момент, когда зашли в подменю настройки одна и таже кнопка (возьмем опять в качестве примера кнопку вверх), может менять часы, а может минуты. Поэтому была введена еще одна переменная subProgram.
Например:

if(PINC.0==0) //кнопка вверх < if(subProgram==1) //subProgram=1 — изменяем часы < a_hour++; . >if(subProgram==2) //subProgram=2 — изменяем минуты < a_min++; . >if(subProgram==3) //subProgram=3 изменяем флаг будильника < . >>

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

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

Пример взят из примеров в папке CodeVisionexampleslcd char.

typedef unsigned char byte; //переопределяем тип flash byte char_table[8]=< //рисуем свой символ 0b10000000, 0b10000100, 0b10001110, 0b10001110, 0b10001110, 0b10011111, 0b10100100, 0b11000000>; // function used to define user characters void define_char(byte flash *pc,byte char_code) < byte i,address; address=(char_code

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

Начнем с печатной платы, для этого требуется программа, которая позволяет рисовать печатки. Существует множество подобных программ: P-cad, Altium, Sprint layout… Мне нравится Альтиум, только потому, что для него куча готовых библиотек с элементами, ибо тратить время на набивку собственной библиотеки элементов, на мой взгляд не дело. Общий смысл всех подобных программ одинаков — сначала рисуется электрическая схема.

Далее данные о связях элементов передаются в трассировщик.

В трассировщике все элементы уже знают, какой с каким должен соединяться, благодаря электрической схеме.

Читайте также:  Как узнать модель своего ноутбука acer

Остается только удобно расположить элементы и соединить их проводниками.

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

Я долгое время печатал на бумаге с плотностью 180 г/м2 и меня устраивало, но недавно бумага закончилась и в магазине оказалась только 220 г/м2, думаю ладно попробую. В результате я отодрать бумагу так и не смог, ни от платы ни от утюга :D. Много раз слышал, что можно брать бумагу от обычных глянцевых журналов. Думаю ладно попробую, взял первый попавшийся журнал с рекламой мебели и результат меня впечатлил. Так что рекомендую не тратить деньги, а печатать на халявных журналах.

Основой служит фольгированный текстолит, который по сути и есть кусок текстолита, с одной стороны покрытый медью.

Отрезаем ножницами по металлу чуть больше размера будущей печатки и зашкуриваем, чтоб блестело. Полученную плату протираем ацетоном и ни в коем случае медный слой не лапаем руками.

Прикладываем рисунок к медному слою и хорошенько прогреваем утюгом. Прилипшую бумагу оттираем зубной щеткой под струей теплой воды. В результате тонер должен прилипнуть слева результат от бумаги 220 г/м2, видно что дорожки кое где поотваливались, справа результат от журнала.

Теперь потребуется приготовить раствор хлорного железа и бросить туда плату. Процесс травления может быть довольно длительным в зависимости от размеров платы. Существует множество всяких шамаств с раствором, для ускорения этого процесса. Меня впечатлило использование бурбулятора, того самого который называется компрессором и пускает пузырьки в аквариумах, с ним процесс травления небольшой платы занимает около 15мин. Чтобы раствор не брызгал разрезал пластиковую бутылку, горлышко стало крышкой.

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

В результате весь проводящий слой не защищенный тонером будет удален, останется только рисунок нашей печатной платы. Смываем остатки тонера ацетоном. Получилась такая печатка.

В общем обленился в край, все сделал, осталось прикрутить винты &#128578;

105 комментариев: Часы на DS1307 от идеи к реализации

Ура . Сделал вот так:
void Nastroika(void)
<
switch (set) // switch // подпрограмма опроса
<
case 0:
<
if (PINB.2==0)

PORTB.0=1; //контроль
hour++;
rtc_set_time(hour,min,sec);
>
if (hour>23)
<
hour=0;
>;
if (PINB.3==0)

PORTB.0=0; //контроль
hour—;
rtc_set_time(hour,min,sec);
if (hour==255)
<
hour=23;>
>;
break;
>

можно выставить флаг и при выходе из меню например, если флаг установлен, то настраивать часы однократно

/*
* EEPROM_atmega 16.c
*
* Created: 10.04.2016 6:06:21
* Author : User
*/
Это работает сохраняет значение с RAM вEEPROM потом читаем и выводим на ЛСД .У меня вопрос я немогу записать с кнопки предыдущая программа не понимает.Прогресс есть а дальше труба ?
#define F_CPU 8000000UL
#include
#include
#include
#include «lcd.h»
#include
#include
unsigned int data_a,data_b,i,adres;
unsigned char masiv[4]=<100,150,200,250>;
volatile unsigned char menu=0;
char flag1=0;
char buf2[10];
char buf1[10];
unsigned data1=5000 ;// размер в 2 байта

unsigned data2=2000 ;// размер в 2 байта

uint16_t save1 EEMEM ;//размер в 1 байт
uint16_t save2 EEMEM ;// размер в 2 байта
// uint32_t save32 EEMEM= 10000;//размер в 3 байта
asm(«sei»);
int main(void)
<
data_a=eeprom_read_word(& save1);// чтение 2 байт
data_b=eeprom_read_word(& save2);// чтение 2 байт

eeprom_write_word(& save1,data1);//запись в память2 байт
data1=0 ;// размер в 2 байта
eeprom_write_word(& save2,data2);//запись в память2 байт
data2=0 ;// размер в 2 байта

//data_a=eeprom_read_word(& save1);// чтение 2 байт
//data_b=eeprom_read_word(& save2);// чтение 2 байт

DDRC=0x00;
PORTC=0xFF;
DDRB=0xFF;
PORTB=0x00;
lcd_init(LCD_DISP_ON);
lcd_clrscr();

Ссылка на основную публикацию
Фото с листком для вк
Сигна в ВК – это просто фотография человека с листком бумаги, на котором обычно написано чье-то имя. Часто надписи делают...
Установка виндовс зависла на начало установки
Если вы решили переустановить или установить операционную систему, но начало установки Windows 7 зависает, то в этой статье, думаю, вы...
Установка драйвера принтера отказ
Нередки ситуации, когда не устанавливается принтер, хотя система видит, что к компьютеру подсоединилось новое оборудование. Решение такой задачи требует серьезного...
Фото спортивных мужчин 40 лет
17. Джерард Батлер, 48 лет (kinopoisk) «Законопослушный гражданин» Джерард Батлер когда-то работал официантом, демонстратором игрушек и даже юристом. Он также...
Adblock detector