Во многих конструкциях полезно
знать текущее время, но не всегда есть возможность, да и если контроллер
будет сильно загружен, то часы будут постоянно отставать или спешить,
что не очень хорошо. Выходом может стать внешний готовый источник
времени – часы реального времени — DS1307.
Фотография модуля
Часы состоят из микросхемы DS1307,
кварца на 32,768Кгц, батарейки и 2-х подтягивающих резисторов на линии
SDA и SLC. Благодаря батарейке они продолжают идти при отключении
внешнего питания. Также у DS1307 есть свободные 56 байтов
энергозависимой статической ОЗУ, которые можно использовать в своих
целях.
Типовая схема включения
Линии SCL и SDA – это I2C. На линии SQW –
находиться тактовый импульс с частотой от 1 Гц до 32,768 Кгц, обычно
она не используется.
Выводы микросхемы
У часов есть пара особенностей:
1. что бы они работали, в них должна быть батарейка
или на крайний случай резистор на 4-10кОм, иначе они не будут работать и
отвечать всяким мусором.
2. вокруг дорожек кварца должен быт замкнутый контур земли и корпус кварц тоже лучше подключить к земле
Немного теории
Хронометр имеет фиксированный адрес 68h, в 7 битовом адресе + 1 бит указывает на действие – чтение/запись.
Для записи используется следующий алгоритм:
Первый байт – адрес часов 68h + 0 бит указывающий на запись, итого D0h.
После получения подтверждения передаётся адрес регистра. Это установит
регистровый указатель. Затем начинается передача байтов данных, чтобы
остановить его – генерируется условие окончания.
Для чтения:
Первый байт – адрес часов 68h + 1 бит указывающий на запись, итого D1h.
После декодирования адреса и выдачи подтверждения устройство начинает
передавать данные с указанного адреса (храниться в регистре указателя).
Если перед началом чтения указатель регистра не записан, то первый
читаемый адрес — это адрес, который был сохранён в нём последним. DS1307
должен принять «неподтверждение» для окончания чтения.
Регистры хронометра DS1307
Для включения часов следует установить
бит CH в ноль, это следует сделать принудительно, т.к. часы после
включения по умолчанию выключены.
Часы хранят информацию в двоично-десятичном виде – для получения данных достаточно прочитать соответствующий им регистр.
DS1307 может работать как в 24, так и в
12 часовом режиме – за это отвечает бит 12/24 (02h 6 бит). При 24
часовом режиме 5 и 4 биты регистра 02h соответствуют текущему десятку
часа, при 12 часовом режиме 4 бит хранит десяток, а 5 признак до полудня
/ после полудня.
7 регистр отвечает за выходной тактовый
генератор часов, SQW вывод. Бит OUT инвертирует выходной сигнал, бит
SQWE включает тактовый генеретор, а биты RS0 и RS1 устанавливают частоту
тактового импульса.
Практика
Был изготовлен небольшой модуль часов
реального времени. На макетке были собраны часы с использованием
микроконтроллера PIC16F628A, знакогенерирующего дисплея 2×16, одной
кнопки для задания времени, модуля часов реального времени и с небольшим
количеством обвязки.
Макетируемые часы
Схема
Печатка модуля
Плата содержит микросхему DS1307 в SMD
исполнении. К ней подпаян кварц на 32,768 КГц, в корпусе DT-38, вокруг
кварца должно быть кольцо земли и корпус самого кварц тоже стоит
подключить к земле, для этого рядом с ним предусмотрено специальное
отверстие. Для работы часов в автономном режиме предусмотрена батарейка
на 3В CR120. Также для индикации работы модуля можно установить SMD
светодиод с резистором на 470 Ом в корпусе типоразмера 0805.
PIC16F628A не содержит аппаратного I2C,
поэтому он был реализован программно. Программный I2C был написан с
нуля, он немного отличается от стандартного протокола, тем, что не ждёт
подтверждения от слейва. Программный I2C будет рассмотрен в одной из
следующих статей. На основе функций работы с I2C были реализованы
следующие функции управления DS1307:
01. void ds_write(unsigned char addr,unsigned char data)
02. {
03. i2c_start();
04. i2c_write(0xD0);
05. i2c_write(addr);
06. i2c_write(data);
07. i2c_stop();
08. }
09.
10. unsigned char ds_read(unsigned char addr)
11. {
12. unsigned temp;
13. i2c_start();
14. i2c_write(0xD0);
15. i2c_write(addr);
16. i2c_stop();
17. i2c_start();
18. i2c_write(0xD1);
19. temp=i2c_read(0);
20. i2c_stop();
21. return temp;
22. }
23.
24. void ds_off()
25. {
26. ds_write(0x00,ds_read(0x00)|0x80);
27. }
28.
29. void ds_on()
30. {
31. ds_write(0x00,ds_read(0x00)&~0x80);
32. }
33.
34. void ds_init()
35. {
36. unsigned char i;
37.
38. i=ds_read(0x02);
39. if ((i&0x40)!=0)
40. {
41. ds_write(0x02,i&~0x40);
42. }
43.
44. i=ds_read(0x00);
45. if ((i&0x80)!=0)
46. {
47. ds_write(0x00,i&~0x80);
48. }
49. }
50.
51. unsigned char IntToBoolInt(unsigned char data)
52. {
53. data=data%100;
54. return data/10*16+data%10;
55. }
ds_write(адрес,байт данных) - отправляет 1 байт данных по указанному адресу DS1307
байт данных ds_read(адрес) - считывает 1 байт данных из указанного адреса DS1307
ds_off() - выключить DS1307
ds_on() - включить DS1307
ds_init() - инициализация DS1307
байт IntToBoolInt(байт) - функция перекодировки числа в двоично-десятичный вид
Во время инициализации проверяются и
устанавливаются, если выключены следующие биты: бит отвечающий за 24-х
часовой режим работы часов и бит отвечающий за включенное состояние
часов. Были реализованы 2 функции для включения и отключения часов.
DS1307 может отправлять и принимать как однобайтовые посылки, так и
много байтовые, но для упрощения работы с часами функции для чтения и
записи только однобайтовые. Для установки часов есть ещё функция для
преобразования привычной десятичной формы представления числа в
двоично-десятичную, в которой микросхема хранит показатели времени.
Приведённых функция для работы с часами вполне достаточно.
В прошивки реализованы функции для считывания и вывода на дисплей времени – time() , даты – date().
В бесконечном цикле через некоторые промежутки времени эти функции
вызываются для вывода времени и даты на дисплей. Рассмотрим, как
устроена функция для чтения с последующим выводом текущего времени:
01. void time ()
02. {
03. unsigned char i;
04. SetLCDPosition(1, 0);
05. i=ds_read(0x02);
06. buffer[0] = i/16+ '0' ;
07. buffer[1] = i%16+ '0' ;
08. buffer[2] = ':' ;
09. i=ds_read(0x01);
10. buffer[3] = i/16+ '0' ;
11. buffer[4] = i%16+ '0' ;
12. buffer[5] = ':' ;
13. i=ds_read(0x00);
14. buffer[6] = i/16+ '0' ;
15. buffer[7] = i%16+ '0' ;
16. buffer[8] = '\0' ;
17. ShowStr(buffer);
18. }
Происходит установка курсора на дисплее. Считываем значение регистра
отвечающего за час и по пол байта, т.к. данные хранятся в
двоично-десятичном виде, записываем в буфер. Далее добавляем разделитель
в виде двоеточия. Считываем и записываем в буфер таким же образом
значения минут и секунд. Выводим содержимое буфера на дисплей. Таким же
образом устроена функция вывода текущей даты.
В прошивки есть функция для установки часов и минут – set_time().
Эта функция с помощью одной кнопки устанавливает время. Как это
делается: нажимаем на кнопку – на дисплее высвечивается надпись «Set
hour :» и количество часов, увеличиваем час по средством коротких
нажатий на кнопку; установив час длительным нажатием переходим на
установку минут, о чём свидетельствует надпись «Set min :», таким же
образом устанавливаем минуты, а длительным нажатием возвращаемся в
бесконечный цикл к часам. Но т.к. эта функция большая приведём из неё
только одну строчку, которая записывает в DS1307 значение минут:
1. ds_write(0x02,IntToBoolInt( time ));
Записываем в регистр, который соответствует минутам желаемое значение, предварительно приведённое к двоично-десятичному виду.
Скачать печатную плату в формате SL5
Скачать Исходники, прошивку и проект часов в Proteus 7.6
|