Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Часы на DS3231 и AVR-микроконтроллере

Сегодня мы продолжим поиски идеальной микросхемы часов реального времени (RTC). Часы будем изготавливать на основе DS3231. Индикация будет использоваться более удобная для разработки - LCD дисплей, на котором будет отображаться вся информация сразу кроме настроек. В таком виде часы удобно использовать как настольный вариант.

Итак, рассмотрим саму микросхему DS3231. DS3231 - это часы реального времени с экстремально точным ходом (подобрали же производители словечко) благодаря встроенному кварцевому резонатору с температурной компенсацией. Интерфейс передачи данных - I2C. В этой микросхеме есть также вход для напряжения резервной батареи, при отключении основного питания микросхема автоматически переключается на работу от резервной батареи, точность хода от резервной батареи не нарушается. Весьма радует, не правда ли? В DS3231 поддерживается подсчет секунд, минут, часов, дней месяца (даты), дней недели, месяцев и лет (с учетом високосного года для месяцев). Поддерживается работа в 12 и 24 часовом формате. Имеется 2 будильника с возможностью их настройки и отслеживания состояния. Подстройка точности температурной компенсации. А также два выхода - на 32 кГц (выход составляет 32.768 кГц) и программируемый выход от 1 Гц до 8.192 кГц. Имеется также вывод сброса - RST. микросхема часов реального времени выпускается в корпусе SO-16. Корпус достаточно крупный, но если учитывать что внутри уже имеется кварц, да еще и температурно компенсируемый, то мне кажется, с размерами тут все отлично. У DS3231 есть близнец в виде DS3232, у которого, правда, на 2 ножки больше. Все это очень напоминает продукцию компании NXP - микросхемы часов PCA2129 и PCF2129. Аналогично температурно компенсируемый встроенных кварцевый резонатор, оба такие же близнецы только с разным количеством n.c. выводов и схожими функциями относительно DS3231 помимо хронометрожа времени.

RTC DS3231 имеются в продаже в виде модулей с необходимой обвязкой, а также до комплекта микросхемой EEPROM, которая чаще всего и даром не нужно, только веса добавляет:

Кроме необходимых деталей на плате модуля есть также светодиод, функция которого - индикация подключения питания к выводам. Наверно просто так доставили, для красоты.

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

Запись данных необходима для первоначальной настройки, а также для настройки текущего времени. Далее нам нужно постоянно получать данные о текущем времени и даты. Для этого необходимо осуществлять чтение из регистров хранения этой информации. Чтение состоит из двух процедур - установить указатель на нужный регистр и прочитать его. Чтобы установить указатель на нужный регистр, нужно передать условие старта, потом передать адрес микросхемы с битом записи и байт с адресом регистра. Далее либо условие остановки и следом условие старта, либо просто рестарт. Теперь вторая процедура - непосредственно чтение из регистров. Старт передан, далее нужно отправить адрес микросхемы с битом чтения и далее считывать регистры в необходимом количестве, по окончании передать условие остановки. Если информация из регистра была прочитана, то указатель автоматически переходит на следующий за ним регистр без лишних действий со стороны микроконтроллера (мастер устройства). На рисунке проиллюстрировано все выше сказанное относительно чтения регистров по средствам I2C интерфейса:

Адрес микросхемы:

  • для записи - 0b11010000
  • для чтения - 0b11010001

Программно код на языке Си будет выглядеть следующим образом:

// функции с часами =======================================================================================================

// инициализация начальных установок
void RTC_init(void){

	i2c_start_cond();               // запуск i2c
	i2c_send_byte(RTC_adr_write);   // передача адреса устройства, режим записи
	i2c_send_byte(0x0E);	        // передача адреса памяти 
	i2c_send_byte(0b00100000);      // запустить преобразование температуры и выход на 1 Гц
	i2c_send_byte(0b00001000);      // разрешить выход 32 кГц
	i2c_stop_cond();                // остановка i2c

}


// получение времени и даты
void RTC_read_time(void){

	i2c_start_cond();               // запуск i2c
	i2c_send_byte(RTC_adr_write);   // передача адреса устройства, режим записи
	i2c_send_byte(0x00);	        // передача адреса памяти 
	i2c_stop_cond();                // остановка i2c

	i2c_start_cond();               // запуск i2c
	i2c_send_byte(RTC_adr_read);    // передача адреса устройства, режим чтения
	sec = bcd(i2c_get_byte(0));     // чтение секунд, ACK
	min = bcd(i2c_get_byte(0));     // чтение минут, ACK
	hour = bcd(i2c_get_byte(0));    // чтение часов, ACK
	wday = bcd(i2c_get_byte(0));    // чтение день недели, ACK
	day = bcd(i2c_get_byte(0));     // чтение число, ACK
	month = bcd(i2c_get_byte(0));   // чтение месяц, ACK
	year = bcd(i2c_get_byte(1));    // чтение год, NACK
	i2c_stop_cond();                // остановка i2c

}


// установка времени
void RTC_write_time(unsigned char hour1,unsigned char min1, unsigned char sec1){

    i2c_start_cond();               // запуск i2c
    i2c_send_byte(RTC_adr_write);   // передача адреса устройства, режим записи
    i2c_send_byte(0x00);	        // передача адреса памяти 
    i2c_send_byte(bin(sec1));       // 0x00 секунды (целесообразно ли задавать еще и секунды?)
	i2c_send_byte(bin(min1));       // 0x01 минуты
    i2c_send_byte(bin(hour1));      // 0x02 часы
    i2c_stop_cond();                // остановка i2c

}


// установка даты
void RTC_write_date(unsigned char wday, unsigned char day, unsigned char month, unsigned char year){

    i2c_start_cond();               // запуск i2c
    i2c_send_byte(RTC_adr_write);   // передача адреса устройства, режим записи
    i2c_send_byte(0x03);	    // передача адреса памяти 
    i2c_send_byte(bin(wday));       // 0x03 день недели (воскресенье - 1, пн 2, вт 3, ср 4, чт 5, пт 6, сб 7)
    i2c_send_byte(bin(day));        // 0x04 день месяц
	i2c_send_byte(bin(month));      // 0x05 месяц
	i2c_send_byte(bin(year));       // 0x06 год
    i2c_stop_cond();                // остановка i2c

}


// чтение температуры
void RTC_read_temper(void){


	i2c_start_cond();               // запуск i2c
	i2c_send_byte(RTC_adr_write);   // передача адреса устройства, режим записи
	i2c_send_byte(0x11);	        // передача адреса памяти 
	i2c_stop_cond();                // остановка i2c

	i2c_start_cond();               // запуск i2c
	i2c_send_byte(RTC_adr_read);    // передача адреса устройства, режим чтения
	t1 = i2c_get_byte(0);           // чтение MSB температуры
	t2 = i2c_get_byte(1);           // чтение LSB температуры
	i2c_stop_cond();                // остановка i2c

	t2=(t2/128); 					// сдвигаем на 6 - точность 0,25 (2 бита)
	                    			// сдвигаем на 7 - точность 0,5 (1 бит)
	t2=t2*5;

}

Это весь исходный код, использовавшийся для работы с микросхемой, подстройка хода часов не затрагивалась, так как и без того часы не ушли ни на секунду за несколько дней.

Да - отличной фишкой DS3231 является то, что эта же микросхема выполняет функции термометра (а то как же еще осуществлять температурную компенсацию) и возможность чтения текущей температуры. Максимальное разрешение температуры составляет 0.25 градусов Цельсия. Также период обновления температуры достаточно большой - около 1 минуты. Да нам быстро то не к чему обновлять ее.

Схема же всего устройства часов выглядит так:

Схема часов на микросхеме DS3231 и AVR-микроконтроллере

Микроконтроллер был выбран Atmega8 за свою широкую распространенность и небольшую цену. Данный микроконтроллер можно использовать как в корпусе DIP-28, так и в SMD исполнении в корпусе TQFP-32. Резистор R3 необходим для предотвращения самопроизвольного перезапуска микроконтроллера в случае появления случайных помех на выводе PC6. Резистор R3 подтягивает плюс питания к этому выводу, надежно создавая потенциал на нем. Для индикации используется жидко кристаллический (ЖК или LCD) дисплей. Мною использовался дисплей 2004А - 4 строки по 20 символов больше для красоты, поэтому можно применять дисплей более привычный - 2 строки по 16 символов. ЖК дисплей подключается к микроконтроллеру по четырех битной системе. Переменный резистор R2 необходим для регулировки контраста символов на дисплее. Вращением движка этого резистора добиваемся наиболее четких для нас показаний на экране. Подсветка ЖК дисплея организована через вывод "А" и "К" на плате дисплея. Подсветка включается через резистор, ограничивающий ток - R1. Чем больше номинал, тем более тускло будет подсвечиваться дисплей. Однако пренебрегать этим резистором не стоит во избежание порчи подсветки. Кнопки S1 - S4 управляют настройками часов. Светодиод сигнализирует о том, что будильник сработал. Светодиод можно заменить на какую-либо звуковую схему. Резисторы R5 - R8 являются подтягивающими (pull-up) и необходимы для формирования прямоугольных импульсов на выводах микросхемы часов. Также это необходимо для правильной работы протокола I2C. Для питания схемы используется микросхема линейного стабилизатора L7805, ее можно заменить на отечественный аналог пяти вольтового линейного стабилизатора КР142ЕН5А, либо применить другу микросхему стабилизатора напряжения в соответствии с подключением ее в схеме (например LM317 или импульсные стабилизаторы LM2576, LM2596, MC34063 и так далее). Далее 5 вольт стабилизируются другой микросхемой - AMS1117 в исполнении, дающей на выходе 3,3 вольта. Микросхема часов, в соответствии с даташитом, питается от напряжения 3,3 вольта. Однако максимальное напряжение составляет 5,5 вольта. Поэтому Данный стабилизатор можно использовать, а можно и нет, на ваше усмотрение. Стабилизатор напряжения AMS1117 можно также заменить на исполнение ADJ (AMS1117ADJ) - то есть регулируемый вариант, задать необходимое напряжение при таком выборе необходимо будет при помощи двух резисторов, подключаемых к микросхеме в соответствии с даташитом на нее. 

Схема была собрана и отлажена с применением отладочной макетной платы для микроконтроллера ATmega8:

Назначение кнопок:

  • S1 - отключает сигнал будильника, либо выходит в главное меню из любого меню настроек
  • S2 - сброс микроконтроллера
  • S3 - изменяет время или дату в меню настроек
  • S4 - вход в меню настроек и перелистывание меню

Вывод 32 кГц может использоваться для контроля частоты кварцевого резонатора. Подключаем к этому выводу частотомер или осциллограф и контролируем частоту:

Как видно из скриншота осциллограммы, частота примерно соответствует 32,768 кГц (примерно в силу ограничения разрешения измерения частоты, а "на глаз" настолько точно трудно определить).

В итоге получились часы со следующими характеристиками:

  • индикация времени
  • индикация даты
  • индикация дня недели
  • индикация активности будильника
  • 1 будильник с выходом сигнала от микроконтроллера
  • индикация температуры окружающей среды (программно реализована только положительная температура, отрицательная, думаю, нам ни к чему)
  • настройки будильника
  • настройки времени
  • настройки даты
  • LCD-дисплей с подсветкой
  • сохранение настроек и продолжение хода часов при отключении основного питания

Подытожим. Микросхема часов реального времени DS3231 является отличным решением. Точность хода сравнительно c какой-нибудь DS1307 или PCF8523 выше, а вот PCA/PCF2129 еще могут потягаться с ней. Среди рассмотренных мною микросхем часов реального времени данный экземпляр на сегодняшний день занимает первое место по функционалу и точности.

Для программирования микроконтроллера Atmega8 необходимо знать конфигурацию фьюз битов (скриншот сделан в программе AVR Studio):

К статье прилагается прошивка для микроконтроллера Atmega8, проект схемы в программе Proteus, а также видео работы часов (в самом начале сработает будильник - загорится светодиод).

Список радиоэлементов

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
IC1 МК AVR 8-бит
ATmega8
1 Поиск в магазине ОтронВ блокнот
IC2 Часы реального времени (RTC)
DS3231
1 Поиск в магазине ОтронВ блокнот
VR1 Линейный регулятор
L7805AB
1 Поиск в магазине ОтронВ блокнот
VR2 Линейный регулятор
AMS1117-3.3
1 Поиск в магазине ОтронВ блокнот
VD1 Выпрямительный диод
1N4148
1 Поиск в магазине ОтронВ блокнот
C1 Электролитический конденсатор470 мкФ1 Поиск в магазине ОтронВ блокнот
C2, C3, C5, C7 Конденсатор100 нФ4 Поиск в магазине ОтронВ блокнот
C4 Электролитический конденсатор220 мкФ1 Поиск в магазине ОтронВ блокнот
C6, C8 Электролитический конденсатор10 мкФ2 Поиск в магазине ОтронВ блокнот
R1 Резистор
22 Ом
1 Поиск в магазине ОтронВ блокнот
R2 Подстроечный резистор10 кОм1 3296W-1-103LFПоиск в магазине ОтронВ блокнот
R3, R5-R8 Резистор
10 кОм
5 Поиск в магазине ОтронВ блокнот
R4 Резистор
390 Ом
1 Поиск в магазине ОтронВ блокнот
R9 Резистор
220 Ом
1 Поиск в магазине ОтронВ блокнот
LED1 Светодиод1 Поиск в магазине ОтронВ блокнот
HG1 LCD-дисплей2004A1 Можно заменить на SC1602Поиск в магазине ОтронВ блокнот
S1-S4 Тактовая кнопкаTC-A1094 Поиск в магазине ОтронВ блокнот
Элемент питанияCR20321 3 ВольтПоиск в магазине ОтронВ блокнот
Держатель CR20321 Поиск в магазине ОтронВ блокнот
Добавить все

Скачать список элементов (PDF)

Прикрепленные файлы:

Теги:

Опубликована: Изменена: 12.06.2016 0 6
Я собрал 3 4
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 4.7 Проголосовало: 4 чел.

Комментарии (70) | Я собрал (0) | Подписаться

0
yuraivan #
Интересная статейка! А не могли бы Вы весь исходник выложить?
Ответить
+1

[Автор]
Gauss #
Вот
Прикрепленный файл: 38.c
Ответить
-3
hasl #
У микросхемы напряжение питания до 5.5В. Зачем стаб на 3,3В поставили? Воздух греть?
Ответить
+3

[Автор]
Gauss #
Потому что напряжение 3,3 В - заданное напряжение питания, а 5,5 В - максимальное, а так да - холодно же, осень
P.S. Если у автомобиля шкала тахометра 8000 оборотов, а нормальные обороты для езды 2-3 тыс, то Вы ездите на 7000?
Прикрепленный файл: 1Снимок.PNG
Ответить
0
hasl #
Не убедили. Вы наверное гадали и вам было сказано, что на 5 вольтах микруха проживет на несколько часов меньше?
Избыточность схемы - явная
Ответить
+3

[Автор]
Gauss #
Горе то какое, не убедил, я и не пытался вам ничего доказать, представил факт и все
Ответить
0
begunof #
Не удачный пример. В диапазоне 2.3 - 5.5В гарантирована работа. В случае же двигателя повышение оборотов повышают износ. Часы на DS3231 работают без сбоев от 5В годами с паспортной точностью хода.
Ответить
0
atac13 #
Пробовал открыть протеусом 7 и 8 версией - не открывает.
Ответить
0

[Автор]
Gauss #
Как не открывает, люди здесь не провидцы, может просто распаковать архив надо?
Ответить
0
Алексей #
Уважаемый автор, а не проверяли - какое минимальное напряжение питания у этих часов ? У меня устройство в питанием 3 вольта и с часами ds1338-33, при снижении питания до 2,9в уже не работает. Ищу замену часикам.
Ответить
0

[Автор]
Gauss #
Проверять сам не проверял, а по документации минимальное напряжение 2,3 вольта, в целом склонен верить, что будет работать ниже 3 вольт
Ответить
0
Антон #
А разве там не меандр должен быть?
Ответить
0
logan_od #
Выложи пожалуйста I2C библиотеку.
Ответить
0
Андрей #
А что за типоразмер чип компонентов? Я как то пытался разместить 1206 /0805 и большие они получаются, выходит только самые маленькие - 0504 или вообще 0402, я не уверен, получится ли уже сделать у меня под такую мелочь компоненты
Ответить
0

[Автор]
Gauss #
0805 и 2 сборки резисторов по 4.7кОм, если про сам модуль
Ответить
0
Андрей #
Ну вот слева скажем от МК, их там 4 в ряд еще стоят, 2 резистора и 2 кондера, я думал, 0805 крупноваты туда, я распечатал плату как было сказано в 50% масштабе, там чутка меньше 2мм выходит, но ладно, не критично...
Ответить
0

[Автор]
Gauss #
Там 1 резистор, 1 светодиод, 2 конденсатора и 2 сборки, а какая плата вообще? Это все заводского изготовления
Ответить
0
AlexAVR #
Уважаемый Gauss, спасибо за отличный проект! Собрал, все заработало! Но где-то видимо я ошибся, не сохраняются настройки будильника при выключении питания. Только начинаю осваивать микроконтроллеры, хочется самому разобраться. Не могли бы Вы выложить или прислать на email библиотеки bcd.h, lcd_lib_2.h, i2c.h, buttons.h ?
Ответить
0

[Автор]
Gauss #
Если сами писали на основе примера, то сохранение идет в eeprom, нужно только подключить #include avr/eeprom.h и сохранять переменные и загружать при включении командами
Ответить
0
AlexAVR #
Не писал, использовал прошивку из Вашей статьи - http://cxem.net/mc/files/mc316_38.hex. Почему-то не сохраняется. Мучить Вас вопросами "почему?" не хочется и самому интересно разобраться. К тому же хотел использовать четырехстрочный индикатор, выводить будильник отдельной строкой, добавить датчик влажности... Вобщем поучиться на основе Вашего проекта. Стал разбираться в исходниках из Вашего поста http://cxem.net/mc/mc316.php#comment-32954, но не хватает библиотек. Был бы очень благодарен за ссылки на библиотеки.
Ответить
0

[Автор]
Gauss #
Нажми на Gauss, там вылетит страничка с моим профилем и в других проектах все есть и думать не надо, а сохраняться должно, может баг какой
Ответить
0
AlexAVR #
Как раз хочется подумать и поучиться. Все ваши статьи я первым делом полез читать. В принципе все нужные библиотеки собрал из нескольких Ваших проектов - http://cxem.net/mc/mc303.php и http://cxem.net/mc/mc295.php. Только нет уверенности, что библиотеки из других проектов применимы к данному.
Ответить
0

[Автор]
Gauss #
Чего это не применимы вдруг? Советую почитать как инициализируются модули для мк, для различных мк
Ответить
0
AlexAVR #
Повнимательнее поразбирался с исходниками и увидел, что сохранение будильника в eeprom у вас идет при переходе из меню настройки будильника в меню настройки часов. А если менять будильник и выходить кнопкой выхода из меню, то переменные в памяти меняются, а в eeprom не пишутся. Т.е. меняю значения, выхожу, снова вхожу - вижу те данные, которые вводил. Выключаю, включаю - данные старые... Это меня и смутило. Добавил для себя запись по кнопке выхода из меню настройки будильника, так вроде логичнее. Кстати, скомпилированная мной прошивка занимает в памяти МК на 511 байт меньше чем Ваша. Но при этом вроде все работает также. Чудеса. Хотя может быть компиляторы разные. Я компилировал в Atmel Studio 6 (Version: 6.2.1563 - Service Pack 2)
Ответить
0

[Автор]
Gauss #
Вот и красава, тогда и я скачаю 6 студию, раньше она давала более худшие решения
Ответить
0

[Автор]
Gauss #
До конца меню получается не доходил, вот и не сохранялось в память
Ответить
0
radiomanoff #
Большое спасибо, за код.
Подключил к Atmega32, часы в виде модуля на фото в вверху.
Обнаружилась странная особенность. Часы иногда зависают. На дисплее, что-то типа 85:85:85, temp 225. То есть они идут-идут и зависли. Лечится банальным отключением на несколько часов!
Судя по всему, часы боятся касаний пальцами и слишком длинных шлейфов. Скорей всего нужна экранировка. Впрочем DS1307 этим тоже "грешат"...
Ответить
0

[Автор]
Gauss #
Этим грешит I2C интерфейс - подтягивающие резисторы должны быть меньше при больших длинах линий, чтобы вникнуть в вопрос советую посмотреть как образуются сигналы в I2C - тогда станет ясно, что палец может вносить как собственные помехи, так и своим, хоть и большим , сопротивлением (зависит от мытости рук) закорачивать линии, искажая сигнал
Ответить
0
Johnowich #
У меня есть вопросы по Вашим часам.
Хотел узнать, сколько по времени активен сигнал будильника? И еще хотел спросить: если у меня уже есть часы, собранные с применением микросхемы DS1307, возможна ли ее замена на модуль DS3231? Заранее спасибо за ответ
Ответить
0

[Автор]
Gauss #
Насколько помню - пока не выключишь.
Совместимы только по времени и дате первые 7 регистров.
Отредактирован 21.09.2015 20:48
Ответить
-2
johnowich #
Спасибо за ответ! А Вы могли бы в программе ввести ограничение по времени длительности работы будильника? Скажем, одной минутой. Или, вообще, ввести в меню возможность управления длительностью работы будильника. Можно ли сделать так, чтобы дни недели были на русском и, по возможности, чтобы отображались полностью? Думаю, это будет еще наглядней. Если это возможно и Вас не затруднит.
Ответить
-1

[Автор]
Gauss #
Все возможно
Ответить
0
Vladimir068 #
У меня модуль почему-то считывает время только один раз
повторно виснет на инструкции StartCondition, т.е. данная инструкция второй раз уже не выполняется. Почему бы это?
В продолжение вышесказанного. Подтыкаю вместо 3231 модуль с 1307 - все работает. В чем все-таки различие между ними?
I2C инициализирую 100 кГц. Использую свою библиотеку с железным I2C, т.е прописываю TWBR, TWCR, TWDR и тд.
Ответить
0

[Автор]
Gauss #
Откуда уверенность, что на именно на этом этапе виснет?
Ответить
0
Vladimir068 #
В начале бесконечного цикла вызываю старт, зажигаю светодиод, потом идет код считывания и обработки байтов с микросхемы, отдаю все это в UART, затем задержка в секунду, потом тушу светодиод, потом опять задержка в секунду - конец цикла. Вот когда вешаю 1307 - светодиод мигает регулярно и дата со временем отдаются в UART, а когдо вешаю 3231 - загорается, тухнет и больше не загорается. Если включение светодиода ставлю вначале цикла до старта, то загорается на втором цикле, если после - нет. Могу завтра выложить код, но думаю что и без него понятно
Ответить
0
Vladimir068 #
Вот основной код
int main(void)
{
unsigned char sec,min,hour,day,date,month,year;
PORTD=0x00;
DDRD=0xFF;
//Скорость USART 115200 при кварцевом генераторе 8MHz
USART_Init (8);
I2C_Init();
while(1)
{
//PORTD|=(1<<PORTD2); //если включаем лапку тут, то
светодиод зажигается во 2м цикле
//Читаем время
I2C_StartCondition(); // генерируем условие СТАРТ
PORTD|=(1<<PORTD2); //если включаем лапку порта тут, то светодиод зажигается только в 1м цикле
I2C_SendByte(0b11010000); //оправляем адрес устройства+бит запись

I2C_SendByte(0);//отправляем байт данных
I2C_StopCondition();//генерируем условие СТОП


// I2C_SendPocket(0,0b11010000);
I2C_StartCondition();
I2C_SendByte(0b11010001);
sec = I2C_RecieveByte();
min = I2C_RecieveByte();
hour = I2C_RecieveByte();
day=I2C_RecieveByte();
date=I2C_RecieveByte();
month=I2C_RecieveByte();
year=I2C_RecieveLastByte();
I2C_StopCondition();
sec = ds1307_perev_for_me(sec);
min = ds1307_perev_for_me(min);
hour = ds1307_perev_for_me(hour);
day = ds1307_perev_for_me(day);
year = ds1307_perev_for_me(year);
month = ds1307_perev_for_me(month);
date = ds1307_perev_for_me(date);
USART_Transmit(date/10+0x30);
USART_Transmit(date%10+0x30);
USART_Transmit('.');
USART_Transmit(month/10+0x30);
USART_Transmit(month%10+0x30);
USART_Transmit('.');
USART_Transmit('2');
USART_Transmit('0');
USART_Transmit(year/10+0x30);
USART_Transmit(year%10+0x30);
USART_Transmit(' ');
USART_Transmit('-');
USART_Transmit(day+0x30);
USART_Transmit('-');
USART_Transmit(' ');
USART_Transmit(' ');
USART_Transmit(hour/10+0x30);
USART_Transmit(hour%10+0x30);
USART_Transmit(':');
USART_Transmit(min/10+0x30);
USART_Transmit(min%10+0x30);
USART_Transmit(':');
USART_Transmit(sec/10+0x30); //Преобразуем число в код числа
USART_Transmit(sec%10+0x30);
USART_Transmit(0x0d);//переход в начало строки
USART_Transmit(0x0a);//переход на новую строку
_delay_ms(1000);
PORTD&=~(1<<PORTD2);
_delay_ms(1000);
}
}

А вот тела некоторых используемых функций

//преобразование из двоично- десятичной системы в двоичную
#define ds1307_perev_for_me(x) ((x>>4)*10)+(0b00001111&x)

//преобразование из двоичной в двоично-десятичную систему
#define ds1307_perev_for_ds(x) ((x/10)<<4)|(x%10)

void I2C_Init (void)
{
TWBR=0x08;//скорость передачи при 8 мгц тактовой частоты получается 100 кгц
}
//----------------------------------------
// отправка команды СТАРТ
void I2C_StartCondition(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
}
//----------------------------------------
// отправка команды СТАРТ
void I2C_StartCondition2(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA);
while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
}
//----------------------------------------

// отправка СТОП
void I2C_StopCondition(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
//----------------------------------------
//----------------------------------------
//отправка байта
void I2C_SendByte(unsigned char c)
{
TWDR = c;//загрузка значения в регистр данных
TWCR = (1<<TWINT)|(1<<TWEN);//начаало передачи байта данных
while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
}
//----------------------------------------
//отправка SLA_W + байт данных
void I2C_SendPocket (unsigned char value,unsigned char adres_rw)
{
I2C_StartCondition(); // генерируем условие СТАРТ
I2C_SendByte(adres_rw); //оправляем адрес устройства+бит запись
I2C_SendByte(value);//отправляем байт данных
I2C_StopCondition();//генерируем условие СТОП
}
//----------------------------------------
//добавляем функции чтения по I2C
//чтение байта
unsigned char I2C_RecieveByte(void)
{
unsigned char dat;//переменная хранения значения
TWCR |= (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
dat = TWDR;//читаем регистр данных
return dat;
}
//----------------------------------------
//чтение последнего байта
unsigned char I2C_RecieveLastByte(void)
{
unsigned char dat;//переменная хранения значения
TWCR |= (1<<TWINT)|(1<<TWEN);//чтение последнего байта
while (!(TWCR & (1<<TWINT)));//ожидание установки бита TWIN
dat = TWDR;//читаем регистр данных
return dat;
}

Все это хозяйство в случае применения Далласа1307 работает, а в случае 3231 - нет.
Может дело в резисторах на 10 ком? Может поменять их в модуле на меньший номинал?
Ответить
0
Vladimir068 #
Поглядел, там стоят резисторные сборки на 4,7 килоом, так что питание к SDA и SCL подтянуто правильно.
Ответить
0
Vladimir068 #
Короче, подключил Вашу библиотеку по работе с шиной, микросхема пошла. Странно, хотелось подключить железную шину. Придется остаться на программной. Спасибо за библиотеку!
Ответить
0

[Автор]
Gauss #
Заработало по моему алгоритму или по тому, что выше?
Ответить
0
Vladimir068 #
По Вашему. Уже прицепил светодиодные индикаторы, завел провод с выхода sq на мигание точки у 2-го разряда, на очереди подключение к схеме фоторезистора для управления свечением посредством шим.
Ответить
0

[Автор]
Gauss #
Все должно работать и с железным I2C, если использовать мои функции, есть подозрение, что без инициализации часов (запуск преобразования температуры) не запустятся сами часы, так как на этом завязана температурная компенсация работы кварца. Это теория, нужно проверять
Ответить
0
Vladimir068 #
В том то и дело, что часы запускаются и в первый раз показания считываются, но считываются именно только один раз.
Ответить
0
Vladimir068 #
А вот когда программирую микросхему памяти EEPROM, находящуюся в корпусе модуля с микросхемой DS1302, то наоборот - всё работает, когда использую железную шину, а если использую ногодрыг на основе Вашего алгоритма, то не работает, мало того данные в памяти стираются. Подозрение, что не подходит задержка.
Она вроде здесь стоит 10 мкс - для частоты 100 кгц, Почитал даташит на AT24C32D - там вроде значатся частоты 400 кГц и 1 мГц. Не понятно только какую задержку делать для 400 мГц. 1000000 на 400000 не делится. Можно конечно написать свою задержку с помощью серии nop-ов.
Как думаете, в этом ли дело или еще в чем?
Ответить
0

[Автор]
Gauss #
Может быть все что угодно, если редактируете код по-своему
Задержка библиотекой стандартной делается, как в ней проблема может быть - не знаю
Ответить
0
Vladimir068 #
Попробую тогда подключить модуль на 3231 и обратиться там к подобной микрухе ЕЕПРОМ. Стандартной не сделаешь задержку 2,5 микросекунды. Она только целочисленные значения принимает.
Ответить
0
Максим #
Скажите для чего на схеме на батарейку идет диод и резистор 220 Ом? Чтобы она заряжалась? Так она же батарейка. И в даташите нет ничего про такой диод и резистор.
Ответить
0

[Автор]
Gauss #
Так сделаны китайские модули, туда можно ставить аккумуляторные 2032, кроме этого батарейка точно не отдает заряд, если есть внешнее питание и при его отсутствии не питает всю остальную схему
Ответить
0
Максим #
Я рассматриваю вариант когда у меня стоит просто батарея 2032, тогда соответственно нужно выпаять этот диод и резистор, а иначе батарейке будет хана изза попытки ее зарядить. Верно? не понимаю зачем китайцы ставят туда акк если производитель дает автономную работу от батареи до 10 лет...
Ответить
0
Юрий #
Вариант печатной платы в layout 50 от gnom 46
Прикрепленный файл: Clok 3231-8.lay
Ответить
0

[Автор]
Gauss #
Плата проверенная? Если хотите, можно добавить плату в статью. А если есть фото, добавляйте их к "я собрал"
Ответить
+1
юрий #
Плата рабочая без ошибок
Прикрепленный файл: 2016-06-11-077_500x375.jpg
Прикрепленный файл: 2016-06-11-078_500x375.jpg
Прикрепленный файл: 2016-06-11-079_500x375.jpg
Прикрепленный файл: 2016-06-11-082_500x375.jpg
Прикрепленный файл: 2016-06-11-083_500x375.jpg
Прикрепленный файл: 2016-06-11-090_500x375.jpg
Ответить
0
юрий #
Печатка и бипер будильника
Прикрепленный файл: BIPER.spl7
Прикрепленный файл: Clok 3231-8.lay
Ответить
0
carlson #
Попробовал сделать печатную плату, но ножки меги сливаются. Они только при большом увеличении показывают зазоры, а в 1:1 не могу понять каким методом ее изготовить.
Ответить
+1
releyshic #
Это у тебя настоящий осциллограф или приставка какая?
Ответить
0

[Автор]
Gauss #
DS203
Ответить
0
lihey.german #
Собрал. В протеусе не проверял. Работают. Автору большое спасибо!
Ответить
0
Валерий #
Каким образом прошивается модуль ds3231? Через микроконтроллер или отдельно?
Вопрос может и некорректный, но я в этом новичок.
Ответить
0

[Автор]
Gauss #
Он работает с контроллером, а не прошивается
Ответить
0
rakel #
Помимо двух упомянутых LCD-дисплеев, какие еще можно использовать в этой конструкции без ее переделки?
Ответить
0

[Автор]
Gauss #
Контроллер hd44780 и нужное количество строк и символов
Ответить
0
Polf #
Почему ATMEGA8 запитана от 3,3 Вольт? По даташиту для контроллера без букв A или L диапазон питания 4.5V - 5.5 Вольт. При применении ATMEGA8 нужно питать её и модуль DS3231 от 5 Вольт, поскольку макс. напряжение лог. единицы для DS3231 составляет Vcc+0,3V
Ответить
0
Максим #
Спасибо за статью!
Применил Ваш код (немного под мои нужды "причёсанный" и разделённый на *.h и *.c ) - и сразу всё заработало!
Вот ещё бы программного slave бы где нарыть - чтоб с любых свободных выводов использовать...
Ответить
0
Максим #
Вот так оно выглядит пока. Может и в самом деле ещё одни часы сделать?
Прикрепленный файл: Изображение 023.jpg
Ответить
0
Максим #
Должен правда заметить: в файле интерфейса i2c я существенно уменьшил задержки, т.к. Ваши дают даже не 100 кГц, а не более 50, в то время как DS3231 в состоянии обеспечить 400 (казалось бы, так ли уж это важно? Но когда микроконтроллер решает много задач и часы - не самая важная из них, есть смысл снизить временные издержки). Ориентируясь на данные микросхемы, я ввёл два значения задержки: по 1,3 и по 0,6 микросекунд (реально длительность этих интервалов больше на два такта, потому что ещё ведь и выводы переключиться должны).
Естественно стандартная функция задержки тут неприменима, но у меня давно уже есть файл задержек - из моих упражнений по inline assembler, эти функции иногда бывают удобнее стандартной.
С этими задержками связка DS3231 + ATmega1284P работает стабильно.
И ещё - надеюсь не в обиду будет - я почистил текст от переопределений работы с битами. Обычный вариант в С - типа DDR_I2C &= ~(1
Прикрепленный файл: I2C.zip
Ответить
0
Иван #
Что делают в программе функции "bcd" и "bin" преобразования чисел (для корректного отображения значений)?
Ответить
0
vishay #
Где в программе задается соответствие кнопок S1, S3, S4 портам PC0, PC1, PC2 ?
Ответить
0
Максим #
Добрый день!
Какой смысл питать DS3231 от 3.3 вольт если линии SCL SDA приходят с уровнями 5 вольт? Надо было на линии ставить согласователь уровней 5-3,3 вольта. Есть схема простая на 2х полевых транзисторах.
Ответить
0
SkyNet #
void RTC_init(void)
Вы уверены что запускаете выход 32кГц ?
Запуск находится в регистре 0Fh, а у Вас запись в 0Eh
Ответить
0
vadegdadeg #
Хочу поблагодарить Gauss'а. Часы понравились. Вывод немного переделал под себя, собрав все исходники воедино с нескольких проектов. На схеме ошибка, у дисплея перепутаны ноги 1 и 2. Добавил сразу четвертую кнопку на PC3, благо для этого даже ничего править не пришлось! Добавил кнопку "минус", повысилось удобство. В планах сделать прерывающийся сигнал на пищалку (выход будильника), завести прерывание от DS3231 обновлять время и мигать разделителем по нему. И еще подсветку дисплея посадить на ШИМ. ПП не разрабатывалась, все спаяно МГТФ'ом, обратную сторону поэтому показывать не буду. Кому нужны именно эти исходники или кекс - пишите.
Прикрепленный файл: IMG_20210321_142345.jpg
Ответить
0
Глеб #
Спасибо. очень полезно.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическое сопротивление?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Солнечная панель 10Вт 12В поликристаллическая USB осциллограф DSO-2090
вверх