Unit for access to Real Time Clock (RTC) Holtek HT1380 or HT 1381
Compiler: Mikropascal 7
Access mode: byte-to-byte (see chip datasheet)
2007 Ramon Domingo Retamar
http://www.hrservicios.com.ar Email: ramonretamar [a] gmail.com
Argentina, South America
Pin connection PIC18F452 <---> HT1380 (see schematic example)
RE0 (pin 8) ----> SCLK (pin 7)
RE1 (pin 9) <---> I/O (Data) (pin 6)
RE2 (pin 10) ----> /REST (pin 5)
See example schematic (png format) here:
http://i17.tinypic.com/3588h1w.png Procedures and function for low-level access
--------------------------------------------
// Copy n bits between variables (or registers)
Function Copy_bits(Source, Start, Bits_to_copy: Byte): Byte;
// Convert A byte variable to string (2 digits with pad-left-zeros)
Procedure ByteToStr_2(Number: Byte ; Var Destination: String[2]);
// Send pulse to SLCK line (RE0)
Procedure SCLK_Pulse;
// Send one byte to RTC (LSB first)
Procedure Send_Byte(Value: Byte);
// Send Command and Data (2 bytes)
Procedure Send_Command_and_Data(Command, Data: Byte);
// Send Command byte and read Data byte
Function Read_Data(Command: Byte): Byte;
Procedures and functions for high-level access
----------------------------------------------
// Set chip flags on first power-on
Procedure Initialize_RTC;
// Get seconds from RTC
Function Get_Seconds: Byte;
// Get minutes from RTC
Function Get_Minutes: Byte;
// Get hours from RTC
Function Get_Hours: Byte;
// Get days from RTC (1..31)
Function Get_Day: Byte;
// Get month from RTC (1..12)
Function Get_Month: Byte;
// Get day of week from RTC (1..7)
Function Get_Day_Of_Week: Byte;
// Get year (0..99)
Function Get_Year: Byte;
// Return time from RTC as string (format is hh:mm:ss)
Procedure Get_Time(Var TimeString: String[8]);
// Return date from RTC as string (format is dd/mm/yy)
Procedure Get_Date(Var DateString: String[8]);
// Set time to RTC
Procedure Set_Time(Hour, Min, Sec: Byte);
// Set date to RTC
Procedure Set_Date(Day, Month, Year: Byte);
// Check if RTC is blank on first power on (test Year register)
Function RTC_Not_Set: Byte;
// Set date/time registers in read-only mode
Procedure Rtc_Write_Protect;
// Enable date/time registers write
Procedure Rtc_Write_Enable;
*)
Unit HT1380;
Implementation
Var
BitNum: Byte; // Used for test individual bits on Command bytes and Data bytes
Const // Day names
DaysNames: Array [1..7] Of String[3] =('Sat','Sun','Mon','Tue','Wed','Thu','Fri');
//
// Procedures and function for low-level read/write RTC chip
//
// Copy n bits between variables (or registers)
Function Copy_bits(Source, Start, Bits_to_copy: Byte): Byte;
Begin
Result:=0; // Set all bits to zero
For BitNum:=Start To Bits_to_copy - 1 Do // Copy from Start position
Result.BitNum := Source.BitNum;
End;
// Send pulse to SLCK line (RE0)
Procedure SCLK_Pulse;
Begin
ClearBit(PORTE,0); // Set SCLK to low state
SetBit(PORTE,0); // Set SCLK to high state (rising edge)
Delay_10us; // Keep high state for 10 microseconds
ClearBit(PORTE,0); // Set SCLK to low state (rising fall)
Delay_10us; // Keep low state for 10 microseconds
End;
// Send one byte to RTC (LSB first)
Procedure Send_Byte(Value: Byte);
Begin
ClearBit(TRISE,1); // Set RE1 (I/O line) as output
For BitNum:=0 To 7 Do // Start on LSB bit
Begin
If Value.BitNum = 1 Then // Check individual bits
SetBit(PORTE,1)
Else
ClearBit(PORTE,1); // Set RE1 (I/O line) state
SCLK_Pulse; // Sent pulse on RE0 (SCLK)
End;
End;
// Send Command and Data (2 bytes)
Procedure Send_Command_and_Data(Command, Data: Byte);
Begin
ClearBit(PORTE,0); // Set SCLK to low state
SetBit(PORTE,2); // Set /REST line to high state (init of read-cycle)
Send_Byte(Command); // Send command byte (LSB first)
Send_Byte(Data); // Send Data byte (LSB first)
ClearBit(PORTE,2); // Set /REST to low state (end of write-cycle)
End;
// Send Command byte and read Data byte
Function Read_Data(Command: Byte): Byte;
Begin
ClearBit(PORTE,0); // Set SCLK (RE0) to low state
SetBit(PORTE,2); // Set /REST (RE2) to high state (init of read-cycle)
Send_Byte(Command); // Send Command byte
SetBit(TRISE,1); // Set RE1 (I/O line) as input
For BitNum:=0 To 7 Do // Read data bits in I/O line (LSB first)
Begin
If TestBit(PORTE,1) = 1 Then
Result.BitNum := 1
Else
Result.BitNum := 0;
SCLK_Pulse; // Send pulse on SCLK
End;
ClearBit(PORTE,2); // Set /REST to low state (end of read-cycle)
End;
//
// High-level functions and procedures for read and write date/time on RTC
//
// Get seconds from RTC
Function Get_Seconds: Byte;
Begin
// Read address 000 (bits 0 to 6 as bcd format)
Get_Seconds:=Bcd2Dec( Copy_Bits(Read_Data($81), 0, 7));
End;
// Get minutes from RTC
Function Get_Minutes: Byte;
Begin
// Read Address 001 (bits 0 to 6 as bcd format)
Get_Minutes:= Bcd2Dec( Copy_Bits(Read_Data($83), 0, 7));
End;
// Get hours from RTC
Function Get_Hours: Byte;
Begin
// Read Address 002 (bits 0 to 4 as bcd format)
Get_Hours:= Bcd2Dec( Copy_Bits(Read_Data($85), 0, 5));
End;
// Get days from RTC (1..31)
Function Get_Day: Byte;
Begin
// Read Address 003 (bits 0 to 5 as bcd format)
Get_Day:= Bcd2Dec( Copy_Bits(Read_Data($87), 0, 6));
End;
// Get month from RTC (1..12)
Function Get_Month: Byte;
Begin
// Read Address 004 (bits 0 to 4 as bcd format)
Get_Month:= Bcd2Dec( Copy_bits( Read_Data($89) ,0,5));
End;
// Get day of week from RTC (1..7)
Function Get_Day_Of_Week: Byte;
Begin
// Read Address 005 (bits 0 to 3 as bcd format)
Get_Day_Of_Week:= Bcd2Dec( Copy_bits( Read_Data($8B) ,0,4));
End;
// Get year (0..99)
Function Get_Year: Byte;
Begin
// Read Address 006 (bits 0 to 7 in bcd format)
Get_Year:= Bcd2Dec( Read_Data($8D));
End;
// Convert A byte variable to string (2 digits with pad-left-zeros)
Procedure ByteToStr_2(Number: Byte ; Var Destination: String[2]);
Var
TmpString: String[3]; // User for Number-to-string conversion
Begin
ByteToStr(Number, TmpString); // Convert Number to string (3 digits)
For BitNum:=0 To 2 Do // Replace spaces with zeros
If TmpString[BitNum]=' ' Then
TmpString[BitNum]:='0';
Destination:=' '; // Initialize destination
For BitNum:=1 To 2 Do // Copy last two digits
Destination[BitNum - 1]:= TmpString[BitNum];
End;
// Return time from RTC as string (format is hh:mm:ss)
Procedure Get_Time(Var TimeString: String[8]);
Var
Hour, Minute, Second: String[2];
segundos: string[3];
Begin
TimeString:='';
ByteToStr_2(Get_Hours, Hour); // Get values and copnvert to string
ByteToStr_2(Get_Minutes, Minute);
ByteToStr_2(Get_Seconds, Second);
StrCat(TimeString,Hour); // Create time-string
StrCat(TimeString,':');
StrCat(TimeString,Minute);
StrCat(TimeString,':');
StrCat(TimeString,Second);
End;
// Return date from RTC as string (format is dd/mm/yy)
Procedure Get_Date(Var DateString: String[8]);
Var
Year, Month, Day: String[2];
Begin
DateString:='';
ByteToStr_2(Get_Year, Year); // Get values and copnvert to string
ByteToStr_2(Get_Month, Month);
ByteToStr_2(Get_Day, Day);
StrCat(DateString,Day); // Create date-string
StrCat(DateString,'/');
StrCat(DateString,Month);
StrCat(DateString,'/');
StrCat(DateString,Year);
End;
// Set time to RTC
Procedure Set_Time(Hour, Min, Sec: Byte);
Begin
// Send values in bcd format
Send_Command_and_Data($80, Dec2Bcd(Sec)); // Send seconds (and set CS flag to 0)
Send_Command_and_Data($82, Dec2Bcd(Min)); // Send minutes
Send_Command_and_Data($84, Dec2Bcd(Hour)); // Send hour (24 Hour mode)
End;
// Set date to RTC
Procedure Set_Date(Day, Month, Year: Byte);
Begin
// Send values in bcd format
Send_Command_and_Data($86, Dec2Bcd(Day)); // Send Day (1..31)
Send_Command_and_Data($88, Dec2BCD(Month)); // Send Month (1..12)
Send_Command_and_Data($8C, Dec2BCD(Year)); // Send Year (0..99)
End;
// Check if RTC is blank (using Year register)
Function RTC_Not_Set: Byte;
Begin
If Get_Year = 00 Then // Check for initial date
Result:=1
Else
Result:=0;
End;
// Set date/tme registers in read-only mode
Procedure Rtc_Write_Protect;
Begin
// Set WP flag to high
Send_Command_and_Data($8E,$40);
End;
// Enable date/time registers write
Procedure Rtc_Write_Enable;
Begin
// Set WP flah to low
Send_Command_and_Data($8E,$00);
End;
// Set chip flags on first power-on.
Procedure Initialize_RTC;
Begin
// Set WP flag to 0 (enable all registers write)
Send_Command_and_Data($8E,$00);
// Set CH flag to 0 (enable crystal oscillator on pins 2 and 3)
Send_Command_and_Data($80,$00);
// Wait 3 seconds while crystal oscillator become stable
Delay_ms(3000);
End;
End.