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

Наш модуль часов реального времени общается с микроконтроллером по 2-направленной синхронной шине передачи данных (SPI) с выбором устройства для обмена (вывод «CS»). Для того, чтобы выбрать устройство, с которым в данный момент должен произойти обмен дынными, — на выходе «CS» нужно установить логическую «1», после окончания передачи — сбросить в «0». ds1394 может общаться с микроконтроллером, использую 2 режима работы SPI — SPI mode 3 и SPI mode 0, соответственно необходимо настроить наш msp430g2553
соответственно этим режимам. (варианты работы шины SPI микроконтроллера приведены в документации на контроллер)

Графики, иллюстрирующие обмен данными микроконтроллера с часами из даташита:

чтение данных из часов реального времени

отправка данных часам
Схема подключения часов к микроконтроллеру:

Din -> P1.7/UCB0SIMO — «Master Output, Slave Input»;

Dout -> P1.6/UCB0SOMI — «Master Input, Slave Output»;

Clk   -> P1.5/UCB0SCL — Сигнал тактирования;

SQW/INT -> P1.3 — выход прерывания, пока его не будем использовать, но его необходимо «подтянуть» к питанию через резистор около 4,7 кОм (можно использовать внутренние резисторы подтяжки msp430g2553, включив их соответствующим регистром). На плате у меня разведено место под резистор и светодиод для этого выхода;

CS -> P1.0 — «Chip Select».

Инициализация обмена данными с часами при использовании встроенного SPI в msp430g2553 не представляет особой сложности. Согласно документации на ds1394 и msp430g2553, получаем вот такие параметры инициализации (используя второй USCI):

void spi_init() {
/* Configure ports on MSP430 device for USCI_B */
P1SEL |= BIT5 | BIT6 | BIT7;
P1SEL2 |= BIT5 | BIT6 | BIT7;
/* USCI-B specific SPI setup */
UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCCKPH | UCMSB | UCMST | UCMODE_0 | UCSYNC;  // SPI mode 0, master
UCB0BR0 = 0x02;
UCB0BR1 = 0x00;
UCB0CTL1 = UCSSEL_2;  // Clock = SMCLK, clear UCSWRST and enables USCI_B module.
}

Для обмена по шине SPI, будут использоваться функции:
unsigned char spi_send(unsigned char data)

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

unsigned char binTobcd (unsigned char binValue)
unsigned char bcdTobin (unsigned char bcdValue)

В часах реального времени DS1394 имеются кроме регистров даты, времени и будильника, дополнительные регистры управления и статуса работы часов:

регистр управления,

где:

EOSC — «Enable Oscillator» — запуск внутреннего тактового генератора (инверсный, то есть разрешается его работа при установке в лог.0);

BBSQI — «Battery-Backed Square-Wave and Interrupt Enable» — разрешение прерываний и выхода сигнала меандра с делителя частоты на вывод SQW/INT при отсутствии основного питающего напряжения;

RS2 и RS1 — «Rate Select» — выбор делителя частоты, устанавливает значение частоты на выходе SQW/INT согласно таблице:

INTCN — «Interrupt Control» — разрешение выхода прерывания на SQW/INT вывод часов, при установке в «0» — используется выход тактового генератора с делителя, при установке в «1» — как индикация срабатывания будильника;

AIE — «Alarm Interrupt Enable» — при установке в «1»  — разрешение прерывания при срабатывании будильника (INTCN = 1), при установке флага AIE или флага INTCN  в «0», срабатывание будильника не приводит к включению сигнала на выходе SQW/INT. При включении питания этот флаг всегда сброшен в «0».

регистр статуса, где

OSF — «Oscillator Stop Flag» — лог.»1″ в этом регистре означает, что тактовый генератор остановлен, или был остановлен по одной из следующих причин:

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

Значение этого регистра может быть принудительно сброшено программно.

AF — «Alarm Flag» — лог.»1″ в этом регистре означает срабатывания будильника по совпадению регистров будильника и текущего времени, так же может быть сброшено программно.

Следующий регистр, значения которого могут быть установлены — регистр настройки зарядного устройства для резервного источника часов:

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

Адреса и значения регистров часов согласно документации обозначены в файле ds1394.h:


/* Address registers define */
#define DS1394_REG_100THS               0x00    // Hundredths of Seconds register /0-99 BCD
#define DS1394_REG_SECONDS              0x01    // Seconds register                /00-59 BCD
#define DS1394_REG_MINUTES              0x02    // Minutes register                /00-59 BCD
#define DS1394_REG_HOURS                0x03    // Hours register                /00-23 BCD
#define DS1394_REG_DAY                  0x04    // Day of week register            /1-7 BCD
#define DS1394_REG_DATE                 0x05    // Date register                /01-31 BCD
#define DS1394_REG_MONTH_CENT           0x06    // Month register                 /01-12 BCD + Century bit (bit7)
#define DS1394_REG_YEAR                 0x07    // Year register                 /00-99 BCD

/* Alarm address registers  */
#define DS1394_REG_ALARM_BIT            0x10    // Alarm match bit, can be added to day, hours, minutes and seconds register, see ds,  Table 4
#define DS1394_REG_ALARM_100THS         0x08    // Hundredths of Seconds alarm register    /0-99 BCD
#define DS1394_REG_ALARM_SECONDS        0x09    // Seconds alarm register                /00-59 BCD
#define DS1394_REG_ALARM_MINUTES        0x0A    // Minutes alarm register                /00-59 BCD
#define DS1394_REG_ALARM_HOURS          0x0B    // Hours alarm register                /00-23 BCD
#define DS1394_REG_ALARM_DAY_DATE       0x0C    // Day alarm register                /01-31 BCD

/* Control registers address define */
#define DS1394_REG_CONTROL              0x0D    // control register (specific for the different models of ds13.., see datasheet)
#define DS1394_REG_STATUS               0x0E    // status register can be written to «0» to reset the flags
#define DS1394_REG_TRICKLE              0x0F    // Trickle charge register, see datasheet? Table 5

/* Control register map */                      // specific for DS1394, see datasheet for other
#define DS1394_CONTROL_REG_CLEAN        0x00    // control register cleaning, oscillator run
#define DS1394_STOP_OSC                 BIT7    // stop oscillator, can be stopped on battery powered
#define DS1394_BBSQI                     BIT5    // Battery-Backed Square-Wave and Interrupt Enable
#define DS1394_RATE_1HZ                 0x00    // Rate Select frequency of the square-wave output
#define DS1394_RATE_4KHZ                 0x08    // when the square wave has been enabled
#define DS1394_RATE_8KHZ                 0x10    //
#define DS1394_RATE_32KHZ                 0x18    //
#define DS1394_INTERRUPT                 BIT2    // Interrupt Control, activates the SQW/INT provided the alarm is also enabled
#define DS1394_ALARM_ENABLE             BIT0    // Alarm Interrupt Enable. permits the alarm flag (AF) bit in the status register to assert SQW/INT

/* Status register map */
#define DS1394_STATUS_REG_CLEAN            0x00    // Status register cleaning, clean all flags
#define DS1394_OSCILLATOR_STOP_FLAG     BIT7    // Oscillator Stop Flag
#define DS1394_ALARM_FLAG                 BIT0    // Alarm Flag

/* Trickle charger register map */
#define DISABLE_TCS                     0x00    // Disable trickle charger
#define ENABLE_TCS                         0xA0    // Enable trickle charger
#define ENABLE_DIODE                     0x08    // Diode switch on
#define RES_250_OHM                     0x01    // resistors are used to select
#define RES_2K_OHM                         0x02    // the appropriate face value or its combination.
#define RES_4K_OHM                         0x03    //

В итоге библиотека для работы с часами реального времени ds1394 содержит следующие функции:

ds1394_init — начальная настройка ds1394
ds1394_get_reg(address) — получение значения соответствующего регистра часов;
ds1394_set_reg(address, data) — установка значения соответствующего регистра;
ds1394_set_date(day, day_date, month, year) — установка текущей даты (день недели, день, месяц и год);
ds1394_set_time(hours, minutes, seconds) — установка времени ЧРВ (часы, минуты, секунды);
ds1394_set_alarm(day, hours, minutes, seconds) — установка времени срабатывания будильника (день, часы, минуты, секунды);
ds1394_status_reg_check — проверка статуса часов: 0 — нет событий, 1 — срабатывание будильника, 2 — ошибка тактового генератора;

В архиве пример работы микроконтроллера с часами, — периодическое считывание значений даты, времени и проверка статусного регистра с отправкой данных в ком-порт. В результате работы программы должен получиться примерно такой протокол:

DS1394 init...
Set date 16/04/2013
Set time 00:53:00
Done
Tuesday 16/04/2013 00:53:00
Tuesday 16/04/2013 00:53:01
Tuesday 16/04/2013 00:53:02
Tuesday 16/04/2013 00:53:03
Tuesday 16/04/2013 00:53:04
...
Alarm! Tuesday 16/04/2013 00:54:00
Tuesday 16/04/2013 00:54:001

При описанных вверху настройках регистров в момент срабатывания будильника должен мигнуть светодиод на выходе «SQW/INT»

файлы проекта часов на ds1394 — выполнены в CCS 5.3.0

Актуальная версия библиотеки ds1394 для msp430 на sourceforge