|
Во многих конструкциях полезно
знать текущее время, но не всегда есть возможность, да и если контроллер
будет сильно загружен, то часы будут постоянно отставать или спешить,
что не очень хорошо. Выходом может стать внешний готовый источник
времени – часы реального времени — 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
|