top of page

Модули обслуживания часов реального времени

DS1306

unit DS1306;
{$O-}
{$xdata}
{$idata}
interface
var
    year1305,month1305,day1305,date1305,hours1305,min1305,sec1305:byte;
    procedure gets;
    procedure sets;
    procedure Setyear;
    procedure SetMonth;
    procedure wrm1305;
    procedure rdm1305;
    procedure setall;
    procedure getall;
    procedure ENWRITE;
    procedure WRS1305;
    procedure SaveBuffer;
    procedure LoadBuffer;
   
implementation

uses declare,ports;
procedure wra13051;forward;
//===============================================
procedure WRA1305;assembler;
asm
setb l1305clk
setb l1305ce
clr l1305clk
lcall wra13051
end;
//===============================================         
procedure wra13051;
begin
ar7:=acc;         
for i:=1 to 8 do
  begin
   asm
    mov a,r7
    RLC A
    mov r7,a
    MOV L1305OUT,C
    SETB L1305CLK
    NOP
    NOP
    CLR L1305CLK
   end;      
  end;
end;         
//===============================================
procedure WRB1305;assembler;
asm
LCALL WRA1305
MOV A,B
LCALL WRA13051
SETB L1305CLK
CLR L1305CE
RET
end;
//===============================================
procedure RDB1305;
begin
WRA1305;
ar7:=0;
for i:=1 to 8 do
  begin
   asm
    SETB L1305CLK
    NOP
    NOP
    mov a,r7
    MOV C,L1305IN
    RLC A
    mov r7,a
    CLR L1305CLK
   end;     
  end;
  asm
   setb l1305clk
   clr l1305ce
   mov a,r7     
  end;         
end;         
//===============================================
procedure WRS1305;assembler;
asm 
  MOV A,#0FH
  LCALL RDB1305
  ANL A,#01111111B
  MOV B,#7
  MOV A,#8FH
  LCALL WRB1305
  RET
end;
//===============================================
procedure ENWRITE;assembler;
asm
  MOV A,#0FH
  LCALL RDB1305
  ANL A,#10111111B
  MOV B,A
  MOV A,#8FH
  LCALL WRB1305
  RET
end;
//===============================================
procedure WRM1305;assembler;
asm
clr c
ADDc A,#0A0H
LCALL WRB1305
RET
end;         
//================================================
procedure RDM1305;assembler;
asm
clr c
ADDc A,#20H
LCALL RDB1305
RET
end;
//===============================================
procedure gets;assembler;
asm

  mov a,r7
  //mov ar7,a
  anl ar7,#00001111b
  swap a
  anl a,#00001111b
  mov b,#10
  mul ab
  add a,ar7
  mov r7,a
  ret
end;
//===============================================
procedure sets;assembler;
asm
{clr c
da a}

  mov r6,a       //сохранение А в регистре 6
  mov b,#10
  div ab
  mov r5,a       //в регистре 5 частное от деления, то есть количество десяток
  mov b,#10
  mul ab          //умножаем частное на 10
  mov r7,a        //и сохраняем в регистре 7
  clr c
  mov a,r6
  subb a,r7       //вычитаем из исходного количество целых десяток,
                  //умноженное на 10, и получаем количество единиц
  mov r6,a               
  mov a,r5      
  swap a
  add a,r6
  ret
end;
//===============================================
procedure SETYEAR;assembler;
asm
          MOV a,YEAR1305
          LCALL SETS
          mov b,a
          MOV A,#86H
          LCALL WRB1305
          RET
end;
//===============================================
procedure SETMONTH;assembler;
asm
          MOV a,MONTH1305
          LCALL SETS
          mov b,a
          MOV A,#85H
          LCALL WRB1305
          RET
end;
//===============================================
procedure SETDATE;assembler;
asm
          MOV a,DATE1305
          LCALL SETS
          mov b,a
          MOV A,#84H
          LCALL WRB1305
          RET
end;         
//===============================================
procedure SETHOURS;assembler;
asm
          MOV a,HOURS1305
          LCALL SETS
          mov b,a
          MOV A,#82H
          LCALL WRB1305
          RET
end;         
//===============================================
procedure SETMIN;assembler;
asm
          MOV A,MIN1305
          LCALL SETS
          mov b,a
          MOV A,#81H
          LCALL WRB1305
          RET
end;         
//===============================================
procedure SETSEC;assembler;
asm
          MOV A,SEC1305
          LCALL SETS
          mov b,a
          MOV A,#80H
          LCALL WRB1305
          RET
end;         
//===============================================
procedure SETDAY;assembler;
asm
          MOV A,DAY1305
          LCALL SETS
          mov b,a
          MOV A,#83H
          LCALL WRB1305
          RET
end;         
//===============================================
procedure GETYEAR;assembler;
asm
          MOV A,#06H
          LCALL RDB1305
          LCALL GETS
          MOV YEAR1305,r7
          RET
end;         
//===============================================
procedure GETMONTH;assembler;
asm
          MOV A,#05H
          LCALL RDB1305
          LCALL GETS
          MOV MONTH1305,r7
          RET
end;         
//===============================================
procedure GETDATE;assembler;
asm
          MOV A,#04H
          LCALL RDB1305
          LCALL GETS
          MOV DATE1305,r7
          RET
end;
//===============================================
procedure GETHOURS;assembler;
asm
          MOV A,#02H
          LCALL RDB1305
          LCALL GETS
          MOV HOURS1305,r7
          RET
end;         
//===============================================
procedure GETMIN;assembler;
asm
          MOV A,#01H
          LCALL RDB1305
          LCALL GETS
          MOV MIN1305,r7
          RET
end;         
//===============================================
procedure GETSEC;assembler;
asm
          MOV A,#00H
          LCALL RDB1305
          LCALL GETS
          MOV SEC1305,r7
          RET
end;         
//===============================================
procedure GETDAY;assembler;
asm
          MOV A,#03H
          LCALL RDB1305
          LCALL GETS
          MOV DAY1305,r7
          RET
end;         
//===============================================
procedure GETALL;assembler;
asm
          LCALL GETSEC
          LCALL GETMIN
          LCALL GETHOURS
          LCALL GETDAY
          LCALL GETDATE
          LCALL GETMONTH
          LCALL GETYEAR
          RET
end;         
//===============================================
procedure SETALL;assembler;
asm
          LCALL SETSEC
          LCALL SETMIN
          LCALL SETHOURS
          LCALL SETDAY
          LCALL SETDATE
          LCALL SETMONTH
          LCALL SETYEAR
          RET
end;
//======================================================
//процедура сохранения буфера в памяти 1305
procedure SaveBuffer;
begin
for j:=0 to 63 do
  begin
   b:=sn[j];
   acc:=j;
   wrm1305;
  end;
end;
//===============================================
//процедура загрузки из памяти 1305 сохраненного содержимого буфера
procedure LoadBuffer;
begin
for j:=0 to 63 do
  begin
   acc:=j;
   rdm1305;
   b:=acc;
   sn[j]:=b;
  end;
end;         
//===============================================
end.

DS1307

unit ds1307;

{$Idata}
{$O-}
{$xdata}
interface
const adr1307=%11010000;
      reg1307=%10010011;    
var
    year1305,
    month1305,
    day1305,
    date1305,
    hours1305,
    min1305,
    sec1305:byte;
    ac1307:byte;         //субадрес ОЗУ DS1307
    data1307:byte;       //данные DS1307

    procedure WriteControl1307;
    procedure ReadControl1307;
    procedure StartWrite1307(mem:boolean);
    procedure StartRead1307;
    procedure WriteByte1307;
    procedure ReadByte1307;
    procedure WriteMem1307;
    procedure ReadMem1307;

    procedure gets;
    procedure sets;
    procedure Setyear;
    procedure SetMonth;
    procedure GetAll;
    procedure SetAll;
    procedure getSec;
    procedure SetSec;
    procedure StartGen1307;
    procedure Init1307;   
implementation

uses declare,i2c;
//===============================================
procedure StartGen1307;
begin
GetSec;
//sec1305:=sec1305 and %01111111;
acc:=sec1305;
if acc.7 then
  begin
   sec1305:=0;
   SetSec;
  end;
end;
//===============================================
//процедура исходной инициализации DS1307
procedure Init1307;
begin
//I2CINIT;
StartGen1307;           //запуск (или подтверждение) генератора
WriteControl1307;       //установка состояния управляющего регистра
end;
//===============================================
//процедура записи контрольного регистра
procedure WriteControl1307;
begin
ac1307:=7;
StartWrite1307(false);
acc:=reg1307;
i2cwb;
i2cans;
i2cstop;
end;
//===============================================
//процедура чтения контрольного регистра
procedure ReadControl1307;
begin
ac1307:=7;
StartWrite1307(false);
i2cstop;
StartRead1307;
i2crb;
data1307:=acc;
i2cnoansm;
i2cstop;
end;
//===============================================
//процедура старта записи - передача адреса 1307 и
//адреса ячейки памяти или часовые регистры.
//если установлен флаг MEM, производится запись
//в память данных, то есть к адресу автоматически
//прибавляется 8 - начало пространства ОЗУ пользователя.
procedure StartWrite1307(mem:boolean);
begin
acc:=adr1307;
cy:=false;
i2cadr;
if mem then acc:=ac1307+8
  else
   acc:=ac1307;
i2cwb;
i2cans;
end;
//===============================================
//процедура старта чтения - передача адреса  1307
//и получение ответа
procedure StartRead1307;
begin
cy:=true;
acc:=adr1307;
i2cadr;
end;
//===============================================
//процедура записи байта в 1307 через адрес ас1307
procedure WriteByte1307;
begin
startwrite1307(false); //запрос устройства и передача адреса ас1307
acc:=data1307;         //байт
i2cwb;                 //запись байта
i2cans;                //ожидание ответа
i2cstop;               //прекращение обмена
end;
//===============================================
//процедура чтения байта из 1307 через адрес ас1307
procedure ReadByte1307;
begin
StartWrite1307(false); //запрос устройства и передача адреса ас1307
i2cstop;               //прекращение обмена
StartRead1307;         //запуск чтения
i2crb;                 //чтение байта
data1307:=acc;         //байт в data1307
i2cnoansm;             //отрицательный ответ мастера
i2cstop;               //прекращение обмена
end;
//===============================================
//процедура преобразования двоично-десятичного кода
//в двоичный
procedure gets;assembler;
asm
  mov ar7,a
  anl ar7,#00001111b
  swap a
  anl a,#00001111b
  mov b,#10
  mul ab
  add a,ar7
end;
//===============================================
//процедура двоично-десятичного преобразования на 4 разряда.
//входные данные R2:R3, выходные ar23:ar22:a21:ar20.
procedure ddc4;
label
     ddc40,ddc41,ddc42,ddc43,ddc44,ddc45,ddc46;
begin
asm
          MOV R4,#16  
          CLR A
          MOV ar20,A
          MOV ar21,A
          MOV ar22,A
          MOV ar23,A   
DDC40:    MOV R0,#ar20
          MOV R5,#4
DDC41:    MOV A,@R0
          XRL A,#5   
          JZ DDC45   
          MOV A,@R0
          SUBB A,#5   
          JC DDC43   
DDC45:    MOV A,@R0
          ADD A,#3    
          MOV @R0,A
DDC43:    INC R0
          DJNZ R5,DDC41
DDC42:    CLR C
          MOV A,R3
          RLC A       
          MOV R3,A
          MOV A,R2
          RLC A       
          MOV R2,A
          MOV F0,C
          MOV R0,#ar20
          MOV R5,#4
DDC46:    MOV C,F0
          MOV A,@R0
          RLC A
          MOV C,ACC.4 
          MOV F0,C
          ANL A,#0FH  
          MOV @R0,A
          INC R0
          DJNZ R5,DDC46
          DJNZ R4,DDC40
end;         
end;         
//*************************************************
//процедура двоично-десятичного преобразования
procedure sets;
begin
asm
  mov r2,#0
  mov r3,a
end;
ddc4;
valb:=ar21 shl 4;
valb:=valb+ar20;
acc:=valb;
end;
//===============================================
//процедура чтения всех временных параметров
procedure GetAll;
begin
ac1307:=0;
startwrite1307(false);
i2cstop;
startread1307;

i2crb;
gets;
sec1305:=acc;
i2cansm;

i2crb;
gets;
min1305:=acc;
i2cansm;

i2crb;
gets;
hours1305:=acc;
i2cansm;

i2crb;
day1305:=acc;
i2cansm;

i2crb;
gets;
date1305:=acc;
i2cansm;

i2crb;
gets;
month1305:=acc;
i2cansm;

i2crb;
gets;
year1305:=acc;
i2cnoansm;
i2cstop;
end;
//===============================================
//процедура установки (записи) всех временных параметров
procedure SetAll;
begin
ac1307:=0;
startwrite1307(false);

acc:=sec1305;
sets;
i2cwb;
i2cans;

acc:=min1305;
sets;
i2cwb;
i2cans;

acc:=hours1305;
sets;
i2cwb;
i2cans;

acc:=day1305;
i2cwb;
i2cans;

acc:=date1305;
sets;
i2cwb;
i2cans;

acc:=month1305;
sets;
i2cwb;
i2cans;

acc:=year1305;
sets;
i2cwb;
i2cans;

i2cstop;
end;
//===============================================
procedure WriteMem1307;
begin
startwrite1307(true);  //запрос устройства и передача адреса ас1307
acc:=data1307;         //байт
i2cwb;                 //запись байта
i2cans;                //ожидание ответа
i2cstop;
end;
//===============================================
procedure ReadMem1307;
begin
startwrite1307(true);
i2cstop;
startread1307;
i2crb;
i2cnoansm;
i2cstop;
data1307:=acc;
end;
//===============================================
procedure SETYEAR;
begin
ac1307:=6;
acc:=year1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETMONTH;
begin
ac1307:=5;
acc:=month1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETDATE;
begin
ac1307:=4;
acc:=date1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETDAY;
begin
ac1307:=3;
data1307:=day1305;
writebyte1307;
end;
//===============================================
procedure SETHOURS;
begin
ac1307:=2;
acc:=hours1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETMIN;
begin
ac1307:=1;
acc:=min1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure SETSEC;
begin
ac1307:=0;
acc:=sec1305;
sets;
data1307:=acc;
writebyte1307;
end;
//===============================================
procedure GETYEAR;
begin
ac1307:=6;
readbyte1307;
acc:=data1307;
gets;
year1305:=acc;
end;
//===============================================
procedure GETMONTH;
begin
ac1307:=5;
readbyte1307;
acc:=data1307;
gets;
month1305:=acc;
end;
//===============================================
procedure GETDATE;
begin
ac1307:=4;
readbyte1307;
acc:=data1307;
gets;
date1305:=acc;
end;
//===============================================
procedure GETDAY;
begin
ac1307:=3;
readbyte1307;
day1305:=data1307;
end;
//===============================================
procedure GETHOURS;
begin
ac1307:=2;
readbyte1307;
acc:=data1307;
gets;
hours1305:=acc;
end;
//===============================================
procedure GETMIN;
begin
ac1307:=1;
readbyte1307;
acc:=data1307;
gets;
min1305:=acc;
end;
//===============================================
procedure GETSEC;
begin
ac1307:=0;
readbyte1307;
acc:=data1307;
gets;
sec1305:=acc;
end;
//===============================================

end.

bottom of page