Ver Mensaje Individual
  #1  
Antiguo 09-01-2010
Avatar de rretamar
[rretamar] rretamar is offline
Miembro Premium
 
Registrado: ago 2006
Ubicación: San Francisco, Córdoba, Argentina
Posts: 1.168
Reputación: 20
rretamar Va camino a la famarretamar Va camino a la fama
Usando un RTC desde Mikropascal

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:



HT1380 Descripcion and datasheet:

http://www.holtek.com.tw/english/doc...mer/1380_1.htm

Code for ht1380.ppas unit:

Código Delphi [-]

(*

  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.
__________________
Lazarus Codetyphon : Desarrollo de aplicaciones Object Pascal, libre y multiplataforma.
Responder Con Cita