AVR Урок 17. Часы реального времени DS1307. Часть 1



 

Урок 17

Часть 1

 

Часы реального времени DS1307

 

Продолжаем занятия по программированию МК AVR.

И сегодня мы познакомимся с очень хорошей микросхемой DS1307. Данная микросхема представляет собой часы реального времени (real time clock или RTC).

Также, благодаря тому, что общение микроконтроллера с данной микросхемой будет происходить с применением интерфейса I2C, мы ещё лишний раз на деле закрепим тему программирования данной шины.

Данная микросхема представлена компанией Dallas, вот её распиновка и основные технические характеристики

 

image00

Здесь мы видим, что есть у нас ножки SDA и SCL, назначение которых мы очень прекрасно знаем из предыдущего занятия. Также есть ножки X1 и X2 для подключения кварцевого резонатора на 32768 Гц, ножки питания — VCC и GND, выход для импульсов продолжительностью 1 секунда либо другой частоты в зависимости от настроек определенных регистров, а также плюсовой контак для батарейки, которая подключается для поддержания хода часов в момент отключения основного питания. Отрицательный контакт данной батарейки мы подключаем к общему проводу питания.

Также мы видим, что данная микросхема исполняется в планарных и DIP-корпусах.

Питаться данная микросхема может как и от 3 вольт, так и от 5 вольт.

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

Так как данная микросхема у меня установлена в том же модуле, в котором установлена и микросхема EEPROM, а шина обмена у нас одна, то «узнавать» микросхема DS1307 о том, что обращаются именно к ней, будет, конечно, по адресу, который у неё другой, нежели у микросхемы EEPROM.

 

 

Вот диаграммы приёма и передачи данных микросхемы

 

image02

image03

 

Адрес, по которому мы будем обращаться к данной микросхеме, выделен синим.

В принципе. особой разницы с диаграммами микросхемы EEPROM мы на видим.

Ещё отличие в обращении будет в том, что адресация памяти будет уже однобайтная, так как ячеек памяти или регистров у данной микросхемы очень мало.

Вот что из себя представляют данные регистры

 

image01

 

Назначение данных регистров:

00h — секунды. Секунды хранятся в двоично-десятичном виде. То есть в младших 4 битах хранятся единицы секунд, а в более старших трёх — десятки. Также есть бит SH — это бит запуска микросхемы.

01h — минуты. Хранятся аналогично.

02h — более универсальный регистр. Здесь хранятся часы. В четырех младших битах — единицы чаов, в следующих более старших двух — десятки, в следующем 6 бите — флаг того, после полудня сейчас время или до полудня, в 7 бите — режим хранения — 12- часовой или 24-часовой.

03h — день недели. Хранится в младших 3 битах, остальные биты не используются.

04h — здесь хранится день месяца, также в двоично-десятичном формате. В четыреё малдших битах — единицы, в двух следующих постарше — десятки, остальные биты не используются.

05h — номер месяца в году — хранится в двоично-десятичном формате точно также, как и часы.

06h — номер года, причём не полный четырёхзначный, а только двузначный. В младших четырех битах — единицы, в старших — десятки.

Вот этими семью регистрами мы и будем пользоваться. Последний регистр предназначен для конфигурирования частоты импульсов на импульсном выходе микросхемы, это делается в младших двух битах регистра. по умолчанию он будет 1 гц частотой, нам этого достаточно, чтобы помигать двоеточием, поэтому мы не будем пользоваться данными битами. Биты SOWE и OUT также применяются для настройки и включения формирователя даннх квадратных импульсов.

 

 

Проект для работы с данной микросхемой был создан обычным образом с именем MyClock1307, файлы, связанные с EEPROM оттуда убраны, а добавлены файлы RTC.c и RTC.h.

Содержание файла main.h у нас теперь вот такое

 

#ifndef MAIN_H_

#define MAIN_H_

#define F_CPU 8000000UL

#include <avr/io.h>

#include <avr/interrupt.h>

#include <util/delay.h>

#include <stdio.h>

#include <stdlib.h>

#include «usart.h»

#include «twi.h»

#include «RTC.h»

#endif /* MAIN_H_ */

 

В главном файле MyClock1307.c создадим глобальные переменные для хранения показаний времени, даты и дня недели и после этого полное содержание после удаления всего лишнего в нём будет вот таким

 

#include «main.h»

unsigned char sec,min,hour,day,date,month,year;

int main(void)

{

  I2C_Init();

  USART_Init (8);

  while(1)

  {

  }

}

 

От прошлого кода останется лишь инициализация I2C и USART.

Теперь нам надо как-то вообще запустить микросхему. Если микросхема новая, либо никогда не использовалась, либо кто-то специально для каких-то целей изменил значение бита CH, то она ещё не «ходит».

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

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

Поэтому, собственно, используя наши знания предыдущего занятия, напишем писать функцию установки времени.

Первым делом мы, само собой, передадим условие СТАРТ

 

//Устанавливаем время

I2C_StartCondition();

 

Затем передаём адрес с битом записи 0

 

I2C_StartCondition();

I2C_SendByte(0b11010000);

 

Перейдём на адрес 0, а значит к той части памяти, где расположен самый первый регистр

 

I2C_SendByte(0b11010000);

I2C_SendByte(0);//Переходим на 0x00

 

Прежде чем писать какие-то значения в регистры микросхемы, мы вспомним, что числа мы сначала должны преобразовать в двоично-десятичный формат, который будет удобен для регистров. Для этого мы зайдём в файл RTC.c и такую функцию и напишем. Она будет очень лёгкой и в объяснении не нуждается

 

unsigned char RTC_ConvertFromBinDec(unsigned char c)

{

  unsigned char ch = ((c/10)<<4)|(c%10);

  return ch;

}

 

Ну и также давайте напишем и функцию обратного типа, переводящую число из двоично-десятичного формата в десятичный. С помощью неё мы, наоборот, будем считанные показания времени преобразовывать в вид, удобный нашему восприятию (ЧПИ — человеко-понятный интерфейс)

 

unsigned char RTC_ConvertFromDec(unsigned char c)

{

  unsigned char ch = ((c>>4)*10+(0b00001111&c));

  return ch;

}

 

Здесь также всё придельно ясно, мы сдвигаем вправо старшую тетраду байта, умножаем её на десять и прибавляем младшую тетраду (старшую отмаскировываем нулями)

Напишем прототипы данных функций в файле RTC.c

 

#include «main.h»

unsigned char RTC_ConvertFromDec(unsigned char c); //перевод двоично-десятичного числа в десятичное

unsigned char RTC_ConvertFromBinDec(unsigned char c); //перевод десятичного числа в двоично-десятичное

 

Соберём код, а прошивать контроллер пока не будем. Нам нужно ещё дописать код записи в регистры и написать в бесконечный цикл процедуру чтения времени и даты и отправку всего этого в USART, а затем уж прошьём полностью весь код, прописав правильные значения времени и даты в установку времени.

Сделаем мы всё это в следующей части занятия.

 

 

Предыдущий урок Программирование МК AVR Следующая часть

 

Документация на микросхему DS1307

 

Программатор, модуль RTC DS1307 с микросхемой памяти и переходник USB-TTL можно приобрести здесь:

Программатор USBASP USBISP с адаптером USBASP USBISP 3.3 с адаптером

Модуль RTC DS1307 с микросхемой памяти

Переходник USB-TTL лучше купить такой (сейчас у меня именно такой и он мне больше нравится)

 

 

Смотреть ВИДЕОУРОК (нажмите на картинку)

 

AVR Часы реального времени DS1307

6 комментариев на “AVR Урок 17. Часы реального времени DS1307. Часть 1
  1. Melamed:

    Проанализировав ваши функции RTC_ConvertFromBinDec  и RTC_ConvertFromDec, пришeл к выводу, что время и дата в микросхеме DS1307 хранятся в следующим формате: в младших четырех битах хранится десятичные единицы, а старших 4 битах  — десятичные десятки. Поэтому достаточно для выделения десятичных единиц выполнить операцию побитного и с числом 0x0F, а десятков с помошью побитного сдвига на 4 бита

    ed = min & 0x0f;

    dec = min>>4;

    И у меня это работает

  2. Игорь:

    Для тех, кому не понятен алгоритм преобразования BCD (как я)

    Разберем дополнительные операции для второго варианта на примере. Например необходимо записать десятичное число 37, в BCD формате оно будет иметь вид 11 0111. Например калькулятор истолкует бинарный код, как десятичное 55. Или десятичное 37 как 10 0101. Поэтому необходимо провести следующие операции.:

    — 37 делим на 10, в итоге получаем целое число 3, все дробное откидываем, получаем в бинарном виде 0000 0011;
    — сдвигаем младшую часть полубайта, содержащей 3 на 4 бита влево , уже имеем вид 0011 0000;
    — теперь применяем деление по модулю 10 (%10), т.е. число 37%10. В результате получаем 7, в буфере имеем бинарный код 0000 0111;
    — и последние — производим сложение 0011 0000+ 0000 0111 = 11 0111;

  3. Алексей:

    А можете пояснить как идёт перевод из двоичной в десчтичной, на бумаге пробую, не сходится. Заранее спасибо.

  4. Владимир:

    Добрый день. У Вас в описании регистра по адресу 02h флаг до/после полудня не в 6-м, а в 5-м бите. И 12/24 часа не в 7-м, а в 6-м бите.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*