AVR Embedded Tutorial - I²C External-Clock
From Lazarus wiki
Jump to navigationJump to search
│
Deutsch (de) │
English (en) │
I²C external clock DS3231
This code is for an Atmega328 / Arduino with 16MHz clock and a DS3231 clock module.
The following functions are described in other tutorials:
This example shows how to address the DS3231 clock module, which is connected to the I²C bus.
PullUp resistors are necessary, the DS3231 does not contain any itself.
Functions for the DS3231 control
Constants
const
I2CAddr = $68; // Default address of the DS3231.
TWI_Write = 0;
TWI_Read = 1;
Record for time storage
type
TDate = record
year : uint16;
month, day, hour, minute, second, dayOfTheWeek : uint8;
end;
var
Date : TDate;
BCD to BIN, BIN to BCD
These conversion functions are required because the time is in BCD format.
function bcd2bin(val : uint8) : uint8;
begin
Result := val - 6 * (val shr 4);
end;
function bin2bcd(val : uint8) : uint8;
begin
Result := val + 6 * (val div 10);
end;
Write the time
Write the block with a time. You can see that you have to convert the format.
procedure WriteDS3231(addr : UInt16);
begin
TWIStart((addr shl 1) or TWI_Write);
TWIWrite(0);
TWIWrite(bin2bcd(Date.Second));
TWIWrite(bin2bcd(Date.Minute));
TWIWrite(bin2bcd(Date.Hour));
TWIWrite(bin2bcd(0));
TWIWrite(bin2bcd(Date.Day));
TWIWrite(bin2bcd(Date.Month));
TWIWrite(bin2bcd(Date.Year - 2000));
TWIStop;
end;
Read the time
Read the time from the block. You can see that you have to convert the format.
procedure ReadDS3231(addr : UInt16);
begin
TWIStart((addr shl 1) or TWI_Write);
TWIWrite(0);
TWIStop;
TWIStart((addr shl 1) or TWI_Read);
Date.second := bcd2bin(TWIReadACK_Error and $7F);
Date.minute := bcd2bin(TWIReadACK_Error);
Date.hour := bcd2bin(TWIReadACK_Error);
TWIReadACK_Error;
Date.day := bcd2bin(TWIReadACK_Error);
Date.month := bcd2bin(TWIReadACK_Error);
Date.year := bcd2bin(TWIReadNACK_Error) + 2000;
TWIStop;
end;
Example program
Variables
var
s : ShortString;
Main program
You only have to write the time to the DS3231 to if you want to set the clock.
begin
UARTInit; // initialize UART
TWIInit; // initialize I²C
asm Sei end; // enable interrupts
// Write a time from the DS3231.
Date.second := 33;
Date.minute := 22;
Date.hour := 11;
WriteDS3231(I2CAddr);
// Read time and output via UART
repeat
ReadDS3231(I2CAddr);
str(Date.second : 6, s);
UARTSendString('Sec:' + s);
str(Date.minute : 6, s);
UARTSendString('Minute:' + s);
str(Date.hour : 6, s);
UARTSendString('hours:' + s);
UARTSendString(#13#10);
until 1 = 2;
end.
See also
- Overview page - AVR Embedded Tutorials.