PDA

Ver la Versión Completa : Usando un RTC desde Mikropascal


rretamar
09-01-2010, 19:44:24
Un mensaje que subí hace tiempo al foro de Mikropascal, donde se muestra cómo usar un chip reloj-calendario (RTC) con un microcontrolador PIC, y adjunto el código fuente en Pascal que escribí. Espero que le sirva a alguien.

Saludos ! :)

----------------------------------------------------------

Schmatic:

http://i17.tinypic.com/3588h1w.png

HT1380 Descripcion and datasheet:

http://www.holtek.com.tw/english/docum/consumer/1380_1.htm

Code for ht1380.ppas unit:



(*

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.

fenixariel
19-01-2010, 03:24:07
Hola rretamar, interesante tu programa.

seria bueno poder colgar algunos topicos que en algun momento seguro nos hicieron patalear, no se algunas cosas (la idea es que quien las lea las estudie y las aprenda y no simplemente las copie y no tenga idea como funciona el asunto) con RF, IR, nose control de fase de carga en alterna, bueno nose solo mensione algunos de los mas buscados.......

Creo que MikroElectronica esta de moda, es mas no creo tenga competidores...........

Neftali [Germán.Estévez]
19-01-2010, 10:59:53
¡¡Qué recuerdos me trae ese gráfico!! :p:p:p:p

fenixariel
02-02-2010, 02:13:46
Hace unos meses un amigo me paso la serie completa en CDs, eran 11 me pase 4 meses viendolos una y otra vez.............