Делаем точные часы с календарем на DS1307 + LCD + ATMEGA8, с меню и будильником.
Привет! Итак, начнем! Сначала немного теории: DS1307 - часы реального времени с последовательным интерфейсом - низкая потребляемая мощность, полный BCD календарь, часы плюс 56 байтов энергонезависимого статического ОЗУ. Адрес и данные передаются последовательно через 2-проводную двунаправленную шину. Часы / календарь хранят следующую информацию: секунды, минуты, часы, день, дату, месяц и год. Конец месяца автоматически подстраивается для месяцев, в которых менее 31 дня, включая поправку для високосного года. Часы работают в 24-часовом или 12-часовом формате с индикатором AM/PM. DS1307 имеет встроенную схему контроля питания, которая обнаруживает пропадание питания и автоматически переключает схему на питание от батареи.
DS1307
С использованием этой микросхемы минимально будет грузиться наш микроконтроллер.
Итак приступим, создадим новый проект мастером.
дальше установим все ножки порта D как выход з подтяжкой резисторов pull-up (пометка - P)
Включим саму шину I2C.
Дальше подкорректируем и допишем код со всеми условиями и соберем схему.
rtc_get_time(&hour,&min,&sek); //считать время rtc_get_date(&day,&month,&year); //считать дату if (PINC.0==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора inf++; // к значению минуты добавляем еденицу } if (inf==0) { lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Time is="); 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); lcd_gotoxy(0,1); lcd_putsf("Date is="); lcd_putchar(day/10+0x30); lcd_putchar(day%10+0x30); lcd_putchar('-'); lcd_putchar(month/10+0x30); lcd_putchar(month%10+0x30); lcd_putchar('-'); lcd_putchar(year/10+0x30); lcd_putchar(year%10+0x30); // проверка на будильник if ((alm==1)&(a_min==min)&(a_hour==hour)) PORTD.2=1; // отключение будильника if (PINC.5==0) { alm=0; PORTD.2=0; } } if (inf==1) {
lcd_clear(); lcd_putsf("Set Time"); lcd_gotoxy(0,1); lcd_putchar(hour/10+0x30); lcd_putchar(hour%10+0x30); lcd_putchar(':'); lcd_putchar(min/10+0x30); lcd_putchar(min%10+0x30); if (PINC.1==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min++; } if (PINC.2==0) // если нажата вторая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора min--; } if (PINC.3==0) // если нажата третья кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour++; } if (PINC.4==0) // если нажата четвертая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора hour--; }
if (min==60||min==255) // если мин = 60 или 255 { min=0; // зануляем переменную "минута" } if (hour==24||hour==255) // так как у нас часы имеют 24 часовый формат { // при достыжении 24 часов, онулируем все переменные. hour=0; } rtc_set_time(hour,min,sek); // установка времени }
if (inf==2) { lcd_clear(); lcd_putsf("Set Data"); lcd_gotoxy(0,1); lcd_putchar(day/10+0x30); lcd_putchar(day%10+0x30); lcd_putchar('-'); lcd_putchar(month/10+0x30); lcd_putchar(month%10+0x30); lcd_putchar('-'); lcd_putchar(year/10+0x30); lcd_putchar(year%10+0x30); if (PINC.1==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора day++; } if (PINC.2==0) // если нажата вторая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора month++; } if (PINC.3==0) // если нажата третья кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора year++; } // условие на переолнение if (day==32) day=0; if (month==13) month=0; if (year==99) year=0; rtc_set_date(day,month,year); //установить дату: день,месяц,год } if (inf==3) { lcd_clear(); lcd_putsf("Set ALARM"); lcd_gotoxy(0,1); lcd_putchar(a_hour/10+0x30); lcd_putchar(a_hour%10+0x30); lcd_putchar(':'); lcd_putchar(a_min/10+0x30); lcd_putchar(a_min%10+0x30); if (PINC.1==0) // если нажата первая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора a_min++; } if (PINC.2==0) // если нажата вторая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора a_min--; } if (PINC.3==0) // если нажата третья кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора a_hour++; } if (PINC.4==0) // если нажата четвертая кнопка { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора a_hour--; }
if (a_min==60||a_min==255) // если мин = 60 или 255 { a_min=0; // зануляем переменную "минута" } if (a_hour==24||a_hour==255) // так как у нас часы имеют 24 часовый формат { // при достыжении 24 часов, онулируем все переменные. a_hour=0; }
} if (inf==4) { lcd_clear(); lcd_putsf("ON/OFF Alarm"); if (PINC.5==0) // on/off alarm { delay_ms(250); // задержка 1/4 сек. (для удобства) выбора alm++; } lcd_gotoxy(0,1); if (alm==0) lcd_putsf("Alarm OFF"); if (alm==1) lcd_putsf("Alarm ON"); } if (inf==5) inf=0; }
};
Есть одна особенность, здесь мы используем маленькое меню на 4 пункта.
Особенность роботы. В нормальном режиме мы видим время и дату. Дальше при нажатии на первую кнопку МК переходит в режим настройки времени, еще раз нажимаем на кнопку и МК переходит в режим настройки даты, еще раз и в режим настройки будильника, после очередного нажатия кнопки мы переходим в режим установки будильника ВКЛ/ВЫКЛ будильник. Стандартно будильник выключен.Следующие кнопки служат для установки времени и даты, смотря в каком режиме находиться МК. Последняя кнопка служит для выключения светодиода после срабатывание будильника. В место светодиода можно использовать Buzzer. Будьте внимательны по подключению DS1307, подключайте согласно даташиту.
Собрал. Не работает. На жк дисплее ничего нет. Дисплей использовал wh1602b. Пробовал два той же марки - результат один. В чем может быть проблема? Какие фьюзы выставлять?
Здравствуйте. Всё нашел, вопрос снимается. " 32 HiSER (26.06.2011 11:00) Есть здесь все, времени нет... И рекламу давать других сайтов это не хорошо..." А как быть, если все молчат. Кому тут вопросы задавать, я задал а что толку.
Здравствуйте. Вот решил попробовать часы реального времени, но при компиляции программы, выскакивает ошибка. Начал разбираться, оказалось что в CodeVision не было #include <ds1307.h>, а точнее библиотеки и хидера. Как у Вас всё работало? Если есть библиотека, и хидер - скиньте пожалуйста ссылку.
Вобщем всё сделал, вся загвоздка была в том, что не было батарейки(или не была vBat заземлена) сейчас часики тикают(проверил это путём передачи из МК через RS-232 переменной, которая получает данные с таймера с помощью функции rtc_get_time(&hour,&min,&sek)). Спасибо огромное Medved’у, что помог в этой ситуации... его страничка http://avrdevices.ru там много чего интересного можно вычитать и совет ещё дадут) Жаль, что здесь нет тех. поддержки.
Добрый день! Уже совсем всё перепробывал! уже и новый кварц ставил, и таймер менял, и резисторы какие-только не пробовал.... вообщем подключил всё как на схеме( подключил к scl и sda резисторы на 4.7 кОм). Создал проект с помощью визарда. скомпилил. Импульсы на ножках scl и sda идут, при нажатии на кнопку ( при нажатии на кнопку запускается процеудра rtc_get_time(&hour,&min,&sek);) Всё вроде бы хорошо, НО... На кварце(а он 32.768 кГц) нет синусоиды, на одной ножке (X2) примерно +0.5 В, на другой (X1) 0В. импульсы от SQW/OUT не идут....То есть таймер похоже не запускается....Я уже второй такой таймер подключаю... и ничего.... вообщем уже завозился с ним, помогите, кто сможет! Заранее спасибо!)
Когда разбирался с программой выяснились следующие моменты: 1. DS1307 не работает при частоте 2Wire больше 100кГц(См datasheet). В авторском варианте 400кГц. Я так понимаю автор моделировал в Proteus, а он не обращает внимания на частоту. 2. Если есть малейшая помеха по питанию обмен данными с DS1307 происходит не корректно.