Часы реального времени DS1302 и микроконтроллер AVR

Просмотров: 42386Комментарии: 16
Электроника. СхемотехникаМикроконтроллеры AVR

Часы реального времени - электронная схема, предназначенная для учета времени, даты, дня недели и др. В общем-то RTC (real time clock - часы реального времени) могут быть реализованы и без специализированных устройств, но использование отдельной микросхемы позволяет добиться более низкого энергопотребления, освободить ресурсы процессора для решения других задач и добиться более высокой точности. Почему выбрал из множества микросхем часов реального времени именно DS1302? Да, просто хотелось поработать с трех проводным интерфейсом и сделать подключение к любым портам МК. 
Итак, скачиваем даташит на микросхему DS1302 и начинаем изучать особенности микросхемы, команды и всю информацию, которая понадобится для работы с этими часами.

Характеристики:
  1. Считает секунды, минуты, часы, день недели, день месяца, месяц, год с учетом высокосных лет до 2100года
  2. Отображение времени в 12 или 24 часовом видах с отображением AM или PM
  3. Питание может находится в диапазоне 2.0 - 5.5В
  4. При 2В потребляет ток меньше 300нА
  5. Простой 3-х проводный интерфейс
  6. Рабочий диапазон температур: -40...+850С
Теперь посмотрим на распиновку микросхемы и описание функций ножек.
В общем-то ничего особенного пока нет. Мне вообще нравятся любые микросхемы с малым количеством внешних деталейsmile. Вот и эту, чтобы подключить нужно припаять кварц и подать питание.
Ну ладно, все подключили, теперь нужно как-то общаться с часами. Эта микросхема имеет трех проводный интерфейс(т.е. 1й провод - разрешение, 2й - синхронизация, 3й - чтение/запись данных), который может быть реализован на любых ножках МК. Для общения с часами микроконтроллер должен посылать им какие-то команды и делать это в такт синхроимпульса. Итак, основные моменты посылки команд:
  • Вход CE должен находится в "1" при чтении или записи данных
  • Запись бит команды в часы происходит по переднему фронту синхроимпульса
  • Чтение бит данных происходит по заднему фронту синхроимпульса, начиная с последнего синхроимпульса команды на чтение данных
  • Данные передаются или читаются начиная с младшего бита
  • Сначала передается команда, а за ней передаются или читаются данные (см.рисунок)
Все команды приведены в таблице ниже (RTC). Из особенностей можно отметить: 
  • По умолчанию часы стоят. Т.е. записать дату и время мы можем, но часы идти не будут. Чтобы они пошли нужно записать в 7-й бит (СH) секундного байта - "0", по умолчанию там "1"
  • 7-й бит (WP) регистра управления защищает от записи данных. Если в этот бит установлен - запись запрещена, если сброшен - разрешена. По умолчанию состояние не определено, поэтому желательно перед записью в устройство этот бит сбросить в "0"
  • Также можно как-то управлять подзарядкой батарейки, точнее если там стоит аккумулятор, для этого есть регистр подзарядки. По умолчанию подзарядка выключена.
Из таблицы видно, что десятки и единицы данных идут отдельно, именно из этих бит нужно вытаскивать данные или записывать при установке времени. Таким образом, посылая нужные команды установки данных или чтения данных мы можем отслеживать время или устанавливать время. Времена передачи и чтения данных определяю в МК.
Написал три функции для работы с часами. Вернее две - запись данных и чтение данных, а третья просто переключает вход CE в нуль. Для чего это сделано? Так как после передачи команды от МК к часам может идти запись данных (а за запись и команды и данных у меня отвечает одна функция) и только после данных должен появиться "0" на CE, за это и отвечает треться функция, которая устанавливает на CE "0" после записи в часы данных.
Ниже приведена реализация функций для записи и чтения данных с поясняющими комментариями, которые, думаю, прольют свет на то что творится в этих функциях.
//определяем куда подключены часы - биты и порт
#define E 1
#define SCLK 2
#define IO 3
#define DDR_RTC DDRB
#define PORT_RTC PORTB
#define PIN_RTC PINB
#define F_CPU 4000000//задаем частоту для формирования задержки
//посылаем команду или байт данных в часы
void write(unsigned char cmd)
{
DDR_RTC |= (1<<E) | (1<<SCLK)|(1<<IO);//устанавливаем на выход
PORT_RTC |= (1<<E);//СE=1
_delay_us(4);
for(unsigned char i=0; i<8; i++)//передаем биты
{
if((cmd&(1<<i)) == 1<<i)
{
PORT_RTC |= (1<<IO);
}
else
{
PORT_RTC &= ~(1<<IO);
}
PORT_RTC |= (1<<SCLK);//устанавливаем синхроимпульс и по фронту бит записывается в часы
_delay_us(1);
PORT_RTC &= ~(1<<IO);//сбрасываем IO и SCLK
PORT_RTC &= ~(1<<SCLK);
}
//вызываем после записи байта данных в часы
void end_write_data()
{
PORT_RTC &= ~(1<<E);//на CE устанавливаем "0"
}
//чтение данных
unsigned char read()
{
unsigned char readbyte=0;//сюда будем читать 
DDR_RTC &= ~(1<<IO);//устанавливаем на вход
        //читаем побитно, если "1" записываем "1" в соответствующий бит, также с "0"
for(unsigned char i=0;i<8;i++)
{
PORT_RTC |= 1<<SCLK;
if((PIN_RTC & (1<<IO))==0)
readbyte &= ~(1<<i);
}
else
{
readbyte |= 1<<i;
}
_delay_us(10);//а это и есть большая задержка, чем при передаче
PORT_RTC &= ~(1<<SCLK);
_delay_us(2);
}
PORT_RTC &= ~(1<<E);
_delay_us(4);
return readbyte;
}
Можно в конце статьи скачать проект в WinAVR, подключить эти часы в Proteus`e и посмотреть (ЖКИ - Подключение библиотеки символьного ЖКИ в WinAVR) как они будут работать и как релизовано то, что описано выше. Так как проект приведен в качестве примера, то в нем вначале программы устанавливается вполне определенное время (10:57:00) и дальше часы тикают от этого времени. Захотел себе сделать такие часики отдельным блоком, чтобы можно было подключать к МК когда нужно, быстренько развел плату и испробовал в деле. Поэтому в архиве в конце статьи также можно найти плату в Sprint-Layout. А в собранном виде она выглядит так:


Комментариев: 16 RSS

1 NikB Сайт 05-04-2011 01:18

Очен хорошо smile. И цена хорошая.

Но я не сумел подключит в Протеус (время на LCD 135:135:...).

Вот URL мою попитку: www.nikbsoft.com/!_Tests/ExampleRTC.rar

2 Dmitry 05-04-2011 03:06

посмотрел.

в примере работа с менюsmile

честно говоря не нашел подключенного RTC

может не тот пример прислал?

4 Dmitry 08-05-2011 02:22

а где проверяете? уже в железе или в протеусе?

5 Комментатор 14 08-05-2011 10:34

в протеусе добавил в свой проект ваши исходники данные успешно записываются я вижу это в состоянии DS1302, т.е запись происходит ,но чтение не работает.

8 Dmitry 08-05-2011 14:48

добавил в конце статьи архив с протеусом и проектом в winavr. вообще заметил такую штуку. когда писал проект подключил к ножкам ds1302 осциллограф в протеусе, чтобы смотреть, что на ножках и так он и работал. а потом прошил в железо и тоже хорошо работало. а вот после вашего сообщения полез в проект и отключил осциллограф от ножек и после этого перестал читать))) в общем в протеусе какой то глюк есть, но в железе все хорошо работает.

11 Аноним 26-05-2011 20:15

Здравствуйте, а есть ли возможность посмотреть полный код в кодвижене?

12 Dmitry 26-05-2011 21:28

я не писал код для CodeVision. в общем-то код не сильно будет отличаться для CV AVR. заменить некоторые функции WinAVR на аналогичные в CV и должно все работать))

15 Андрей 29-02-2012 03:24

Здравствуйте Дмитрий!По моему Вы напутали что то в коде. Во первых, в Proteus проект моделируется не корректно - всё время бегает по экрану курсор. Во вторых, в начале программы устанавливается не 10.57, а 11.30 . Да и установка происходит не корректно. Команда, устанавливающая wp в 0 почему то идёт не первой, а третьей. Начальная инициализация часов тоже не верна. Ведь в регистрах данные должны быть в упакованном BCD коде, значит 11 нужно передавать по 1 на каждые 4 импульса SCLK, а у Вас на первые 4 импульса приходится число 1011(11дес.), а на вторые 4 импульса - 0000. Подключите в Proteus_е digital analysis граф и Вы сами всё увидите.

16 Сергей Михайлович 20-04-2012 15:34

Написал вопрос, а он не отображается почему то :-(

Но ладно повторю на всякий случай:

Вопрос в следующем: Не задействованные ножки порта Б у МК можно использовать ведь в своих, совершенно других целях нежели в общении с ртц модулем?

И ещё обьясните мне как простому смертному и всем подобным: про формирование синхроимпульсов в коде, что к чему и почему?.

Заранее спасибо!

grin

Оставьте комментарий!

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)