cd00004131

AN1216
Application note
Implementing a periodic alarm with TIMEKEEPER®
and serial real-time clocks (RTCs)
Introduction
The TIMEKEEPER® and serial real-time clock (RTC) devices provide an alarm which can
be set either for a given time and day, or to repeat at a certain day in every month, or at a
certain hour in every day, or at a certain minute of every hour, or at a certain second of every
minute. With this functionality already provided in the hardware, the software to implement
an alarm of any given period is greatly simplified, as described in this document.
Table 1. TIMEKEEPER® and serial RTC devices with alarm
TIMEKEEPER
M48T37V/Y, M48T201V/Y
Serial RTC
M41T62, M41T63, M41T64, M41T65, M41T66, M41T80, M41T81, M41T81S,
M41T82, M41T83, M41T93, M41T94, M41ST85W, M41ST87W
Although specifically tailored for the M48T37V/Y device, applications can be easily adapted
to use any of ST’s other TIMEKEEPER or serial RTC devices that have the alarm feature.
Some modifications in the MCU memory mapping (the TIMEKEEPER or RTC address
space) and in the MCU register mapping (such as the pointer to register address) would
need to be made.
September 2013
DocID007016 Rev 2
1/11
www.st.com
AN1216
TIMEKEEPER® configuration
The TIMEKEEPER register mapping is shown in Table 2. This is divided in two parts: the
clock registers and the alarm registers.
Table 2. Typical TIMEKEEPER® (M48T37V/Y) register map
Data
Function
Range
(in BCD format)
Year
Year
00-99
Month
Month
01-12
Date
Date
01-31
Day
01-7
Hours
Hour
00-23
Address
D7
7FFFh
D6
D5
D4
D3
D2
10 Years
0
0
7FFDh
0
0
7FFCh
0
FT
7FFBh
0
0
7FFAh
0
10 Minutes
10 Minutes
Minute
00-59
7FF9h
ST
10 Seconds
Seconds
Second
00-59
7FF8h
W
R
S
7FF7h
WDS
BMB4
BMB3
BMB2
7FF6h
AFE
0
ABE
0
7FF5h
RPT4
0
Al 10 Date
Alarm Date
A Date
01-31
7FF4h
RPT3
0
Al 10 Hour
Alarm Hour
A Hour
00-23
7FF3h
RPT2
Alarm 10 Minutes
Alarm Minutes
A Minute
00-59
7FF2h
RPT1
Alarm 10 Seconds
Alarm Seconds
A Second
00-59
100 Years
Century
00-99
7FF0h
10M
D0
7FFEh
7FF1h
0
D1
10 date
0
0
0
10 hours
Calibration
BMB1 BMB0
0
1000 Years
WDF
AF
Day
Z
BL
Z
0
Z
Control
RB1
RB0
Watchdog
0
0
Interrupt
Z
Z
Flags
Clock registers
The clock registers can be configured in the C language computer program as follows:
*TIMEKEEPER_CAL |= 0x80
*TIMEKEEPER_SEC= 00 //user clock setting : seconds parameter
*TIMEKEEPER_MIN= 00 //user clock setting : minutes parameter
*TIMEKEEPER_HOUR= 00 //user clock setting : hours parameter
*TIMEKEEPER_CAL&= 0x7F
The process for starting the clock and making the calibration adjustments are described in
the M48T37V/Y datasheet, and in application notes AN925 and AN934.
Alarm registers
For TIMEKEEPER devices it is necessary to set the Write bit, W, at the top of the control
register (at address offset 7FF8h) before proceeding to any clock modification. Modifications
2/11
DocID007016 Rev 2
AN1216
to the alarm registers, though, can be made at any time, with no prior changes to the control
register being necessary.
The program listing, at the end of this document, contains statements to perform the
following functions:
1. The Stop bit (ST, bit 7 of the register at offset 7FF9h) has to be reset to start the
TIMEKEEPER oscillator
2.
3.
*TIMEKEEPER_SEC &= 0x7F; // reset bit D7 using a mask 0x7F
The Alarm Flag Enable (AFE) bit (bit 7 of the register at offset 7FF6h) is set, thereby
allowing the IRQ pin (pin 40) to output the interrupt signal (active low).
*TKPER_AL_IT |= 0x80; // set bit D7 using a mask 0x80
The flag register (at offset 7FF0h) must be read at the beginning of the alarm updating
routine. If not, the AF flag will never be released, and the TIMEKEEPER will
continuously output an interrupt to the MCU, and the system will become
unresponsive.
Software configuration
The program is listed in Alarm update management. To understand its operation, it is
important to distinguish between the three pointer variables, pointing to physical addresses
in the hardware:
*TKPER_AL_HOUR, *TKPER_AL_MIN, *TKPER_AL_SEC
and the three integer variables, used as work-space by the software:
alarm_hour, alarm_minute, alarm_second
The first three variables are pointers to the physical address of the values that are stored in
the device.
The three software variables are used to hold the user’s data (they specify the period of the
alarm in hours, minutes and seconds). This is not the same information as is stored in the
TIMEKEEPER registers, as pointed to by the pointer variables, but is used in their
calculation.
The program does make use of the four Repeat bits (RPT4, RPT3, RPT2 and RPT1) that
are physically located in the TIMEKEEPER device. These should all be set, except for those
corresponding to fields that contain significant data. For instance, to set an alarm that
repeats every 3 minutes and 45 seconds, the alarm_minutes and alarm_seconds variables
would be loaded with these two values. Then appropriate values would be calculated for
loading in the “Alarm Minutes” and “Alarm Seconds” fields of the alarm registers (at
addresses 7FF3h and 7FF2h, *TKPER_AL_MIN and *TKPER_AL_SEC, respectively), and
their Repeat bits (RPT2 and RPT1, respectively) would be reset to ‘0’. Meanwhile, the
alarm_hour variable, and the “Alarm Date” and “Alarm Hour” fields of the alarm registers (at
addresses 7FF5h and 7FF4h, *TKPER_AL_DATE and *TKPER_AL_HOUR, respectively)
would be treated as “Don’t Care”, as indicated by their Repeat bits (RPT4 and RPT3,
respectively) being set. This is summarized in Table 3, with the three local integer variables,
alarm_second, alarm_minute and alarm_hour, used to represent the period.
DocID007016 Rev 2
3/11
11
AN1216
Table 3. Bit setting to control the period of the repeated alarm
RPT4 RPT3 RPT2 RPT1
Periodic alarm activated every
1
1
1
1
1 second
1
1
1
0
alarm_second seconds (less than 1 minute)
1
1
0
0
alarm_minute minutes alarm_second seconds (less than 1 hour)
1
0
0
0
alarm_hour hours alarm_minute minutes alarm_second seconds (less than 1 day)
For example, to set a period of 1 hour 49 minutes 35 seconds, the procedure is as follows:
RPT4 = 1
RPT3 = RPT2 = RPT1 = 0
alarm_second = 0x35
alarm_minute = 0x49
alarm_hour = 0x01
Or, to set a period of 49 minutes 35 seconds, the procedure is as follows:
RPT4 = RPT3 = 1
RPT2 = RPT1 = 0
alarm_second = 0x35
alarm_minute = 0x49
alarm_hour = Don’t care
Software implementation
TIMEKEEPER® data format
TIMEKEEPER data is held as BCD (binary coded decimal). This is handled in the C
programming language using the ‘unsigned char’ data type. This can be converted within
the C program to other data types, such as ‘integer’, for numeric processing. Two functions
are provided in the program at the end of this document for making this conversion.

Char_To_Int: to take a BCD parameter, and to return the equivalent integer value

Int_To_Char: to take an integer parameter, and to return the equivalent BCD value.
The valid ranges for the alarm fields are summarized in Table 4.
Table 4. TIMEKEEPER® data format
4/11
Data C language type
Int (integer)
decimal
Char (character)
hexadecimal
Char (character)
BCD
Alarm second
0-59
00-3B
0-59
DocID007016 Rev 2
AN1216
Table 4. TIMEKEEPER® data format
Data C language type
Int (integer)
decimal
Char (character)
hexadecimal
Char (character)
BCD
Alarm minute
0-59
00-3B
0-59
Alarm hour
0-12
00-0B
0-12
Alarm update management
When the alarm signal is generated by the TIMEKEEPER® device, it is communicated to
the MCU. The MCU can monitor for this event either by polling, or by using interrupts. There
are two variants of each method:

Polling
–
Read the flag register and check the AF bit (bit 6 of the register at offset 7FF0h)
–
Output the alarm signal on the TIMEKEEPER® IRQ pin (pin 40), and read it on the
MCU I/O port

Interrupts
–
Give priority to processing the alarm interrupt
–
The alarm signal is used to cause a wake-up event
The last option is ideally suited when power consumption is the critical issue. For instance,
when measuring, processing and storing some metering data every three minutes, the MCU
can stay in its standby state for 95% of the time, and only run at full speed, with high power
consumption, during the other 5% of the time.
The other interrupt option is ideally suited when service time is the critical issue. The MCU
will be interrupted from whatever processing it was currently engaged in, to service the
alarm event. This can be integrated into a hierarchy of prioritized interrupts.
The two polling options are equally suited when the MCU needs to run at full speed, and full
power, all of the time, executing important background work, only responding to the alarm
event when it has nothing else to do.
In polling method, the MCU is always running full speed and full power consumption. In this
case, the application power consumption is not a key issue and/or the process to be
executed due to an alarm which has no priority. The alarm check and update is served as
every other application routine.
The TIMEKEEPER IRQ pin (pin 40) is an active-low signal.
In the following program, a routine “Update_Next_Alarm” is provided to take care of the
periodic update of the alarm parameters. The program has been written in ANSI C, and has
been compiled and tested with an M68HC11 series MCU.
/* TIMEKEEPER ; M48T37V/Y PERIODIC ALARM SOURCE CODE :
/* Version: 1.01
*/
*/
/*********************************************************************************/
/*
Copyright (c) 1999 STMicroelectronics.
*/
/*
*/
/* This program is provided “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
/* EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTY
/* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
*/
*/
*/
DocID007016 Rev 2
5/11
11
AN1216
/* AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
*/
/* PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
*/
/* REPAIR OR CORRECTION.
*/
/*********************************************************************************/
/****************************************************************/
/*
*/
/*
This program controls the TIMEKEEPER alarm hardware so
*/
/*
as to provide the functionality of a periodic alarm.
*/
/*
*/
/****************************************************************/
#include <mcu_hc11.h>
#include <m88xxfx.h>
// this was developed on HC11 platform
// M88 Flash+PSD register map
extern volatile unsigned char dip_sw;
/*********************************************************************/
/* TIMEKEEPER memory map
*/
/* Depend on your system and your TIMEKEEPER.
*/
/* The device is M48T37V/Y series, 32kx8 non volatile SRAM, 16 clock
/* alarm registers in address 7FF8h to 7FFFh
*/
/* In this example, the TIMEKEEPER was mapped from 2000h to 9FFFh
*/
/*********************************************************************/
/*
#ifndef _MEM_MAP_H
#define _MEM_MAP_H
#define
EXT_RAM_BASE (unsigned int)
#define
TIMEKEEPER_HOUR (unsigned char *)
#define
TIMEKEEPER_MIN (unsigned char *)
#define
TIMEKEEPER_SEC (unsigned char *)
#define
TIMEKEEPER_CAL (unsigned char *)
#define
TKPER_AL_IT (unsigned char *)
#define
TKPER_AL_DATE (unsigned char *)
#define
TKPER_AL_HOUR (unsigned char *)
#define
TKPER_AL_MIN (unsigned char *)
#define
TKPER_AL_SEC (unsigned char *)
#define
TKPER_FLAG (unsigned char *)
*/
0x2000
0x9FFB
0x9FFA
0x9FF9
0x9FF8
0x9FF6
0x9FF5
0x9FF4
0x9FF3
0x9FF2
0x9FF0
#endif
*/
/**************************************************************************/
/* function Char_To_Int
*/
/* description :
This function convert the timekeeper data*/
/*
(in BCD format) to an integer.
*/
/* input :
char byte
*/
/* output :
integer
*/
/* example :
octet = 0x33
(51 in integer)
*/
/*
Char_To_Int = 33
(0x21 in hexa)
*/
/**************************************************************************/
int Char_To_Int(unsigned char octet)
{
int buffer;
buffer = (int)(octet);
if (octet <= 0x09) return(buffer);
if ((octet >= 0x10) & (octet <= 0x19)) return (buffer-6);
if ((octet >= 0x20) & (octet <= 0x29)) return (buffer-12);
if ((octet >= 0x30) & (octet <= 0x39)) return (buffer-18);
6/11
DocID007016 Rev 2
AN1216
if ((octet >= 0x40) & (octet <= 0x49)) return (buffer-24);
if ((octet >= 0x50) & (octet <= 0x59)) return (buffer-30);
}
/**************************************************************************/
/* function Int_To_Char
*/
/* description :
This function convert an integer data
*/
/*
to BCD TIMEKEEPER format (unsigned char)
*/
/* input :
int integ
*/
/* output :
unsigned char
*/
/* example :
integ = 33
(0x21 in hexa)
*/
/*
Int_To_Char = 0x33
(51 in integer)
*/
/**************************************************************************/
unsigned char Int_To_Char(int integ)
{
char buffer;
buffer = (unsigned char)(integ);
if (integ <= 9) return(buffer);
if ((integ >= 10) & (integ <= 19)) return (buffer+6);
if ((integ >= 20) & (integ <= 29)) return (buffer+0x0C);
if ((integ >= 30) & (integ <= 39)) return (buffer+0x12);
if ((integ >= 40) & (integ <= 49)) return (buffer+0x18);
if ((integ >= 50) & (integ <= 59)) return (buffer+0x1E);
}
/*************************************************************************/
/* void Update_Next_Alarm
*/
/* description :
After alarm interupt, it will :
*/
/*
- reset the TIMEKEEPER IT flag
*/
/*
- read the actual time in the clock register
*/
/*
- calculate the next alarm time
*/
/*
- update the alarm register
*/
/*
to prepare for the next alarm
*/
/* input :
alarm period (al_hour, al_minute, al_second)
*/
/* output :
nothing
*/
/*************************************************************************/
void Update_Next_Alarm(int al_hour,int al_minute,int al_second)
{
// time carry, going to be used for hour, minute and second
// calculation process.
unsigned char time_flag = 0;
// intermediate storage for alarm data.
int buffsec;
int buffmin;
int buffhour;
// temporary storage
unsigned char buffchar;
// Touch the flag register to reset TIMEKEEPER AF flag (interupt)
buffchar = *TKPER_FLAG;
/*****************************************************************/
/* This is to update the alarm second register.
*/
/* It will test if RPT1 is set. If not then it adds “al_second” */
/* to second alarm register. It takes care of the minute carry. */
/*****************************************************************/
if (!(*TKPER_AL_SEC & 0x80))
// if !RPT1
{
// update register with carry
buffsec = Char_To_Int(*TIMEKEEPER_SEC) + al_second;
if (buffsec > 59)
// if >59
{
// then restore 60sec format
DocID007016 Rev 2
7/11
11
AN1216
*TKPER_AL_SEC = Int_To_Char(buffsec-60);
time_flag = 1;
}
else *TKPER_AL_SEC = Int_To_Char(buffsec);
// normal case
}
/*****************************************************************/
/* This is to update the alarm minute register. */
/* It will test if RPT2 is set. If not then it adds “al_minute” */
/* to alarm minute register. It takes care of the hour carry.
*/
/*****************************************************************/
if (!(*TKPER_AL_MIN & 0x80))
// if !RPT2
{
// update register with carry
buffmin = Char_To_Int(*TIMEKEEPER_MIN) + al_minute + time_flag;
if (buffmin > 59)
// if >59
{
// then restore 60 min format
*TKPER_AL_MIN = Int_To_Char(buffmin-60);
time_flag = 1;
}
else
{
*TKPER_AL_MIN = Int_To_Char(buffmin); // normal case
time_flag = 0;
}
}
/*****************************************************************/
/* This is to update the alarm hour register.
*/
/* It will test if RPT2 is set. If not then it adds “al_hour” to */
/* alarm hour register
*/
/*****************************************************************/
if (!(*TKPER_AL_HOUR & 80))
{
buffhour = Char_To_Int(*TIMEKEEPER_HOUR) + al_hour + time_flag;
if (buffhour > 23) *TKPER_AL_HOUR = Int_To_Char(buffhour-24);
else *TKPER_AL_HOUR = Int_To_Char(buffhour);
}
}
main(void)
{
int alarm_second;
int alarm_minute;
int alarm_hour;
// relative alarm variable
/*****************************************************************/
/* TIMEKEEPER alarm configuration example.
*/
/*****************************************************************/
// Memory-mapped unsigned char pointers
*TKPER_AL_HOUR
&= 0x7F;
// to the external hardware registers
*TKPER_AL_MIN
&= 0x7F;
// to set a one-off alarm
*TKPER_AL_SEC
&= 0x7F;
// for a fixed time today.
// Local memory integer variables
8/11
DocID007016 Rev 2
AN1216
alarm_hour
= 1;
// to hold the repetition period
alarm_minute
= 49;
// for an alarm (& an interrupt on pin 26)
alarm_second
= 35;
// every 1hr 49min 35sec (for example).
// Start the Timekeeper oscillator.
*TIMEKEEPER_SEC
&= 0x7F;
// RPT4 set
*TKPER_AL_DAY
|= 0x80;
// enable IRQ request on pin40 (M48T37V/Y)
*TKPER_AL_IT
|= 0x80;
while (1)
{
/*******************************************************************/
/* read_the_port is a read of MCU I/O to detect an alarm interrupt */
/* lcd_min_display is a lcd software driver used for routine debug */
/* Those library were developed for FLASH+PSD development board.
*/
/*******************************************************************/
read_the_ports();
lcd_min_display(0,3,*TIMEKEEPER_HOUR); // display current time
lcd_min_display(0,7,*TIMEKEEPER_MIN);
lcd_min_display(0,13,*TIMEKEEPER_SEC);
if (dip_sw==0x0E)
// dip_sw is updated by read_the_port
// if detect alarm interrupt from TIMEKEEPER
{
Update_Next_Alarm(alarm_hour,alarm_minute,alarm_second);
lcd_min_display(1,3,*TKPER_AL_HOUR); // display next alarm time
lcd_min_display(1,7,*TKPER_AL_MIN);
lcd_min_display(1,13,*TKPER_AL_SEC);
}
}
}
DocID007016 Rev 2
9/11
11
Revision history
AN1216
Revision history
Table 5. Document revision history
Date
Revision
Feb-2000
1
Initial release.
2
Updated title of document
Removed references to obsolete products
Added Table 1: TIMEKEEPER® and serial RTC devices with alarm
Updated Table 2 and text throughout the document to reflect the memory map and
address of the M48T37V/Y device
03-Sep-2013
10/11
Changes
DocID007016 Rev 2
AN1216
Please Read Carefully:
Information in this document is provided solely in connection with ST products. STMicroelectronics NV and its subsidiaries (“ST”) reserve the
right to make changes, corrections, modifications or improvements, to this document, and the products and services described herein at any
time, without notice.
All ST products are sold pursuant to ST’s terms and conditions of sale.
Purchasers are solely responsible for the choice, selection and use of the ST products and services described herein, and ST assumes no
liability whatsoever relating to the choice, selection or use of the ST products and services described herein.
No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted under this document. If any part of this
document refers to any third party products or services it shall not be deemed a license grant by ST for the use of such third party products
or services, or any intellectual property contained therein or considered as a warranty covering the use in any manner whatsoever of such
third party products or services or any intellectual property contained therein.
UNLESS OTHERWISE SET FORTH IN ST’S TERMS AND CONDITIONS OF SALE ST DISCLAIMS ANY EXPRESS OR IMPLIED
WARRANTY WITH RESPECT TO THE USE AND/OR SALE OF ST PRODUCTS INCLUDING WITHOUT LIMITATION IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE (AND THEIR EQUIVALENTS UNDER THE LAWS
OF ANY JURISDICTION), OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.
ST PRODUCTS ARE NOT AUTHORIZED FOR USE IN WEAPONS. NOR ARE ST PRODUCTS DESIGNED OR AUTHORIZED FOR USE
IN: (A) SAFETY CRITICAL APPLICATIONS SUCH AS LIFE SUPPORTING, ACTIVE IMPLANTED DEVICES OR SYSTEMS WITH
PRODUCT FUNCTIONAL SAFETY REQUIREMENTS; (B) AERONAUTIC APPLICATIONS; (C) AUTOMOTIVE APPLICATIONS OR
ENVIRONMENTS, AND/OR (D) AEROSPACE APPLICATIONS OR ENVIRONMENTS. WHERE ST PRODUCTS ARE NOT DESIGNED
FOR SUCH USE, THE PURCHASER SHALL USE PRODUCTS AT PURCHASER’S SOLE RISK, EVEN IF ST HAS BEEN INFORMED IN
WRITING OF SUCH USAGE, UNLESS A PRODUCT IS EXPRESSLY DESIGNATED BY ST AS BEING INTENDED FOR “AUTOMOTIVE,
AUTOMOTIVE SAFETY OR MEDICAL” INDUSTRY DOMAINS ACCORDING TO ST PRODUCT DESIGN SPECIFICATIONS.
PRODUCTS FORMALLY ESCC, QML OR JAN QUALIFIED ARE DEEMED SUITABLE FOR USE IN AEROSPACE BY THE
CORRESPONDING GOVERNMENTAL AGENCY.
Resale of ST products with provisions different from the statements and/or technical features set forth in this document shall immediately void
any warranty granted by ST for the ST product or service described herein and shall not create or extend in any manner whatsoever, any
liability of ST.
ST and the ST logo are trademarks or registered trademarks of ST in various countries.
Information in this document supersedes and replaces all information previously supplied.
The ST logo is a registered trademark of STMicroelectronics. All other names are the property of their respective owners.
© 2013 STMicroelectronics - All rights reserved
STMicroelectronics group of companies
Australia - Belgium - Brazil - Canada - China - Czech Republic - Finland - France - Germany - Hong Kong - India - Israel - Italy - Japan Malaysia - Malta - Morocco - Philippines - Singapore - Spain - Sweden - Switzerland - United Kingdom - United States of America
www.st.com
DocID007016 Rev 2
11/11
11