Работа с часами реального времени DS1307
Дата: 13 Февраля 2014. Автор: Алексей
Здравствуйте!
Сегодня я хочу Вам поведать о такой интересной микросхеме как DS1307. Это чудные часики плюс календарь и самое замечательное что к этой микрухе есть библа в CVAVR. Да и просто она мне под руку попалась и я решил ее помучить 8) Первым делом нам понадобится схема ее подключения. Она довольно проста и была взята из даташита. Но тут есть небольшое исключение. В даташите требуют подключить резистор между ножкой питания и ножкой вывода прямоугольных импульсов. Так как я делал отдельную плату, дабы иметь возможность на ней тестировать дальнейшие проекты, приляпал еще светодиод. Очень удобно получилось. Видно например секундные импульсы.
Собственно схема.
А вот как это выглядит в сборе.
![Плата в сборе верх DS1307](/picture/articles/rtc/pcb_top.jpg)
![Плата в сборе низ DS1307](/picture/articles/rtc/pcb_bot.jpg)
Испытания я проводил в связке ATmega32 + LCD 16x2 + DS1307. Далее есть два варианта. Первый, можно сгенерить код прям генератором CVAVR. Второй, самому все написать. Я предлагаю писать самому, но сначала давайте пройдемся по функциям DS1307.
1. rtc_init(rs, sqwe, out) Эта самая первая функция для инициализации микросхемы. Теперь все аргументы по порядку. rs нужен для того чтобы задать частоту выходных прямоугольных импульсов на ноге SQW/OUT. 0 - 1 Гц 1 - 4096 Гц 2 - 8192 Гц 3 - 32768 Гц sqwe нужен для разрешения выхода прямоугольных импульсов. 1 - можно 0 - нет. out нужен для определения логического уровня на выходной ноге если нет разрешения на вывод прямоугольных импульсов. Во загнул. Короче если не нужно дергать ногой SQW/OUT, то параметр sqwe ставим в 0 и теперь если out равен 1, то и на ножке будет 1, а если запишем 0, то и на ноге тоже 0. Пример: rtc_init(0,1,0); Это значит включить вывод прямоугольных импульсов с частотой 1 Гц. 2. rtc_set_time(hour, min, sec) Ну из названия видно что эта функция устанавливает время. Тут все просто, аргументы часы, минуты и секунды. 3. rtc_set_date(day, month, year) Та же шляпа но с датой. 4. rtc_get_time(&hour, &min, &sec) А вот тут по подробнее. Эта функция нужна для получения текущего времени. Аргументы функции являются адреса переменных куда она потом запишет значения. Это сделано из-за того что функции могут возвращать лишь один параметр (такой вот С). То есть перед вызовом функции нужно проинициализировать три беззнаковые переменные char. 5. rtc_get_date(&day, &month, &year) То же самое но с датой. Теперь все то же на примерах. rtc_set_time(15, 0, 0); Установили время 15:00:00 rtc_set_date(14, 2, 14); Установили дату 14 февраля 2014 г. Заметьте что год пишется двумя числами. Кусок даташита:Ну вроде как и все. Для старта я думаю понятно, а там кому как. Вот как это выглядит в работе.Real-Time Clock (RTC) Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the week, and Year with Leap-Year Compensation Valid Up to 2100 До 2100 года, а так как у нас в функцию передается unsigned char, то значение может приниматься от 0 до 255. Я не пробовал загонять больше ста, но записанный с перепугу 2014 год отображался как 144 8) unsigned char hour, min, sec; rtc_get_time(&hour, &min, &sec); Сначала инициализируем переменные, а после вызываем функцию. После ее вызова можно смело оперировать временем которое запишется в переменные. unsigned char day, month, year; rtc_get_date(&day, &month, &year); В принципе тут тоже самое только в переменных будет лежать дата. Ну и наконец вся программа с коментами как и обещал. /***************************************************** Программа для работы с часами реального времени DS1307 Микроконтроллер: ATmega32 Частота кварца: 3,686400 MHz *****************************************************/ #include <mega32.h> // Указываем порт и пины для шины I2C #asm .equ __i2c_port=0x1B ;PORTA .equ __sda_bit=0 .equ __scl_bit=1 #endasm #include <i2c.h> // Подключаем библиотеку для работы с DS1307 #include <ds1307.h> // Указываем к какому порту подключен ЖКИ #asm .equ __lcd_port=0x12 ;PORTD #endasm // Подключаем библиотеку для работы с ЖКИ #include <lcd_rus.h> // Подключаем библиотеку для работы со строками #include <stdio.h> void main(void) { // Инициализация массива для строки и переменные для данных unsigned char string[20]; unsigned char c, m, s, d, me, g; PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; // Инициализация шины I2C i2c_init(); // Инициализация DS1307 rtc_init(0,1,0); // Инициализация дисплея lcd_init(16); // Эти функции я использовал один раз для установки времени и даты. // rtc_set_time(16, 0, 0); // rtc_set_date(13, 2, 14); while (1) { // Получили время rtc_get_time(&c, &m, &s); lcd_gotoxy(0,0); // Отформатировали sprintf(string, "Время %02i:%02i:%02i ", c, m, s); // Вывели время lcd_puts(string); // Получили дату rtc_get_date(&d, &me, &g); lcd_gotoxy(0,1); // Отформатировали sprintf(string, "Дата %02i.%02i.20%2i ", d, me, g); // Вывели дату lcd_puts(string); }; }
![Вывод на ЖКИ](/picture/articles/rtc/rtc_lcd.jpg)
![Все в сборе](/picture/articles/rtc/rtc_lcd_all.jpg)
Роман 29.10.15 21:30
Спасибо за статью, все понятно и без воды.
Алексей 29.10.15 22:47
Стараюсь)
Женя 07.11.15 09:33
Алексей спасибо большое!
Алексей 07.11.15 10:23
Пожалуйста.
Петр 05.04.16 00:11
А в проге flowcode реально это повторить?
Алексей 05.04.16 08:52
А что это за программа?
Михаил 09.09.16 00:18
Огромное спасибо автору за статью.Все оч. просто и доступно описано
Алексей 09.09.16 12:16
Спс.
Сергей 20.11.16 12:28
Спасибо за подробное объяснение примеров. Не могли бы Вы дополнить пример ручной установки времени в RTC? Иногда корректировка времени все таки нужна.
Алексей 20.11.16 15:33
Для полноценной работы с часами реального времени DS1307 и DS3231 мной написаны функции которые входят в библиотеку axlib. Рекомендую использовать axlib генератор для боле упрощенной генерации проекта под Atmel Studio. Так же можно посмотреть видео о использовании данной библиотеки.
Вениамин 10.12.16 23:33
rtc_set_date(13, 2, 14);
На такую запись компилятор может ругаться "too few arguments" так как должно передаваться 4 аргумента, первый из которых - день недели. Поэтому передавать нужно 4 числа, и забирать - тоже 4. Насколько мне известно в некоторых версиях codevision прокатывает с тремя, но я лично порядком повозился, пока выяснил почему у меня время спокойно пишется и читается, а дата - нет.
На такую запись компилятор может ругаться "too few arguments" так как должно передаваться 4 аргумента, первый из которых - день недели. Поэтому передавать нужно 4 числа, и забирать - тоже 4. Насколько мне известно в некоторых версиях codevision прокатывает с тремя, но я лично порядком повозился, пока выяснил почему у меня время спокойно пишется и читается, а дата - нет.
Алексей 11.12.16 00:00
Вот поэтому я забил на CVAVR с ее косяками (а они не только в часах), перешел на AtmelStudio и написал библиотеку под нее а-пя CVAVR. Теперь у меня все работает и не глючит.)))
АНОНИМ 02.03.17 00:39
Всем советую заменять Ds1307 на 3231 т.к 32я намного точней, а 1307 только для таймеров подходит.
АНТОНИМ 03.04.17 15:18
намного точней - это на сколько именно? ИМХО точность часов определяется на 99,9999999 % точностью кварцевого резонатора.
Алексей 03.04.17 16:09
Ну не совсем. Человек наверное просто имел в виду термокомпенсацию, так как частота кварца зависит еще и от температуры.
ИгорьКазанце 31.07.19 16:54
Ситуация: Купил микруху DS1307. Спаял Вашу схему. Нужна единственная функция - выход секундных импульсов. Больше ничего не нужно. Что делать? Какой использовать программатор? vespe2012@gmail.com
Алексей 01.08.19 10:50
Программатор не нужен. Нужно написать программу под любой МК который передаст команду для задания частоты выходной ножки SQW/OUT. Далее пока есть напряжение на микросхеме, на выходе будет меандр в 1ГЦ.