Главная » Микроконтроллеры
Призовой фонд
на октябрь 2017 г.
1. Термометр Relsib WT51
Рэлсиб
2. 1000 руб
PCBWay
3. Регулируемый паяльник 60 Вт
Паяльник
4. 100 руб.
От пользователей

Библиотека AVR для работы с шиной I2C и с часами реального времени PCF8583

Мне нужно было сделать часы на основе микросхемы, имеющей I2C интерфейс. Микросхема RTC, т.н. "часы реального времени" PCF8583.

Внутри микросхемы расположены: часы, будильник, таймер, календарь (кривой), и 240 байт оперативной памяти, куда можно записывать любую информацию, которую только вздумается. Оперативная память это очень полезная штука, в отличии от флеш-памяти, оперативная память не имеет ограничений по количеству циклов перезаписи, и в неё можно сохранять какие-то данные, настройки, сколь угодно часто.

Но была одна проблемка - писАть код жутко не хотелось, и я решил найти готовый код в интернете. Как позже выяснилось, найти «на свою голову». Скачал пример работы с I2C, подправил, прошил микроконтроллер. Не заработало. Стал ковырять код, искать причину неработоспособности… и ужаснулся!! Запись в некоторых случаях велась во весь порт сразу, а не в конкретные биты. Таким образом, если на порт повесить ещё что-то, например, дисплей, то скорее всего, оно работать не будет. Также неправильно было реализовано чтение данных по шине (без генераций условия окончания приёма, или просто без NACK). Но это пол-беды. Основная проблема в другом. Зачастую автор кода выставлял в порт логическую «1», а как мы знаем, шина I2C управляется «притягиванием» выводов SDA и SCL к общему проводу. А логическая «1» на шине, в свою очередь, формируется за счёт подтяжки к плюсу питания резисторами на 4,7 килоом. Таким образом, если на выходе микроконтроллера выставить логическую «1», а ведомое устройство «притянет» этот выход к общему проводу, то получится «ба-бах» короткое замыкание. Мне это очень не понравилось, и я решил изобрести свой велосипед  написать свою библиотеку, а вернее даже 2 библиотеки: одна для работы с шиной I2C, а другая непосредственно для работы с часами реального времени PCF8583. Да, кстати, код написан в AVR Studio 6.

Для того, чтобы подключить библиотеку I2C к проекту, нужно прописать её через include, как на картинке, а также скопировать библиотеку в папку с проектом.

После чего, необходимо открыть файл "i2c.h", и указать ножки микроконтроллера, которые будут выступать в роли шины I2C. По умолчанию шина настроена на ножки PC0 (SCL) и PC1 (SDA). А настройка делается вот тут:

Всё, библиотеку I2C мы подключили, ножки настроили, библиотека готова к работе. Пример использования:

i2c_init ();    // Инициализация шины I2C

i2c_start_cond();   // старт шины

i2c_send_byte (0xA0);   // адрес устройства, которое висит на шине

i2c_send_byte (0x10);   // байт данных, который записываем в устройство

i2c_send_byte (0x10);   // ещё один байт данных, который записываем в устройство

i2c_stop_cond();   // стоп шины

После стоп-условия, мы можем проверить, всё ли у нас в порядке с шиной I2C. Для этого нужно прочитать переменную «i2c_frame_error». Если всё нормально, то в ней будет 0. Если один из выводов шины не «подтянулся» к питанию, и логическая «1» не установилась на шине, то библиотека генерирует ошибку, и записвает в переменную «i2c_frame_error» циферку 1. Читать переменную «i2c_frame_error» нужно после стоп-условия. На рисунке ниже продемонстрирую как работает контроль ошибки:

Теперь займёмся подключением библиотеки часов реального времени PCF8583. Для этого нужно проделать те же самые действия. Скопируем в папку с проектом файл "PCF8583.h", и пропишем его в include, как на фото:

Готово. Библиотека часов реального времени PCF8583 подключена. Она не требует каких-либо настроек, поэтому можно сразу приступать к чтению времени и даты с микросхемы. Обращаю внимание, что библиотека PCF8583 работает при помощи библиотеки I2C, поэтому если хотим работать с PCF8583, то нужно подключить обе библиотеки!

Пример использования библиотеки (запись и чтение времени и даты):

// Инициализация шины I2C

i2c_init ();


// Подготавливаем время и дату для записи в микросхему PCF8583

PCF_hour=23;   // 23 часа

PCF_min=59;   // 59 минут

PCF_day=31;   // 31 число

PCF_month=12;   // 12 месяц - декабрь

PCF_year=0;   // год (0 - не високосный)

PCF_weekday=6;   // 6 день недели (воскресенье)

// Записываем время и дату в микросхему PCF8583

PCF_write_hh_mm_ss();

// Считываем время и дату из микросхемы PCF8583

PCF_read_hh_mm_ss();


Пример работы с оперативной памятью (запись и чтение):

// Подготавливаем 5 байт для записи в микросхему PCF8583

PCF_data_ram_1=255;   // байт 1

PCF_data_ram_2=255;   // байт 2

PCF_data_ram_3=255;   // байт 3

PCF_data_ram_4=255;   // байт 4

PCF_data_ram_5=255;   // байт 5


// Записываем 5 байт в микросхему PCF8583

PCF_write_ram();


// Считываем 5 байт из микросхемы PCF8583

PCF_read_ram();

Чтение из микросхемы ещё проще – достаточно вызвать функцию PCF_read_hh_mm_ss() после чего, время и дата появятся в переменных, откуда их только забирай. Для чтения оперативной памяти соответственно используем функцию PCF_read_ram()  после чего данные забираем в переменных PCF_data_ram_N

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

// время и дата

PCF_hour=0; // время, часы (от 0 до 23, защита от переполнения при записи и чтении)

PCF_min=0;  // время, минуты (от 0 до 59, защита от переполнения при записи и чтении)

PCF_sec=0;  // время, секунды (только для чтения, при записи сбрасываются в 00)

PCF_day=0;  // день (от 1 до 31, защита от переполнения при записи и чтении)

PCF_weekday=0 // день недели (0-понедельник; 6-воскресенье, защита от переполнения при записи и чтении)

PCF_month=0; // месяц (от 1 до 12, защита от переполнения при записи и чтении)

PCF_year=0; // год (0-високосный; 1,2,3-невисокосные, защита от переполнения при записи и чтении)


// оперативная память

PCF_data_ram_1;   // Данные (ОЗУ PCF8583), байт 1

PCF_data_ram_2;   // Данные (ОЗУ PCF8583), байт 2

PCF_data_ram_3;   // Данные (ОЗУ PCF8583), байт 3

PCF_data_ram_4;   // Данные (ОЗУ PCF8583), байт 4

PCF_data_ram_5;   // Данные (ОЗУ PCF8583), байт 5

Теперь расскажу про защиту от переполнения. Допустим, мы забыли подключить микросхему. Прочитаем данные с микросхемы, и… прочитается байт 11111111, или число 255. Всё дело в том, что в основе шины I2C лежат 2 подтягивающих резистора, вот они то и выдают нам логические «единички» если микросхема не подключена. Для защиты от подобных случаев, в библиотеке PCF8583 я сделал защиту от переполнений, которая следит за тем, чтобы часики не показывали вам 62 часа 81 минуту… Наличие переполнения можно проследить, прочитав переменную «PCF_overflow». Если в ней 0, значит ошибок переполнения не было. Если в ней 1 или более, значит ошибки переполнения имеются. Читать переменную «PCF_overflow» нужно после функции чтения даты и времени PCF_read_hh_mm_ss()

Для наглядности, проект AVR Studio 6 под ATmega32 прилагается. Перекомпилировать можно под любой AVR. В проекте я также подключил дисплей для визуального контроля. При подаче питания, микроконтроллер устанавливает 23 часа 59 минут, 31 декабря, Воскресенье. И через минуту становится 00 часов 00 минут, 1 января, Понедельник.

Теперь расскажу, почему я говорил про «кривой» календарь этой микросхемы. Всё дело в том, что микросхема не умеет хранить текущий календарный год, а хранит лишь флаг високосного года. Короче говоря:
0 – високосный год
1 – не високосный год
2 – не високосный год
3 – не високосный год

И так по циклу 0-1-2-3-0-1-2-3-0…

В общем чтобы сделать нормальный календарь, нужно реализовывать программный расчёт и сохранение года, например, в ту же оперативную память PCF8583, но это не удобно. А главное, что при обесточенной схеме память, увы, никто не перезапишет...

Также прилагаю в конце статьи небольшой видеоотчёт. В программировании я можно сказать новичок, хоть и программирую уже 3 года (понемногу), за код строго не судите, если есть какие-либо дополнения и замечания, пишите, будем исправлять. Всем удачных самоделок!

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

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
МК AVR 8-бит
ATmega32
1 Поиск в LCSCВ блокнот
Часы реального времени (RTC)
PCF8583
1 Поиск в LCSCВ блокнот
LCD-дисплейWH16021 Поиск в LCSCВ блокнот
Резистор
4.7 кОм
2 Поиск в LCSCВ блокнот
Кварц32768 Гц1 Поиск в LCSCВ блокнот
Добавить все

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

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

Теги:

Опубликована: Изменена: 13.06.2014 0 1
Я собрал 0 0
x

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

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

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

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

0

[Автор]
Zlodey #
На демонстрационной схеме отсутствует резистор регулировки контраста, думаю не страшно. Так как дисплей подключен всего лишь для наглядности происходящего
Ответить
0
u33 #
Часы и дату для вывода на дисплей можно было привести в формат 0X:0X:0X, когда X меньше 10, а не 0:0:0 .
Ответить
0

[Автор]
Zlodey #
С точки зрения микроконтроллера, нет такого понятия как 00 часов. Есть переменная, которая может быть 0, меньше нуля, или больше нуля. Поэтому тема форматированного вывода- это вопрос другой статьи. Я например, люблю когда выводится 5:06:45 вместо 05:06:45, поэтому это уже дело вкуса разработчика...
Отредактирован 16.11.2013 21:11
Ответить
0
Владимир #
Как всё это исправить на DS1307?
Ответить
0

[Автор]
Zlodey #
Почитать даташиты, внести изменения
Ответить
0
Aнатолий #
SoftI2CMaster.h
где скачать эту библиотеку?
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Конструктор: DDS генератор сигналов Печатная плата для усилителя "LM3886 + AD825"
вверх