Главная » Микроконтроллеры
Призовой фонд
на июль 2017 г.
1. Осциллограф DSO138
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 200 руб.
От пользователей

Библиотека 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 Поиск в FivelВ блокнот
Часы реального времени (RTC)
PCF8583
1 Поиск в FivelВ блокнот
LCD-дисплейWH16021 Поиск в FivelВ блокнот
Резистор
4.7 кОм
2 Поиск в FivelВ блокнот
Кварц32768 Гц1 Поиск в FivelВ блокнот
Добавить все

Скачать список элементов (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
Автомобильный GPS-трекер с GSM/GPRS и дистанционным управлением Сатфайндер
вверх