Реклама ⓘ
Главная » Микроконтроллеры
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Часы на PCF8523 и AVR-микроконтроллере

Приветствую всех. Сегодня предлагаю рассмотреть часы на микросхеме PCF8523. Когда-то их можно было получить бесплатным сэмплом от компании NXP. При первом рассмотрении уже видно, что эта микросхема часов реального времени достаточно навороченная. Но это не делает работу с ней сложной. Разработчики наделили ее хорошим функционалом и возможностями.

Итак, RTC PCF8523 - это часы реального времени и календарь, оптимизированные для низкого потребления мощности. Данные передаются по средствам I2C интерфейса с максимальной скоростью 1000 кбит / с. Имеются функции будильника и таймера, которые могут генерировать сигналы на выходах микросхемы. Также имеется цепь резервного питания, отслеживаются сбои в основном питании и при этом происходит переключение на питании от батарейки (батарейку можно заменить на ионистор, если кому-то так удобнее, благодаря низкому потреблению тока, время работы от ионисторного источника в зависимости от емкости, может достигать несколько недель, неплохо).

Характеристики:

  • для работы необходим внешний кварцевый резонатор на 32768 Гц
  • напряжение питания от 1 до 5,5 вольт
  • разрешение времени от секунд до лет
  • потребление тока 150 нА
  • максимальная частота работы I2C - 1 МГц
  • возможность подстройки частоты кварца выбором конденсаторов 7 или 12,5 пФ (внутри микросхемы)
  • функция power-on reset
  • программная подстройка частоты кварца
  • часы содержат 20 регистров

 Указатель на регистр при обращении (чтение или запись) автоматически смещается на единицу вниз. Как и во многих других микросхемах эта функция нормально так упрощает чтение и запись. 20 регистров включают в себя:

  • регистры настроек
  • регистры времени и даты
  • регистры будильника
  • регистр подстройки частоты кварца (подстройка хода часов)
  • регистры таймера

Все подробности по содержанию каждого регистра можно посмотреть в даташите. 

В целом микросхема RTC PCF8523 является весьма и весьма хорошей, как по функционалу, так и по исполнению и качеству. В сравнении с народной DS1307 единственным минусом может быть только цена, и то не всегда. Размер относительно одинаков, если не мелочиться, функционал в разы и разы больше.

Одним из главных вопросов является то, как же общаться с микросхемой по I2C интерфейсу. Именно по этой микросхеме PCF8523 есть одни большие грабли, точнее косяк разработчиков или инженеров - неправильная информация в даташите по этому вопросу. Спустя 2 года после выхода микросхемы на рынок, они, правда, это исправили, но если у кого-то скачан и хранится старый даташит, то лучше его перекачать. А именно, информация содержала неправильные адреса (ленивые инженеры не глядя скопировали их с микросхемы RTC PCF2129). Главное, что все же исправили.

Вот так, в соответствии с рисунком идет правильное общение (чтение или запись) с микросхемой по I2C интерфейсу:

Для записи нужно передать адрес микросхемы (с битом записи), адрес регистра, чтобы установить указатель куда нам нужно, и передать один или несколько байт информации. Чтение же чуть сложнее происходит. Нужно повторить шаги для записи - передать адрес микросхемы (с битом записи), далее адрес регистра, чтобы установить указатель, сформировать стоп и потом сразу старт и передать адрес микросхемы (с битом чтения) и только тогда считать один или несколько байт данных из микросхемы.

Теперь, зная все про микросхему PCF8523, можно сделать часы на ее основе. Конструкция будет на основе микроконтроллера Atmega8.

Схема:

Схема часов на PCF8523

Помимо микроконтроллера Atmega8, конструкция содержит ЖК дисплей, можно использовать любой на основе контроллера HD44780 16 символов, 2 строки, линейный стабилизатор напряжения LM7805  на 5 вольт, можно заменить любым другим с аналогичными характеристиками, непосредственно сама микросхема часов реального времени PCF8523 со всей необходимой обвязкой, кнопки управления можно заменить любыми другими помимо тактовых. Также конструкция содержит реализацию будильника на основе функций PCF8523, при срабатывании будильника на ЖК дисплее загорится соответствующий символ, а также на ножке PB0 микроконтроллера будет сформирован сигнал высокого логического уровня. По схеме к этой ножке подключен светодиод для индикации, его можно заменить на любое другое устройство для сигнализации будильника - например, внешнее звуковое устройство. Тактирование микроконтроллера происходит от внутреннего RC генератора частотой 8 МГц. Дополнительные выводы микросхемы RTC присутствуют на схеме и печатной плате для модуля часов, но функционально не задействованы.

Программная реализация функционирования часов на основе микросхемы часов реального времени PCF8523 на gcc (программный код на С для работы с часами):

// функции работы с микросхемой PCF8523

void pcf8523_init(void){

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x00);         // передача адреса памяти (Control)
    i2c_send_byte(0b00000010);   // запись значения Control_1 (по дефолту 00000000) тут общие натройки
    i2c_send_byte(0b00000000);   // запись значения Control_2 (по дефолту 00000000) тут по таймерам, будильнику
   
    i2c_send_byte(0b00000000);   // запись значения Control_3 (по дефолту 111-0000) тут по батарейке, значения по даташиту стр. 8-10
	                             // контроль батреки включен (нули в 5-7 байтах), прерывания не используются
    i2c_stop_cond();             // остановка i2c
	

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x0E);         // передача адреса памяти (Offset - коррекция времени)
    i2c_send_byte(0b00001000);   // 0x0E даташит стр.27 (по дефолту 00000000 (без коррекции)) 
    i2c_send_byte(0b00110000);   // 0x0F CLKOUT_ctrl (сдесь включаются таймеры, а также выход CLKOUT (частота))
	i2c_stop_cond();             // остановка i2c
		
}


void pcf8523_reset(void) {
// софт ресет до заводских параметров 

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x00);         // передача адреса памяти (Control)
    i2c_send_byte(0b01011000);   // запись значения сброса параметров в регистр Control_1
    i2c_stop_cond();             // остановка i2c
}


void pcf8523_set_time(unsigned char hour1,unsigned char min1, unsigned char sec1){

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x03);	     // передача адреса памяти - регистры времени 3-5
    i2c_send_byte(bin(sec1));    // 0x03 секунды 
	i2c_send_byte(bin(min1));    // 0x04 минуты
    i2c_send_byte(bin(hour1));   // 0x05 часы
    i2c_stop_cond();             // остановка i2c

}


                                 // в некоторых даташитах адреса написаны неправильно, так что внимательно (за 11 год было с косяками, за 13й год все нормально)
void pcf8523_get_time(void){

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи (для чтения) - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x03);	     // передача адреса памяти - регистры времени 3-5
    i2c_stop_cond();             // остановка i2c


	i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010001);   // передача адреса устройства, режим чтения - 0b11010001 (1101000 - slave адрес + 1 бит чтения)
    sec = bcd(i2c_get_byte(0));  // чтение секунд, ACK
	min = bcd(i2c_get_byte(0));  // чтение минут, ACK
	hour = bcd(i2c_get_byte(1)); // чтение часов, NACK
    i2c_stop_cond();             // остановка i2c
	
}


void pcf8523_set_date(unsigned char day, unsigned char wday, unsigned char month, unsigned char year){
    
	i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x06);	     // передача адреса памяти - регистры даты 6-9
    i2c_send_byte(bin(day));     // 0x06 день месяца
    i2c_send_byte(bin(wday));    // 0x07 день недели (воскресенье - 0, пн 1, вт 2, ср 3, чт 4, пт 5, сб 6)
	i2c_send_byte(bin(month));   // 0x08 месяц
	i2c_send_byte(bin(year));    // 0x09 год
    i2c_stop_cond();             // остановка i2c

}


void pcf8523_get_date(void){

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи (для чтения) - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x06);	     // передача адреса памяти - регистры даты 6-9
    i2c_stop_cond();             // остановка i2c


	i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010001);   // передача адреса устройства, режим чтения - 0b11010001 (1101000 - slave адрес + 1 бит чтения)
    day = bcd(i2c_get_byte(0));  // чтение секунд, ACK
	wday = bcd(i2c_get_byte(0)); // чтение минут, ACK
    month = bcd(i2c_get_byte(0));// чтение минут, ACK
	year = bcd(i2c_get_byte(1)); // чтение часов, NACK
    i2c_stop_cond();             // остановка i2c
	
}


void pcf8523_set_alarm(unsigned char hour, unsigned char min, unsigned char start) {

// чтобы запретить будильник отправляем в минуты и часы единицу в 7й бит: 0x80 или 0b10000000 или 128 через bin

// выставить все нобходимое в Control_1 (bit AIE) и Control_2 (флаг AF) для звонка, даташит стр. 26

    unsigned char r1 = 0, r2 = 0;

	if(start == 1){
		r1 |= (0<<7) | (bin(min)<<0);
		r2 |= (0<<7) | (bin(hour)<<0);
	}
	else{
		r1 |= (1<<7) | (bin(min)<<0);
		r2 |= (1<<7) | (bin(hour)<<0);
	}

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x0A);	     // передача адреса памяти - регистры времени будильника 0A-0B
    i2c_send_byte(r1);           // 0x0A минуты звонка
    i2c_send_byte(r2);           // 0x0B часы звонка
	//i2c_send_byte(0b10000000); // 0x0C часы день (месяца) звонка - нам не надо, мы не пользуем - отключено
	//i2c_send_byte(0b10000000); // 0x0D часы день (недели) звонка - нам не надо, мы не пользуем - отключено
 	i2c_stop_cond();             // остановка i2c

}


void pcf8523_get_alarm_time (void){

    char hh5 = 0, mm5 = 0;

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи (для чтения) - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x0A);	     // передача адреса памяти 
    i2c_stop_cond();             // остановка i2c

	i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010001);   // передача адреса устройства, режим чтения - 0b11010001 (1101000 - slave адрес + 1 бит чтения)
    mm5 = i2c_get_byte(0);       // чтение секунд, ACK
    hh5 = i2c_get_byte(1);       // чтение минут, NACK

    if((hh5 & (1<<7))) alarm_on = 0; else alarm_on = 1;   // 
    alarm_hour = bcd (hh5);
    alarm_min = bcd (mm5);

    i2c_stop_cond();             // остановка i2c

}


unsigned char pcf8523_get_alarm(void) {
// считываем состояние будильника для программного отслеживания звонка

    char alarm = 0, get = 0;

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи (для чтения) - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x01);	     // передача адреса памяти 
    i2c_stop_cond();             // остановка i2c


    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010001);   // передача адреса устройства, режим чтения - 0b11010001 (1101000 - slave адрес + 1 бит чтения)
    alarm = i2c_get_byte(1);     // чтение регистра Control_2, NACK   интересует только 3й байт AF (флаг состояния будильника)
    i2c_stop_cond();             // остановка i2c

	if((alarm & (1<<3))) get = 1; else get = 0; // если в 3 бите 1, значит будильник сработал

	return get;

// для сброса звонка вызываем функцию pcf8523_alarm_reset
// флаг сработки сбрасывается в 0 и ожидается снова время сработки
// включается и выключается будильник в функции pcf8523_set_alarm переменной start 

}


void pcf8523_alarm_reset(void) {
// сбросит флаг срабатывания будильника AF в Control_2 в нолик

    i2c_start_cond();            // запуск i2c
	i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x01);         // передача адреса памяти (Control)
	i2c_send_byte(0<<3);         // сдвигом записать нолик нодо тут (так же правильно??)
	i2c_stop_cond();             // остановка i2c
// 

}


unsigned char pcf8523_low_bat(void) {
// прочитает состояние резервной батареи (возвращаемое значение - bat, 1 - разряжена)

    char low = 0, bat = 0;    

    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010000);   // передача адреса устройства, режим записи (для чтения) - 0b11010000 (1101000 - slave адрес + 0 бит записи)
    i2c_send_byte(0x02);	     // передача адреса памяти - регистры даты 6-9
    i2c_stop_cond();             // остановка i2c


    i2c_start_cond();            // запуск i2c
    i2c_send_byte(0b11010001);   // передача адреса устройства, режим чтения - 0b11010001 (1101000 - slave адрес + 1 бит чтения)
    low = i2c_get_byte(1);       // чтение регистра Control_3, NACK   интересует только 2й байт BLF (флаг состояния резервной батареи)
    i2c_stop_cond();             // остановка i2c

    if((low & (1<<2))) bat = 1; else bat = 0; // если во 2 бите 1, значит разряжена

	return bat;

}

bcd - перевод из двоично десятичного кода
bin - перевод в двоичный код из десятичного
Фактически, это библиотека для работы с часами PCF8523, нужно только оформить в .c и .h файлы.

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

Пример расчета коррекции частоты кварца (не самого кварца напрямую, а компенсация ошибки частоты кварца программно внутри микросхемы часов):

Результат расчета переводится в двоичную систему и записывается в регистр коррекции. Особых пояснению, думаю, не нужно.

Дополнительно частоту кварца можно регулировать внесением в схему подстроечного конденсатора, подключенного к ножке кварца. Также рекомендуют в подобных часах использовать кварцы из материнских плат, потому что они там более качественные. 

Опрос состояния кнопок происходит по прерыванию таймера 0 (прерывания по переполнению таймера). В функции main инициализируем таймер 0, порты микроконтроллера, циклический опрос времени, даты и состояний часов (вызов функций работы с часами) и вывод всего этого добра на ЖК дисплей. Так же для установки времени, даты и параметров будильника небольшая менюшка для управления переменными. Это весь состав часов.

Управление часами:

  • кнопка S2 - сброс микроконтроллера (reset, перезагрузка)
  • кнопка S4 - вход меню настроек и перелистывание уровней (часы будильника - минуты будильника - включенность будильника - и так далее, а при завершении всех уровней переход на отображение времени и даты - главное меню)
  • кнопка S3 - управление переменными (увеличение на единицу переменной, при переполнении приравнивается к 0, например, часы от 0 до 23)
  • кнопка S2 - выход из настроек, если находимся в настройках, или сброс срабатывания будильника в главном меню

Модуль часов на основе PCF8523 (печатная плата прилагается ниже):

На печатной плате расположение перемычки исправлено.

В целом часы собирались и тестировались на макетной плате:

Фьюзы для программирования микроконтроллера:

К статье прилагается печатная плата для модуля часов PCF8523, прошивка, проект протеус (8 версия, в которой как раз присутствует PCF8523 в библиотеке элементов), небольшое видео работы часов, демонстрирующее работоспособность.

Статья носит более обучающий характер или пример, нежели практический.

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

Обозначение Тип Номинал Количество ПримечаниеМагазинМой блокнот
IC1 МК AVR 8-бит
ATmega8
1 Поиск в магазине ОтронВ блокнот
IC2 RTCPCF85231 Поиск в магазине ОтронВ блокнот
VR1 Линейный регулятор
LM7805CT
1 Поиск в магазине ОтронВ блокнот
HG1 LCD-дисплейSC16021 на базе HD44780Поиск в магазине ОтронВ блокнот
Z1 Кварц32768 Гц1 Поиск в магазине ОтронВ блокнот
R1 Подстроечный резистор10 кОм1 3296W-1-103LFПоиск в магазине ОтронВ блокнот
R2,R4,R5,R7-R9 Резистор
10 кОм
6 Поиск в магазине ОтронВ блокнот
R3 Резистор
390 Ом
1 Поиск в магазине ОтронВ блокнот
R6 Резистор
200 Ом
1 Поиск в магазине ОтронВ блокнот
C1,C4 Конденсатор220 мкФ2 Поиск в магазине ОтронВ блокнот
С5 Конденсатор10 мкФ1 Поиск в магазине ОтронВ блокнот
C2,C3,C6 Конденсатор100 нФ3 Поиск в магазине ОтронВ блокнот
S1-S4 Тактовая кнопкаTC-A1094 Поиск в магазине ОтронВ блокнот
LED1 Светодиод1 Поиск в магазине ОтронВ блокнот
Элемент питания3 В1 cr2032Поиск в магазине ОтронВ блокнот
Добавить все

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

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

Теги:

Опубликована: 0 0
Я собрал 0 2
x

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

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

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

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

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется сила тока?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

AVR-программатор USB ASP
AVR-программатор USB ASP
Мультиметр DT9205A Модуль радиореле на 4 канала
вверх